about summary refs log tree commit diff
path: root/sysdeps/mach/hurd/dl-sysdep.c
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@gnu.org>2000-08-01 20:24:20 +0000
committerMark Kettenis <kettenis@gnu.org>2000-08-01 20:24:20 +0000
commit15f033cf1cc05b4d25a6c27f65c7c156eae3a9ad (patch)
treea2939a46c1f0edca618cc443452a30b231d1de28 /sysdeps/mach/hurd/dl-sysdep.c
parentb73204bf74da7f304323ff217484ac6905f64728 (diff)
downloadglibc-15f033cf1cc05b4d25a6c27f65c7c156eae3a9ad.tar.gz
glibc-15f033cf1cc05b4d25a6c27f65c7c156eae3a9ad.tar.xz
glibc-15f033cf1cc05b4d25a6c27f65c7c156eae3a9ad.zip
* sysdeps/mach/hurd/dl-sysdep.c (_dl_sysdep_start): Take into acount that elf/rtld's main program might remove some varibales from the environment if we're trying to be secure. Move the Hurd startup data if necessary, or, if we there is no startup data, make sure the magical convention that ARGV[0] is stored just after the environment list.
2000-07-29  Mark Kettenis  <kettenis@gnu.org>

	* sysdeps/mach/hurd/dl-sysdep.c (_dl_sysdep_start): Take into
	acount that elf/rtld's main program might remove some varibales
	from the environment if we're trying to be secure.  Move the Hurd
	startup data if necessary, or, if we there is no startup data,
	make sure the magical convention that ARGV[0] is stored just after
	the environment list.
Diffstat (limited to 'sysdeps/mach/hurd/dl-sysdep.c')
-rw-r--r--sysdeps/mach/hurd/dl-sysdep.c47
1 files changed, 38 insertions, 9 deletions
diff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c
index 099b84bc1c..6dfd9ed22b 100644
--- a/sysdeps/mach/hurd/dl-sysdep.c
+++ b/sysdeps/mach/hurd/dl-sysdep.c
@@ -184,16 +184,45 @@ unfmh();			/* XXX */
 		  _dl_hurd_data->phdrsz / sizeof (Elf32_Phdr),
 		  &_dl_hurd_data->user_entry);
 
-      if (_dl_skip_args && _dl_argv[-_dl_skip_args] == (char *) p)
+      /* The call above might screw a few things up.
+
+	 First of all, if _dl_skip_args is nonzero, we are ignoring
+	 the first few arguments.  However, if we have no Hurd startup
+	 data, it is the magical convention that ARGV[0] == P.  The
+	 startup code in init-first.c will get confused if this is not
+	 the case, so we must rearrange things to make it so.  We'll
+	 overwrite the origional ARGV[0] at P with ARGV[_dl_skip_args].
+
+	 Secondly, if we need to be secure, it removes some dangerous
+	 environment variables.  If we have no Hurd startup date this
+	 changes P (since that's the location after the terminating
+	 NULL in the list of environment variables).  We do the same
+	 thing as in the first case but make sure we recalculate P.
+	 If we do have Hurd startup data, we have to move the data
+	 such that it starts just after the terminating NULL in the
+	 environment list.
+
+	 We use memmove, since the locations might overlap.  */
+      if (__libc_enable_secure || _dl_skip_args)
 	{
-	  /* We are ignoring the first few arguments, but we have no Hurd
-	     startup data.  It is magical convention that ARGV[0] == P in
-	     this case.  The startup code in init-first.c will get confused
-	     if this is not the case, so we must rearrange things to make
-	     it so.  Overwrite the original ARGV[0] at P with
-	     ARGV[_dl_skip_args].  */
-	  assert ((char *) p < _dl_argv[0]);
-	  _dl_argv[0] = strcpy ((char *) p, _dl_argv[0]);
+	  char **newp;
+
+	  for (newp = _environ; *newp++;);
+
+	  if (_dl_argv[-_dl_skip_args] == (char *) p)
+	    {
+	      if ((char *) newp != _dl_argv[0])
+		{
+		  assert ((char *) newp < _dl_argv[0]);
+		  _dl_argv[0] = memmove ((char *) newp, _dl_argv[0],
+					 strlen (_dl_argv[0]) + 1);
+		}
+	    }
+	  else
+	    {
+	      if ((void *) newp != _dl_hurd_data)
+		memmove (newp, _dl_hurd_data, sizeof (*_dl_hurd_data));
+	    }
 	}
 
       {