svn commit: r356444 - head/libexec/rtld-elf

Ryan Stone rstone at FreeBSD.org
Tue Jan 7 16:03:12 UTC 2020


Author: rstone
Date: Tue Jan  7 16:03:11 2020
New Revision: 356444
URL: https://svnweb.freebsd.org/changeset/base/356444

Log:
  rtld: Fix segfault in direct exec mode
  
  When rtld is directly executed with arguments, it has to move the
  program arguments, environment and elf aux data up a few slots to
  remove its own arguments before the process being executed sees
  them.  When copying the environment, rtld was incorrectly testing
  whether the location about to be written to currently contained
  NULL, when was supposed to check whether it had just copied the
  NULL terminator of the environment string.  This had the result
  that the ELF aux data was mostly treated as environment variables,
  and rtld would quickly crash when it tried to access required
  ELF aux data that it didn't think was present.
  
  Differential Revision:	https://reviews.freebsd.org/D23008
  Reviewed by:	kib
  MFC after:	1 month

Modified:
  head/libexec/rtld-elf/rtld.c

Modified: head/libexec/rtld-elf/rtld.c
==============================================================================
--- head/libexec/rtld-elf/rtld.c	Tue Jan  7 15:59:31 2020	(r356443)
+++ head/libexec/rtld-elf/rtld.c	Tue Jan  7 16:03:11 2020	(r356444)
@@ -514,12 +514,13 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entr
 		    argv[i] = argv[i + rtld_argc];
 		*argcp -= rtld_argc;
 		environ = env = envp = argv + main_argc + 1;
+		dbg("move env from %p to %p", envp + rtld_argc, envp);
 		do {
 		    *envp = *(envp + rtld_argc);
-		    envp++;
-		} while (*envp != NULL);
+		}  while (*envp++ != NULL);
 		aux = auxp = (Elf_Auxinfo *)envp;
 		auxpf = (Elf_Auxinfo *)(envp + rtld_argc);
+		dbg("move aux from %p to %p", auxpf, aux);
 		/* XXXKIB insert place for AT_EXECPATH if not present */
 		for (;; auxp++, auxpf++) {
 		    *auxp = *auxpf;


More information about the svn-src-head mailing list