Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Private loader does not support text relocations, which can happen when accidentally linking a non-PIC .a #6543

Closed
derekbruening opened this issue Jan 5, 2024 · 0 comments

Comments

@derekbruening
Copy link
Contributor

Documenting what I saw in PR #6534

I accidentally installed zlib1g-dev without zlib1g, which resulted in libz.a but no libz.so. This caused our CMake code to pick libz.a (you'd think it would also pick it over libz.so even when both are installed but that is not the case; it's a good thing too). Yet the distributed libz.a is not PIC. What ends up happening is that there are relocations in .text but our loader has it already as +rx and does not try to temporarily make it +w. Prior to PR #6542 this surfaced as this assert:

<Application /home/runner/work/dynamorio/dynamorio/build_debug-internal-32/suite/tests/bin/simple_app (24678).  Internal Error: DynamoRIO debug check failure: /home/runner/work/dynamorio/dynamorio/core/synch.c:261 res
(Error occurred @0 frags in tid 24678)

But, that was just an issue hit during processing the SIGSGV. WIth that PR in place we see:

*** cmd failed (255): <Application
310:   /home/runner/work/dynamorio/dynamorio/build_debug-internal-32/suite/tests/bin/simple_app
310:   (21281).  DynamoRIO internal crash at PC 0xf7aae3c1.  Please report this at
310:   [http://dynamorio.org/issues/.](http://dynamorio.org/issues/)  Program aborted.

Diving deeper:

Program received signal SIGSEGV, Segmentation fault.
0xf7c8dce5 in module_relocate_symbol (rel=0xf7f13520, pd=0x433edd64, is_rela=false) at /home/runner/work/dynamorio/dynamorio/core/unix/module_elf.c:1585
1585            *(uint *)r_addr = (uint)(reg_t)res;
(gdb) bt
#0  0xf7c8dce5 in module_relocate_symbol (rel=0xf7f13520, pd=0x433edd64, is_rela=false) at /home/runner/work/dynamorio/dynamorio/core/unix/module_elf.c:1585
#1  0xf7c8ddbf in module_relocate_rel (modbase=0xf7f0f000 "\177ELF\001\001\001", pd=0x433edd64, start=0xf7f12c30, end=0xf7f135c0)
    at /home/runner/work/dynamorio/dynamorio/core/unix/module_elf.c:1614
#2  0xf7c83e75 in privload_relocate_os_privmod_data (opd=0x433edd64, mod_base=0xf7f0f000 "\177ELF\001\001\001") at /home/runner/work/dynamorio/dynamorio/core/unix/loader.c:1254
#3  0xf7c84188 in privload_relocate_mod (mod=0x433edb44) at /home/runner/work/dynamorio/dynamorio/core/unix/loader.c:1304
#4  0xf7c820e4 in privload_process_imports (mod=0x433edb44) at /home/runner/work/dynamorio/dynamorio/core/unix/loader.c:597
#5  0xf7b8b6f6 in privload_load_process (privmod=0x433edb44) at /home/runner/work/dynamorio/dynamorio/core/loader_shared.c:811
#6  0xf7b8b002 in privload_load (filename=0xffffa760 "/home/runner/work/dynamorio/dynamorio/build_debug-internal-32/ext/lib32/debug/libdrsyms.so", dependent=0x433594f8, 
    client=true) at /home/runner/work/dynamorio/dynamorio/core/loader_shared.c:683
#7  0xf7c82a9f in privload_locate_and_load (impname=0xf7f6b6c8 "libdrsyms.so", dependent=0x433594f8, reachable=true)
    at /home/runner/work/dynamorio/dynamorio/core/unix/loader.c:776
#8  0xf7c8204e in privload_process_imports (mod=0x433594f8) at /home/runner/work/dynamorio/dynamorio/core/unix/loader.c:571
#9  0xf7b8b6f6 in privload_load_process (privmod=0x433594f8) at /home/runner/work/dynamorio/dynamorio/core/loader_shared.c:811
#10 0xf7b89918 in privload_process_early_mods () at /home/runner/work/dynamorio/dynamorio/core/loader_shared.c:139
#11 0xf7b89af8 in loader_init_epilogue (dcontext=0x43360b40) at /home/runner/work/dynamorio/dynamorio/core/loader_shared.c:203
#12 0xf7a3052f in dynamorio_app_init_part_two_finalize () at /home/runner/work/dynamorio/dynamorio/core/dynamo.c:675
#13 0xf7c85e38 in privload_early_inject (sp=0xffffbf80, old_libdr_base=0x0, old_libdr_size=0) at /home/runner/work/dynamorio/dynamorio/core/unix/loader.c:2264
#14 0xf7c39a47 in reloaded_xfer () at /home/runner/work/dynamorio/dynamorio/core/arch/x86/x86.asm:1187
(gdb) info local
r_addr = 0xf7f34507
r_type = 2
r_sym = 259
sym = 0xf7f11244
res = 0xfffff059 <error: Cannot access memory at address 0xfffff059>
addend = 0
name = 0xf7f1243b "deflateResetKeep"
resolved = false

The sym is there:

runner@fv-az1148-579:~/work/dynamorio/dynamorio/build_debug-internal-32$ nm ext/lib32/debug/libdrsyms.so | grep deflateReset
000246c0 T deflateReset
00024560 T deflateResetKeep
module_add_segment_data: #=0 0xf7f0f000-0xf7f13c80 0x1
module_add_segment_data: #=1 0xf7f14000-0xf7f481f0 0x5
module_add_segment_data: #=2 0xf7f49000-0xf7f5c008 0x1
module_add_segment_data: #=3 0xf7f5d5f4-0xf7f5e0d4 0x3

f7f0f000-f7f14000 r--p 00000000 08:11 557214                             /home/runner/work/dynamorio/dynamorio/build_debug-internal-32/ext/lib32/debug/libdrsyms.so
f7f14000-f7f49000 r-xp 00005000 08:11 557214                             /home/runner/work/dynamorio/dynamorio/build_debug-internal-32/ext/lib32/debug/libdrsyms.so
f7f49000-f7f5d000 r--p 0003a000 08:11 557214                             /home/runner/work/dynamorio/dynamorio/build_debug-internal-32/ext/lib32/debug/libdrsyms.so
f7f5d000-f7f5f000 rw-p 0004d000 08:11 557214                             /home/runner/work/dynamorio/dynamorio/build_debug-internal-32/ext/lib32/debug/libdrsyms.so

relocating libdrsyms.so
privload_mod_tls_init for #1 libdrsyms.so: offset 1120
module_relocate_rel walking rel 0xf7f12c30-0xf7f135c0
sym lookup for deflateResetKeep from libdrsyms.so
elf_sym_matches: considering type=2 deflateResetKeep
symbol lookup for deflateResetKeep 0xf7f33560

(gdb) info local
r_addr = 0xf7f34507
r_type = 2
r_sym = 259
sym = 0xf7f11244
res = 0xfffff059 <error: Cannot access memory at address 0xfffff059>
addend = 0
name = 0xf7f1243b "deflateResetKeep"
resolved = false
(gdb) x/8i 0xf7f34507-10
   0xf7f344fd:  and    $0x50,%al
   0xf7f344ff:  mov    %eax,0x88(%ebx)
   0xf7f34505:  push   %esi
   0xf7f34506:  call   0xf7f34507
   0xf7f3450b:  add    $0x10,%esp
(gdb) x/1wx 0xf7f34507
0xf7f34507:     0xfffffffc
(gdb) x/4i 0xf7f3450b + 0xfffff059
   0xf7f33564:  push   %ebp
   0xf7f33565:  push   %edi
   0xf7f33566:  push   %esi
   0xf7f33567:  push   %ebx
(gdb) x/4i 0xf7f3450b + 0xfffff059-4
   0xf7f33560:  endbr32 
   0xf7f33564:  push   %ebp

So the reloc looks ok (seems off by 4 though..did I mess sthg up?).
The main issue is the mmap is +rx.
It's relocating .text which is mapped as +rx and is not
writable. I'm guessing text relocation ever
worked, and modern PIC libraries never have text relocs as
there are security policies banning text relocs.

If we expect users to hit this, we could add a better error message,
but given we've never hit this in all these years I would suggest we
do nothing. I documented this so it will show up in searches but I think
we resolve this as Won't Fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant