Bug 1125616 - [stagnig] syslinux fails to build due aliasing bugs in lzo
[stagnig] syslinux fails to build due aliasing bugs in lzo
Classification: openSUSE
Product: openSUSE Tumbleweed
Classification: openSUSE
Component: Basesystem
Other Other
: P3 - Medium : Normal (vote)
: ---
Assigned To: Steffen Winterfeldt
E-mail List
Depends on:
  Show dependency treegraph
Reported: 2019-02-15 15:40 UTC by Dominique Leuenberger
Modified: 2019-02-18 14:55 UTC (History)
2 users (show)

See Also:
Found By: ---
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Note You need to log in before you can comment on or make changes to this bug.
Description Dominique Leuenberger 2019-02-15 15:40:46 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)
Comment 1 Michael Matz 2019-02-15 16:34:07 UTC
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_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)
  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.
Comment 2 Steffen Winterfeldt 2019-02-18 12:01:53 UTC
Tracking in YaST Scrum board.
Comment 3 Steffen Winterfeldt 2019-02-18 14:09:49 UTC
fix submitted
Comment 4 Swamp Workflow Management 2019-02-18 14:50:10 UTC
This is an autogenerated message for OBS integration:
This bug (1125616) was mentioned in
https://build.opensuse.org/request/show/677142 Factory / syslinux