NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: lib/57792: SIGSEGV in ld.elf_so / _rtld_call_ifunc



The following reply was made to PR lib/57792; it has been noted by GNATS.

From: RVP <rvp%SDF.ORG@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc: 
Subject: Re: lib/57792: SIGSEGV in ld.elf_so / _rtld_call_ifunc
Date: Tue, 26 Dec 2023 23:51:11 +0000 (UTC)

 On Mon, 25 Dec 2023, Patrick Welche wrote:
 
 > Just repeated the experiment with LD_DEBUG:
 > sp = 0x7f7fffffe6c0, argc = 1, argv = 0x7f7fffffe6d8 <./Gdk-4.0> relocbase 0x7f7ff7ee8000
 > ...
 > headers: digesting PT_DYNAMIC at 0x7f7ff7efdba0
 >   d_tag 16 at 0x7f7ff7efdba0
 >   d_tag 4 at 0x7f7ff7efdbb0
 >   d_tag 5 at 0x7f7ff7efdbc0
 >   d_tag 6 at 0x7f7ff7efdbd0
 >   d_tag 10 at 0x7f7ff7efdbe0
 >   d_tag 11 at 0x7f7ff7efdbf0
 >   d_tag 7 at 0x7f7ff7efdc00
 >   d_tag 8 at 0x7f7ff7efdc10
 >   d_tag 9 at 0x7f7ff7efdc20
 >   d_tag 1879048185 at 0x7f7ff7efdc30
 >  added path "/usr/lib"
 >
 > Does that last d_tag look strangely large?
 >
 
 That's `DT_RELACOUNT':
 
 ```
 $ fgrep DT_RELACOUNT /usr/src/external/bsd/elftoolchain/
 /usr/src/external/bsd/elftoolchain/dist/common/sys/elfconstants.m4:_(`DT_RELACOUNT',        0x6FFFFFF9UL,
 $
 ```
 
 I think what's happening here is the dynamic linker _not_ doing a
 mprotect(PROT_WRITE) before it goes to patch the ifunc addresses
 in an _executable_ (shared libs seem fine) built with RELRO+NOW:
 
 ```
 $ cat i.c
 #include <stdio.h>
 
 #define MAGIC 0xdeadbeefLL
 
 static long long ifunc_helper(void) {
          return MAGIC;
 }
 
 static void* resolve_ifunc(void) {
          return ifunc_helper;
 }
 
 static long long ifunc(void) __attribute__((ifunc ("resolve_ifunc")));
 
 int main(void) {
          printf("calling ifunc\n");
          fflush(stdout);
          return ifunc() != MAGIC;
 }
 
 $ gcc -Wall -Wextra -Wconversion -o i i.c -Wl,-z,now
 $ ./i || echo FAIL
 calling ifunc		# only -z now works
 
 $ gcc -Wall -Wextra -Wconversion -o i i.c -Wl,-z,relro
 $ ./i || echo FAIL
 calling ifunc		# only -z relro also works
 
 $ gcc -Wall -Wextra -Wconversion -o i i.c -Wl,-z,now,-z,relro
 $ ./i || echo FAIL
 Segmentation fault (core dumped)
 FAIL			# -z relro + -z now fails!
 
 $
 ```
 
 Unfortunately, src/tests/libexec/ld.elf_so/t_ifunc.c doesn't test
 with RELRO + NOW, otherwise this would've been caught long ago.
 
 Try compiling the package without `-z now'.
 
 -RVP
 


Home | Main Index | Thread Index | Old Index