arrfab / rpms / glibc

Forked from rpms/glibc 5 years ago
Clone

Blame SOURCES/glibc-rh1540480-8.patch

147e83
CVE-2017-16997: Incorrect handling of RPATH or RUNPATH containing $ORIGIN
147e83
for AT_SECURE or SUID binaries could be used to load libraries from the
147e83
current directory.
147e83
147e83
Depends on f6110a8fee2ca36f8e2d2abecf3cba9fa7b8ea7d which is already
147e83
backported by glibc-rh1452721-1.patch.
147e83
147e83
commit 3e3c904daef69b8bf7d5cc07f793c9f07c3553ef
147e83
Author: Aurelien Jarno <aurelien@aurel32.net>
147e83
Date:   Sat Dec 30 10:54:23 2017 +0100
147e83
147e83
    elf: Check for empty tokens before dynamic string token expansion [BZ #22625]
147e83
147e83
    The fillin_rpath function in elf/dl-load.c loops over each RPATH or
147e83
    RUNPATH tokens and interprets empty tokens as the current directory
147e83
    ("./"). In practice the check for empty token is done *after* the
147e83
    dynamic string token expansion. The expansion process can return an
147e83
    empty string for the $ORIGIN token if __libc_enable_secure is set
147e83
    or if the path of the binary can not be determined (/proc not mounted).
147e83
147e83
    Fix that by moving the check for empty tokens before the dynamic string
147e83
    token expansion. In addition, check for NULL pointer or empty strings
147e83
    return by expand_dynamic_string_token.
147e83
147e83
    The above changes highlighted a bug in decompose_rpath, an empty array
147e83
    is represented by the first element being NULL at the fillin_rpath
147e83
    level, but by using a -1 pointer in decompose_rpath and other functions.
147e83
147e83
    Changelog:
147e83
            [BZ #22625]
147e83
            * elf/dl-load.c (fillin_rpath): Check for empty tokens before dynamic
147e83
            string token expansion. Check for NULL pointer or empty string possibly
147e83
            returned by expand_dynamic_string_token.
147e83
            (decompose_rpath): Check for empty path after dynamic string
147e83
            token expansion.
147e83
147e83
Index: glibc-2.17-c758a686/elf/dl-load.c
147e83
===================================================================
147e83
--- glibc-2.17-c758a686.orig/elf/dl-load.c
147e83
+++ glibc-2.17-c758a686/elf/dl-load.c
147e83
@@ -447,31 +447,39 @@ fillin_rpath (char *rpath, struct r_sear
147e83
 {
147e83
   char *cp;
147e83
   size_t nelems = 0;
147e83
-  char *to_free;
147e83
 
147e83
   while ((cp = __strsep (&rpath, sep)) != NULL)
147e83
     {
147e83
       struct r_search_path_elem *dirp;
147e83
+      char *to_free = NULL;
147e83
+      size_t len = 0;
147e83
 
147e83
-      to_free = cp = expand_dynamic_string_token (l, cp);
147e83
-
147e83
-      size_t len = strlen (cp);
147e83
-
147e83
-      /* `strsep' can pass an empty string.  This has to be
147e83
-	 interpreted as `use the current directory'. */
147e83
-      if (len == 0)
147e83
+      /* `strsep' can pass an empty string.  */
147e83
+      if (*cp != '\0')
147e83
 	{
147e83
-	  static const char curwd[] = "./";
147e83
-	  cp = (char *) curwd;
147e83
-	}
147e83
+	  to_free = cp = expand_dynamic_string_token (l, cp);
147e83
+	  /* expand_dynamic_string_token can return NULL in case of empty
147e83
+	     path or memory allocation failure.  */
147e83
+	  if (cp == NULL)
147e83
+	    continue;
147e83
+
147e83
+	  /* Compute the length after dynamic string token expansion and
147e83
+	     ignore empty paths.  */
147e83
+	  len = strlen (cp);
147e83
+	  if (len == 0)
147e83
+	    {
147e83
+	      free (to_free);
147e83
+	      continue;
147e83
+	    }
147e83
 
147e83
-      /* Remove trailing slashes (except for "/").  */
147e83
-      while (len > 1 && cp[len - 1] == '/')
147e83
-	--len;
147e83
-
147e83
-      /* Now add one if there is none so far.  */
147e83
-      if (len > 0 && cp[len - 1] != '/')
147e83
-	cp[len++] = '/';
147e83
+	  /* Remove trailing slashes (except for "/").  */
147e83
+	  while (len > 1 && cp[len - 1] == '/')
147e83
+	    --len;
147e83
+
147e83
+	  /* Now add one if there is none so far.  */
147e83
+	  if (len > 0 && cp[len - 1] != '/')
147e83
+	    cp[len++] = '/';
147e83
+	}
147e83
 
147e83
       /* See if this directory is already known.  */
147e83
       for (dirp = GL(dl_all_dirs); dirp != NULL; dirp = dirp->next)
147e83
@@ -626,6 +634,14 @@ decompose_rpath (struct r_search_path_st
147e83
      necessary.  */
147e83
   free (copy);
147e83
 
147e83
+  /* There is no path after expansion.  */
147e83
+  if (result[0] == NULL)
147e83
+    {
147e83
+      free (result);
147e83
+      sps->dirs = (struct r_search_path_elem **) -1;
147e83
+      return false;
147e83
+    }
147e83
+
147e83
   sps->dirs = result;
147e83
   /* The caller will change this value if we haven't used a real malloc.  */
147e83
   sps->malloced = 1;