Bugzilla – Bug 1125616
[stagnig] syslinux fails to build due aliasing bugs in lzo
Last modified: 2019-02-18 14:55:10 UTC
Binutils 2.32 has been staged and is making good progress. One package failing to build in this setup is syslinux (on i586) The build log ends with: >[ 132s] objdump -h ldlinux.elf > ldlinux.sec >[ 132s] perl lstadjust.pl ldlinux.lsr ldlinux.sec ldlinux.lst >[ 132s] objcopy -O binary ldlinux.elf ldlinux.raw >[ 132s] ../lzo/prepcore ldlinux.raw ldlinux.bin >[ 132s] ../lzo/prepcore: ldlinux.raw: internal error - lzo_init() failed! >[ 132s] make[1]: *** [Makefile:86: ldlinux.bin] Error 1 >[ 132s] rm ldlinux.o >[ 132s] make[1]: Leaving directory '/home/abuild/rpmbuild/BUILD/syslinux-4.04/core' >[ 132s] make: *** [Makefile:88: all] Error 2 >[ 132s] error: Bad exit status from /var/tmp/rpm-tmp.k5I91R (%build)
This has nothing to do with binutils. What actually happens is that LZO contains non-conforming code that does or doesn't work depending on the phase of the moon. We seemed to have been lucky until now. lzo/src/lzo_init.c, routine _lzo_config_check is broken. It effectively does this: ------------ snip ---------------- typedef int lzo_bool; typedef unsigned long lzo_uint; typedef unsigned int lzo_uint32; int __attribute__((noipa)) _lzo_config_check(void) { lzo_bool r = 1; union { unsigned char c[2*sizeof(lzo_uint)]; lzo_uint l[2]; } u; unsigned long p; u.l[0] = u.l[1] = 0; u.c[0] = 128; r &= (u.l[0] == 128); p = (unsigned long) (const void *) &u.c[0]; u.l[0] = u.l[1] = 0; r &= ((* (const unsigned short *) (p+1)) == 0); p = (unsigned long) (const void *) &u.c[0]; u.l[0] = u.l[1] = 0; r &= ((* (const lzo_uint32 *) (p+1)) == 0); return r == 1 ? 0 : (-1); } extern int printf (const char *, ...); int main() { if (_lzo_config_check() != 0) printf("broken\n"); return 0; } ------------ snap -------------- The two accesses to 'p+1' are wrong: it tries to read memory as a short or uint32, which was written to as an long before (the write to u.l[1]). The store and the loads don't alias (because of different types) and GCC is free to remove the stores, which it does with -Os and -O2. The load then accesses uninitialized stack memory and the check might or might not succeed. You could compile lzo_init.c with -fno-strict-aliasing, or better yet fix this routine to be written in ISO C. As LZO is like it is, there might be other similar aliasing bugs lurking so maybe it's better to just addd -fno-strict-aliasing, though.
Tracking in YaST Scrum board.
fix submitted
This is an autogenerated message for OBS integration: This bug (1125616) was mentioned in https://build.opensuse.org/request/show/677142 Factory / syslinux