> Date: Thu, 15 Apr 2021 14:20:00 +0200 > From: Martin Pieuchot <m...@openbsd.org> > Content-Type: text/plain; charset=utf-8 > Content-Disposition: inline > > On 14/04/21(Wed) 18:33, Klemens Nanni wrote: > > A bogus libvorbisenc.so.3.1 causes ld.so(1) to crash on my Pinebook Pro > > which saw a few NVMe/power related panics: > > > > $ ogg123 song62.ogg > > Segmentation fault (core dumped) > > > > $ egdb -q ogg123 ogg123.core > > Reading symbols from ogg123...(no debugging symbols found)...done. > > [New process 512916] > > Core was generated by `ogg123'. > > Program terminated with signal SIGSEGV, Segmentation fault. > > #0 0x0000000d388623e4 in _dl_find_symbol_obj (obj=0xcfae56000, > > sl=0x7ffffdd728) at /usr/src/libexec/ld.so/resolve.c:614 > > 614 for (si = obj->buckets_elf[sl->sl_elf_hash % > > obj->nbuckets]; > > (gdb) p obj->buckets_elf > > There is no member named buckets_elf. > > > > (`buckets_elf' is a macro) > > > > (gdb) p obj->hash_u.u_elf.buckets > > $1 = (const Elf_Hash_Word *) 0x0 > > (gdb) p obj->nbuckets > > $2 = 0 > > > > Backtrace for completeness: > > > > (gdb) bt > > #0 0x0000000d388623e4 in _dl_find_symbol_obj (obj=0xcfae56000, > > sl=0x7ffffdd728) at /usr/src/libexec/ld.so/resolve.c:614 > > #1 0x0000000d38862210 in _dl_find_symbol (name=0xd9e9e6919 > > "malloc_options", flags=16, ref_sym=0xd9e9d23f8, req_obj=0xcfae52000) at > > /usr/src/libexec/ld.so/resolve.c:704 > > #2 0x0000000d388603b8 in _dl_md_reloc (object=<optimized out>, > > rel=<optimized out>, relsz=<optimized out>) at > > /usr/src/libexec/ld.so/aarch64/rtld_machine.c:170 > > #3 0x0000000d38864714 in _dl_rtld (object=0xcfae52000) at > > /usr/src/libexec/ld.so/loader.c:722 > > #4 0x0000000d388646dc in _dl_rtld (object=0xcfae52400) at > > /usr/src/libexec/ld.so/loader.c:712 > > #5 0x0000000d388646dc in _dl_rtld (object=0xd6d641400) at > > /usr/src/libexec/ld.so/loader.c:712 > > #6 0x0000000d388646dc in _dl_rtld (object=0xcfae52800) at > > /usr/src/libexec/ld.so/loader.c:712 > > #7 0x0000000d388646dc in _dl_rtld (object=0xcfae53c00) at > > /usr/src/libexec/ld.so/loader.c:712 > > #8 0x0000000d388646dc in _dl_rtld (object=0xcfae56800) at > > /usr/src/libexec/ld.so/loader.c:712 > > #9 0x0000000d388646dc in _dl_rtld (object=0xcfae56400) at > > /usr/src/libexec/ld.so/loader.c:712 > > #10 0x0000000d388646dc in _dl_rtld (object=0xcfae56c00) at > > /usr/src/libexec/ld.so/loader.c:712 > > #11 0x0000000d388646dc in _dl_rtld (object=0xd0b867400) at > > /usr/src/libexec/ld.so/loader.c:712 > > #12 0x0000000d388646dc in _dl_rtld (object=0xd6d63f400) at > > /usr/src/libexec/ld.so/loader.c:712 > > #13 0x0000000d388646dc in _dl_rtld (object=0xcfae53400) at > > /usr/src/libexec/ld.so/loader.c:712 > > #14 0x0000000d388646dc in _dl_rtld (object=0xd6d63f800) at > > /usr/src/libexec/ld.so/loader.c:712 > > #15 0x0000000d388646dc in _dl_rtld (object=0xcfae52c00) at > > /usr/src/libexec/ld.so/loader.c:712 > > #16 0x0000000d388646dc in _dl_rtld (object=0xcfae53000) at > > /usr/src/libexec/ld.so/loader.c:712 > > #17 0x0000000d388646dc in _dl_rtld (object=0xd0b867c00) at > > /usr/src/libexec/ld.so/loader.c:712 > > #18 0x0000000d388646dc in _dl_rtld (object=0xd6d640000) at > > /usr/src/libexec/ld.so/loader.c:712 > > #19 0x0000000d388646dc in _dl_rtld (object=0xd6d640c00) at > > /usr/src/libexec/ld.so/loader.c:712 > > #20 0x0000000d388646dc in _dl_rtld (object=0xd0b867000) at > > /usr/src/libexec/ld.so/loader.c:712 > > #21 0x0000000d388646dc in _dl_rtld (object=0xcfae56000) at > > /usr/src/libexec/ld.so/loader.c:712 > > #22 0x0000000d388646dc in _dl_rtld (object=0xd0b867800) at > > /usr/src/libexec/ld.so/loader.c:712 > > #23 0x0000000d3886b618 in _dl_boot (argv=<optimized out>, > > envp=<optimized out>, dyn_loff=56782815232, dl_data=0x7ffffddde4) at > > /usr/src/libexec/ld.so/loader.c:663 > > #24 0x0000000d3886a044 in _dl_start () at > > /usr/src/libexec/ld.so/aarch64/ldasm.S:59 > > Backtrace stopped: previous frame identical to this frame (corrupt > > stack?) > > > > > > libvorbis being the culprit wasn't clear at all, but I went through > > pkg_check(1) to see checksum mismatches in the "libvorbis" package. > > > > tl;dr: I Upgraded to the latest snapshot, saved the currupted libraries, > > deinstalled all packages with `pkg_delete -X', installed "vorbis-tools" > > for ogg123(1) (pulling in "libvorbis") and the song played fine using > > valid files. > > > > Forcing the corrupted library I can reproduce, though: > > > > $ LD_PRELOAD=./libvorbisenc.so.3.1 ogg123 song62.ogg > > Segmentation fault (core dumped) > > > > So that's really this shared object and not any other currupted files. > > > > I'm not familiar with ld.so internals but the NULL dereference seems > > easy to avoid based on the condition that is used to set the `buckets' > > member in resolve.c:408f: > > > > if (object->Dyn.info[DT_HASH] != 0) { > > Elf_Hash_Word *hashtab = > > (Elf_Hash_Word *)(object->Dyn.info[DT_HASH] + obase); > > > > object->nchains = hashtab[1]; > > if (object->nbuckets == 0) { > > object->nbuckets = hashtab[0]; > > object->buckets_elf = hashtab + 2; > > object->chains_elf = object->buckets_elf + > > object->nbuckets; > > } > > } > > > > Hence, only access buckets in _dl_find_symbol_obj() if there are any; > > this fixes the crash and in fact allows me to play the song even when > > preloading the currupted library, i.e. > > > > $ LD_PRELOAD=./libvorbisenc.so.3.1 ogg123 song62.ogg > > > > now also works with patched ld.so installed -- I'd expected ld.so, > > libvorbis or ogg123 to crash on some other place... > > > > I'm not sure what to make of this, I also don't know enough about ld.so > > to judge this diff in context, it does however fix an obvious error. > > FWIW, regress/libexec/ld.so runs fine with this diff. > > I'm not sure if silently ignoring the corruption is the best way to go.
It certainly isn't. If corruption is detected, the prcess should terminate immedtaley. > Do you know why `nbuckets' and `buckets_elf' aren't initialized for this > object? Do you know if _dl_finalize_object() has been call for it? > > > Is this a code path that can happen with intact objects? > > Given that the file is obviously corrupted but programs using it still > > (partially) work, should a warning be printed in this case? > > Indicating that the library is corrupted might indeed be better than > crashing. However it isn't clear to me where such check should happen. > > > Feedback? > > > > PS: I can upload/mail the corrupted library if someone wants to poke it. > > > > Index: resolve.c > > =================================================================== > > RCS file: /cvs/src/libexec/ld.so/resolve.c,v > > retrieving revision 1.94 > > diff -u -p -r1.94 resolve.c > > --- resolve.c 4 Oct 2019 17:42:16 -0000 1.94 > > +++ resolve.c 14 Apr 2021 15:56:14 -0000 > > @@ -608,7 +608,7 @@ _dl_find_symbol_obj(elf_object_t *obj, s > > return r > 0; > > } > > } while ((*hashval++ & 1U) == 0); > > - } else { > > + } else if (obj->nbuckets > 0) { > > Elf_Word si; > > > > for (si = obj->buckets_elf[sl->sl_elf_hash % obj->nbuckets]; > > > >