severity 731082 important retitle 731082 ld.so.cache parsing code does not deal with mixed endianess multiarch, causing segfaults reassign 731082 libc6 thanks
Michael Tokarev wrote... > 01.12.2013 23:27, Marc Glisse wrote: > [] > > I managed to run: > > $ qemu-ppc-static /lib/powerpc-linux-gnu/libc.so.6 > > > > which prints the usual text, but so far that's the only program that > > hasn't failed with: > > > > $ qemu-ppc-static ./bin/true > > Invalid data memory access: 0xb6d15008 > [...] > > > Other people seem to have more luck, but I have mostly read posts about > > debootstrap or chroots, not about multiarch setups. > > I've never tried multiarch setup, never ever considered it. > Only on second read of your bugreport I realized you're not > running it in chroot but on real root with multiarch instead. > > And now I realize that I don't even know how to do that. > I don't really want to mess with my regular system (unless > it is something easy, like just libc6), so it looks I'll > have to try multiarch-within-chroot. > > Can you provide some details about how this kind of multiarch > system can be set up, pleae? > > Note: I verified several arches from qemu-user-static in foreign > chroots (using debootstrap --arch=powerpc in this case), and it > works quite well. But it never occured to me to test in a live > system.. > > > According to strace, the segfault happens just after closing > > /etc/ld.so.cache. On arm, that's followed by a second check for > > /etc/ld.so.nohwcap and then looking everywhere for libc.so.6. > > Might it be due to some differences within ld.so.cache? I mean, > when it has stuff from several architectures, does the runtime > linker actually work right? I dunno. Quite close. The problem is not architectures per se, it's endianess: powerpc is big endian, amd64 and armel/armhf are little endian. That's why armhf was no problem for you. The content of /etc/ld.so.cache is in the host architecture, probably the one of ldconfig, for example: amd64: vvvvvvvvvvv = 0x32e nlibs 00000000 6c 64 2e 73 6f 2d 31 2e 37 2e 30 00 2e 03 00 00 |ld.so-1.7.0.....| 00000010 03 03 00 00 80 4c 00 00 8d 4c 00 00 03 03 00 00 |.....L...L......| powerpc: vvvvvvvvvvv = 0x90 nlibs 00000000 6c 64 2e 73 6f 2d 31 2e 37 2e 30 00 00 00 00 90 |ld.so-1.7.0.....| 00000010 00 00 00 03 00 00 0d 98 00 00 0d a2 00 00 00 03 |................| However the loader code in elf/dl-cache.c always treats the content in his own endianess, like in line 278 (content mapped to struct cache_file *cache): cache_data = (const char *) &cache->libs[cache->nlibs]; which is likey the code line that causes the segfault due to a ludicrous value of nlibs if read in the wrong endianess. Fastest way to reproduce probably is # dpkg --add-architecture <arch> where <arch> has different endianess * Install qemu-user-static * Run a program in the foreign architecture, using qemu-*-static Debugging is eased a bit by setting LD_DEBUG=all btw, last messages here were 8273: file=libselinux.so.1 [0]; needed by /usr/bin/<redacted> [0] 8273: find library=libselinux.so.1 [0]; searching 8273: search cache=/etc/ld.so.cache No idea for a simple fix. Personally, I'd change ld.so.cache to ld.so.cache.<triple> since I doubt mixing different archs' shared objects makes any sense. If I'm wrong, split at least for endianess. Worst approach: Guess the file's endianess from nlibs, and switch all values when required. (Re-assigning to libc) Christoph
signature.asc
Description: Digital signature