[MacPorts] #45582: grace: xmgrace crashes with SIGSYS in yosemite
MacPorts
noreply at macports.org
Fri Jun 10 14:23:00 UTC 2022
#45582: grace: xmgrace crashes with SIGSYS in yosemite
--------------------------+--------------------------------
Reporter: gezelter@… | Owner: macports-tickets@…
Type: defect | Status: new
Priority: Normal | Milestone:
Component: ports | Version:
Resolution: | Keywords:
Port: grace t1lib |
--------------------------+--------------------------------
Comment (by chuckcranor):
I have figured out why grace crashes at startup (unless you compile -O1 or
less).
The t1lib is triggering a clang code generation bug.
There is also a malloc buffer overflow in t1lib that causes issues on OSX.
Here are the details from an email I posted elsewhere:
there are two bugs in fonts/t1lib that cause grace to crash on OSX:
1. compiler bug in some versions of clang when compiling with "-O2" ...
this appears to have been fixed somewhere between clang-11 and
clang-12.
it works ok with "-O1".
2. one case of t1lib trying to be clever and instead writing past end of
malloc'd buffer (which the OSX malloc did not like at all). the
address
sanitizer helped pinpoint this.
For 1, the t1lib is trying to roll its own optmized memcpy() using
this macro in lib/type1/objects.h:
{{{
#define LONGCOPY(dest,source,bytes) { \
register LONG *p1 = (LONG *)dest; register LONG *p2 = (LONG
*)source; \
register int count = (bytes) / sizeof(LONG); \
while (--count >= 0) *p1++ = *p2++; }
}}}
they explain (in lib/type1/objects.c) they are doing this because
there is no standarized portable memory copy routine (e.g. memcpy()
vs bcopy()). maybe that was true in 1991 when this code was written,
but i think pretty much everyone has memcpy() now?
At any rate, some versions of "clang -O2" choke on LONGCOPY() and
produce incorrect code. I've got a 49 line test C program that
reproduces the issue (see attached xalloc-test.c):
{{{
% clang-11 -O1 -o alloc-test xalloc-test.c
% ./alloc-test
Result CORRECT!
% clang-11 -O2 -o alloc-test xalloc-test.c
% ./alloc-test
Result FAILED! (0 != 0x80)
% clang-12 -O2 -o alloc-test xalloc-test.c
% ./alloc-test
Result CORRECT!
%
}}}
I think the solution is to assume that memcpy() is going to be
available and have LONGCOPY() use memcpy() rather than its custom
copy.
For 2, the issue is in lib/type1/regions.c where it allocates
"(ymax - iy) * sizeof(pel)" bytes of extra data using malloc and
then uses LONGCOPY() like this:
{{{
/*
We must round up (ymax - iy) so we get the ceiling of the number of
longs. The destination must be able to hold these extra bytes because
Allocate() makes everything it allocates be in multiples of longs.
*/
LONGCOPY(&r[1], xvalues, (ymax - iy) * sizeof(pel) + sizeof(LONG) -
1);
}}}
they've incorrectly computed the ceiling by just adding "sizeof(LONG) - 1"
(need to mask off the low bits by "~(sizeof(LONG) - 1)").
with those fixes in, I can run grace on all the examples
that it installs (using the "dotest" script there) on OSX
without grace crashing with everything compiled -O2.
xalloc test program source:
{{{
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct xobject {
int flag;
};
#define LONGCOPY(dest,source,bytes) do {
\
long *p1 = (long *)dest;
\
long *p2 = (long *)source;
\
int count = (bytes) / sizeof(long);
\
while (--count >= 0)
\
*p1++ = *p2++;
\
} while(0)
struct xobject *t1_Allocate(int size, struct xobject *xtemplate) {
struct xobject *r;
r = (struct xobject *) malloc(size);
if (r == NULL) errx(1, "malloc abort");
#if 1
LONGCOPY(r, xtemplate, size);
#else
memcpy(r, xtemplate, size);
#endif
r->flag &= ~(0x01);
return(r);
}
int main(int argc, char **argv) {
struct xobject *xo, *xo2;
xo = malloc(56);
memset(xo, 0, 56);
xo->flag = 0x80;
xo2 = t1_Allocate(56, xo);
if (xo2->flag == 0x80) {
fprintf(stderr, "Result CORRECT!\n");
} else {
fprintf(stderr, "Result FAILED! (%#x != 0x80)\n", xo2->flag);
}
exit(0);
}
}}}
--
Ticket URL: <https://trac.macports.org/ticket/45582#comment:13>
MacPorts <https://www.macports.org/>
Ports system for macOS
More information about the macports-tickets
mailing list