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: Taylor R Campbell <riastradh%NetBSD.org@localhost>
To: prlw1%cam.ac.uk@localhost
Cc: gnats-bugs%NetBSD.org@localhost, netbsd-bugs%NetBSD.org@localhost
Subject: Re: lib/57792: SIGSEGV in ld.elf_so / _rtld_call_ifunc
Date: Fri, 18 Apr 2025 02:00:25 +0000

 This is a multi-part message in MIME format.
 --=_rhGMeJlKcnVU63TmxERqST609Awrm+9s
 
 The attached patch should resolve the underlying issue -- both fixing
 the t_ifunc_now test, and fixing the gtk4 issue.  Details in the
 commit message.
 
 --=_rhGMeJlKcnVU63TmxERqST609Awrm+9s
 Content-Type: text/plain; charset="ISO-8859-1"; name="pr57792-ldelfsodefereagerrelro"
 Content-Transfer-Encoding: quoted-printable
 Content-Disposition: attachment; filename="pr57792-ldelfsodefereagerrelro.patch"
 
 # HG changeset patch
 # User Taylor R Campbell <riastradh%NetBSD.org@localhost>
 # Date 1744941415 0
 #      Fri Apr 18 01:56:55 2025 +0000
 # Branch trunk
 # Node ID f0c0c2d90c130d5e6e06ac9f5a230a3902d23412
 # Parent  438b14ea036dd2bd2e1109f5e08f7d74109e6fae
 # EXP-Topic riastradh-pr57792-relrorounding
 ld.elf_so(1): Defer RELRO a bit for eagerly-bound (-z now) programs.
 
 GNU binutils links programs a little differently if they're eagerly
 bound with -Wl,-z,now.  In particular, the part of the .got relocated
 for ifuncs is covered by the RELRO region in eagerly-bound programs
 (-z now), but not in lazily-bound programs (default).
 
 Presumably this is done under the premise that eagerly-bound programs
 will resolve all ifuncs at startup _before_ mprotecting the main
 object's RELRO region.  But ld.elf_so was mprotecting it first, in
 _rtld_do_copy_relocations, and then resolving ifuncs -- at which the
 memory locations where it tries to write the resolutions will be
 mapped read-only.
 
 (In contrast, for lazily bound programs, ifuncs may also be resolved
 lazily, so the locations they relocate are _not_ covered by the RELRO
 region and we don't run into any trouble)
 
 To avoid this trouble, for eagerly-bound programs, we defer the RELRO
 mprotect of the main object by a little bit -- we move it from
 _rtld_do_copy_relocations to just after _rtld_call_init_functions.
 
 PR lib/57792: SIGSEGV in ld.elf_so / _rtld_call_ifunc
 
 diff -r 438b14ea036d -r f0c0c2d90c13 libexec/ld.elf_so/reloc.c
 --- a/libexec/ld.elf_so/reloc.c	Thu Apr 17 13:43:59 2025 +0000
 +++ b/libexec/ld.elf_so/reloc.c	Fri Apr 18 01:56:55 2025 +0000
 @@ -154,7 +154,22 @@ int
  		}
  	}
  #ifdef GNU_RELRO
 -	if (_rtld_relro(dstobj, true) =3D=3D -1)
 +	/*
 +	 * If the main program is lazily bound (default -- whether or
 +	 * not LD_BINDNOW is set in the calling environment), we are
 +	 * now done writing to anything covered by RELRO and we can
 +	 * safely make it read-only.  There may still be ifunc
 +	 * resolution to do later; it will happen in a read/write
 +	 * segment and will not be made read-only.
 +	 *
 +	 * But if the main program is eagerly bound (i.e., the object
 +	 * has DF_1_NOW set in DT_FLAGS_1, whether or not LD_BIND_NOW
 +	 * is set in the calling environment), we delay protecting the
 +	 * RELRO region as read-only until we have resolved ifuncs --
 +	 * at which point we will make the ifunc resolution read-only
 +	 * too.
 +	 */
 +	if (!dstobj->z_now && _rtld_relro(dstobj, true) =3D=3D -1)
  		return -1;
  #endif
  #endif /* RTLD_INHIBIT_COPY_RELOCS */
 diff -r 438b14ea036d -r f0c0c2d90c13 libexec/ld.elf_so/rtld.c
 --- a/libexec/ld.elf_so/rtld.c	Thu Apr 17 13:43:59 2025 +0000
 +++ b/libexec/ld.elf_so/rtld.c	Fri Apr 18 01:56:55 2025 +0000
 @@ -806,6 +806,27 @@ Elf_Addr
 =20
  	_rtld_exclusive_exit(&mask);
 =20
 +#ifdef GNU_RELRO
 +	/*
 +	 * If the main program is lazily bound (default -- whether or
 +	 * not LD_BINDNOW is set in the calling environment), its RELRO
 +	 * region has already been mapped read-only in
 +	 * _rtld_do_copy_relocations.  The ifunc resolutions lie
 +	 * outside this region, so future lazy ifunc resolution is
 +	 * unaffected by the RELRO region's being read-only.
 +	 *
 +	 * If the main program is eagerly bound (i.e., the object has
 +	 * DF_1_NOW set in DT_FLAGS_1, whether or not LD_BIND_NOW is
 +	 * set in the calling environment), we deferred that from
 +	 * _rtld_do_copy_relocations so that the ifunc resolution, we
 +	 * have now resolved all ifuncs in it, so we can commit the
 +	 * RELRO region to be read-only -- and that means ifunc
 +	 * resolutions are read-only too.
 +	 */
 +	if (_rtld_objmain->z_now && _rtld_relro(_rtld_objmain, true) =3D=3D -1)
 +		return -1;
 +#endif
 +
  	/*
  	 * Return with the entry point and the exit procedure in at the top
  	 * of stack.
 
 --=_rhGMeJlKcnVU63TmxERqST609Awrm+9s--
 


Home | Main Index | Thread Index | Old Index