about summary refs log tree commit diff
path: root/elf/dl-load.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1998-02-17 18:23:42 +0000
committerUlrich Drepper <drepper@redhat.com>1998-02-17 18:23:42 +0000
commitc6222ab921cee390ea3aab57795e028d587b77e2 (patch)
tree1786e626fbd5876fac5496febe5f5c118d4c0ac8 /elf/dl-load.c
parent71a14d64831fed0b9fd6a0488aff6d6eab89b448 (diff)
downloadglibc-c6222ab921cee390ea3aab57795e028d587b77e2.tar.gz
glibc-c6222ab921cee390ea3aab57795e028d587b77e2.tar.xz
glibc-c6222ab921cee390ea3aab57795e028d587b77e2.zip
Update.
1998-02-17 17:41  Ulrich Drepper  <drepper@cygnus.com>

	* elf/dl-load.c (open_path): Take extra argument PRELOADED.
	If PRELOADED is nonzero check in case of an SUID application
	whether the shared object has the SUID bit set.
	Fix some other problems with handling shared objects in system
	specific directories.
	(_dl_map_object): Also take extra parameter and pass it to open_path.
	* elf/link.h (_dl_map_object): Correct prototype and comment.
	* elf/rtld.c (dl_main): Call _dl_map_object correctly.
	* elf/dl-open.c (_dl_open): Likewise.
	* elf/dl-deps.c (openaux, _dl_map_object_deps): Likewise.

	* sysdeps/libm-ieee754/s_modfl.c: Handle numbers > 1.0 correctly.

	* math/libm-test.c (modf_test): Add test for 1.5.
Diffstat (limited to 'elf/dl-load.c')
-rw-r--r--elf/dl-load.c61
1 files changed, 52 insertions, 9 deletions
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 96c1eb6bc6..cc94d7b510 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -793,7 +793,7 @@ _dl_map_object_from_fd (char *name, int fd, char *realname,
    with the malloc'd full directory name.  */
 
 static int
-open_path (const char *name, size_t namelen,
+open_path (const char *name, size_t namelen, int preloaded,
 	   struct r_search_path_elem **dirs,
 	   char **realname)
 {
@@ -839,9 +839,31 @@ open_path (const char *name, size_t namelen,
 		else
 		  this_dir->machdirstatus = existing;
 	      }
+	  if (fd != -1 && preloaded && __libc_enable_secure)
+	    {
+	      /* This is an extra security effort to make sure nobody can
+		 preload broken shared objects which are in the trusted
+		 directories and so exploit the bugs.  */
+	      struct stat st;
+
+	      if (__fxstat (_STAT_VER, fd, &st) != 0
+		  || (st.st_mode & S_ISUID) == 0)
+		{
+		  /* The shared object cannot be tested for being SUID
+		     or this bit is not set.  In this case we must not
+		     use this object.  */
+		  __close (fd);
+		  fd = -1;
+		  /* We simply ignore the file, signal this by setting
+		     the error value which would have been set by `open'.  */
+		  errno = ENOENT;
+		}
+	    }
 	}
+      else
+	errno = ENOENT;
 
-      if (fd == -1 && this_dir->dirstatus != nonexisting)
+      if (fd == -1 && errno == ENOENT && this_dir->dirstatus != nonexisting)
 	{
 	  /* Construct the pathname to try.  */
 	  buflen = ((char *) __mempcpy (__mempcpy (buf, this_dir->dirname,
@@ -871,12 +893,32 @@ open_path (const char *name, size_t namelen,
 		  else
 		    this_dir->dirstatus = existing;
 		}
+	  if (fd != -1 && preloaded && __libc_enable_secure)
+	    {
+	      /* This is an extra security effort to make sure nobody can
+		 preload broken shared objects which are in the trusted
+		 directories and so exploit the bugs.  */
+	      struct stat st;
+
+	      if (__fxstat (_STAT_VER, fd, &st) != 0
+		  || (st.st_mode & S_ISUID) == 0)
+		{
+		  /* The shared object cannot be tested for being SUID
+		     or this bit is not set.  In this case we must not
+		     use this object.  */
+		  __close (fd);
+		  fd = -1;
+		  /* We simply ignore the file, signal this by setting
+		     the error value which would have been set by `open'.  */
+		  errno = ENOENT;
+		}
+	    }
 	}
 
       if (fd != -1)
 	{
 	  *realname = malloc (buflen);
-	  if (*realname)
+	  if (*realname != NULL)
 	    {
 	      memcpy (*realname, buf, buflen);
 	      return fd;
@@ -901,8 +943,8 @@ open_path (const char *name, size_t namelen,
 /* Map in the shared object file NAME.  */
 
 struct link_map *
-_dl_map_object (struct link_map *loader, const char *name, int type,
-		int trace_mode)
+_dl_map_object (struct link_map *loader, const char *name, int preloaded,
+		int type, int trace_mode)
 {
   int fd;
   char *realname;
@@ -963,7 +1005,8 @@ _dl_map_object (struct link_map *loader, const char *name, int type,
 	      }
 
 	    if (l->l_rpath_dirs != (struct r_search_path_elem **) -1l)
-	      fd = open_path (name, namelen, l->l_rpath_dirs, &realname);
+	      fd = open_path (name, namelen, preloaded, l->l_rpath_dirs,
+			      &realname);
 	  }
 
       /* If dynamically linked, try the DT_RPATH of the executable itself
@@ -971,12 +1014,12 @@ _dl_map_object (struct link_map *loader, const char *name, int type,
       l = _dl_loaded;
       if (fd == -1 && l && l->l_type != lt_loaded
 	  && l->l_rpath_dirs != (struct r_search_path_elem **) -1l)
-	fd = open_path (name, namelen, l->l_rpath_dirs, &realname);
+	fd = open_path (name, namelen, preloaded, l->l_rpath_dirs, &realname);
 
       /* This is used if a static binary uses dynamic loading and there
 	 is a LD_LIBRARY_PATH given.  */
       if (fd == -1 && fake_path_list != NULL)
-	fd = open_path (name, namelen, fake_path_list, &realname);
+	fd = open_path (name, namelen, preloaded, fake_path_list, &realname);
 
       if (fd == -1)
 	{
@@ -1001,7 +1044,7 @@ _dl_map_object (struct link_map *loader, const char *name, int type,
 
       /* Finally, try the default path.  */
       if (fd == -1)
-	fd = open_path (name, namelen, rtld_search_dirs, &realname);
+	fd = open_path (name, namelen, preloaded, rtld_search_dirs, &realname);
     }
   else
     {