forked from rpms/glibc
		
	CVE-2023-4911 glibc: buffer overflow in ld.so leading to privilege escalation
Resolves: RHEL-3036
This commit is contained in:
		
							parent
							
								
									114cf7bf60
								
							
						
					
					
						commit
						113ab44550
					
				
							
								
								
									
										157
									
								
								glibc-RHEL-3036.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								glibc-RHEL-3036.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,157 @@ | |||||||
|  | This patch was developed under embargo and cannot reference an upstream | ||||||
|  | commit. To find the associated commit please review the upstream git | ||||||
|  | log for CVE-2023-4911 to identify the relevant commits. | ||||||
|  | 
 | ||||||
|  | Author: Siddhesh Poyarekar <siddhesh@sourceware.org> | ||||||
|  | Date:   Tue Sep 19 18:39:32 2023 -0400 | ||||||
|  | 
 | ||||||
|  |     tunables: Terminate if end of input is reached (CVE-2023-4911) | ||||||
|  |      | ||||||
|  |     The string parsing routine may end up writing beyond bounds of tunestr | ||||||
|  |     if the input tunable string is malformed, of the form name=name=val. | ||||||
|  |     This gets processed twice, first as name=name=val and next as name=val, | ||||||
|  |     resulting in tunestr being name=name=val:name=val, thus overflowing | ||||||
|  |     tunestr. | ||||||
|  |      | ||||||
|  |     Terminate the parsing loop at the first instance itself so that tunestr | ||||||
|  |     does not overflow. | ||||||
|  |      | ||||||
|  |     This also fixes up tst-env-setuid-tunables to actually handle failures | ||||||
|  |     correct and add new tests to validate the fix for this CVE. | ||||||
|  |      | ||||||
|  |     Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org> | ||||||
|  |     Reviewed-by: Carlos O'Donell <carlos@redhat.com> | ||||||
|  | 
 | ||||||
|  | Conflicts: | ||||||
|  | 	NEWS | ||||||
|  | 	(Dropped) | ||||||
|  | 	elf/tst-env-setuid-tunables.c | ||||||
|  | 	(Trivial conflict at HAVE_TUNABLES) | ||||||
|  | 
 | ||||||
|  | diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
 | ||||||
|  | index 3c84809d44381241..2c878e08ea197b29 100644
 | ||||||
|  | --- a/elf/dl-tunables.c
 | ||||||
|  | +++ b/elf/dl-tunables.c
 | ||||||
|  | @@ -193,11 +193,7 @@ parse_tunables (char *tunestr, char *valstring)
 | ||||||
|  |        /* If we reach the end of the string before getting a valid name-value | ||||||
|  |  	 pair, bail out.  */ | ||||||
|  |        if (p[len] == '\0') | ||||||
|  | -	{
 | ||||||
|  | -	  if (__libc_enable_secure)
 | ||||||
|  | -	    tunestr[off] = '\0';
 | ||||||
|  | -	  return;
 | ||||||
|  | -	}
 | ||||||
|  | +	break;
 | ||||||
|  |   | ||||||
|  |        /* We did not find a valid name-value pair before encountering the | ||||||
|  |  	 colon.  */ | ||||||
|  | @@ -257,9 +253,16 @@ parse_tunables (char *tunestr, char *valstring)
 | ||||||
|  |  	    } | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -      if (p[len] != '\0')
 | ||||||
|  | -	p += len + 1;
 | ||||||
|  | +      /* We reached the end while processing the tunable string.  */
 | ||||||
|  | +      if (p[len] == '\0')
 | ||||||
|  | +	break;
 | ||||||
|  | +
 | ||||||
|  | +      p += len + 1;
 | ||||||
|  |      } | ||||||
|  | +
 | ||||||
|  | +  /* Terminate tunestr before we leave.  */
 | ||||||
|  | +  if (__libc_enable_secure)
 | ||||||
|  | +    tunestr[off] = '\0';
 | ||||||
|  |  } | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  | diff --git a/elf/tst-env-setuid-tunables.c b/elf/tst-env-setuid-tunables.c
 | ||||||
|  | index 0b9b075c40598c6f..8b0861c4ad853040 100644
 | ||||||
|  | --- a/elf/tst-env-setuid-tunables.c
 | ||||||
|  | +++ b/elf/tst-env-setuid-tunables.c
 | ||||||
|  | @@ -52,6 +52,8 @@ const char *teststrings[] =
 | ||||||
|  |    "glibc.malloc.perturb=0x800:not_valid.malloc.check=2:glibc.malloc.mmap_threshold=4096", | ||||||
|  |    "glibc.not_valid.check=2:glibc.malloc.mmap_threshold=4096", | ||||||
|  |    "not_valid.malloc.check=2:glibc.malloc.mmap_threshold=4096", | ||||||
|  | +  "glibc.malloc.mmap_threshold=glibc.malloc.mmap_threshold=4096",
 | ||||||
|  | +  "glibc.malloc.check=2",
 | ||||||
|  |    "glibc.malloc.garbage=2:glibc.maoc.mmap_threshold=4096:glibc.malloc.check=2", | ||||||
|  |    "glibc.malloc.check=4:glibc.malloc.garbage=2:glibc.maoc.mmap_threshold=4096", | ||||||
|  |    ":glibc.malloc.garbage=2:glibc.malloc.check=1", | ||||||
|  | @@ -70,6 +72,8 @@ const char *resultstrings[] =
 | ||||||
|  |    "glibc.malloc.perturb=0x800:glibc.malloc.mmap_threshold=4096", | ||||||
|  |    "glibc.malloc.mmap_threshold=4096", | ||||||
|  |    "glibc.malloc.mmap_threshold=4096", | ||||||
|  | +  "glibc.malloc.mmap_threshold=glibc.malloc.mmap_threshold=4096",
 | ||||||
|  | +  "",
 | ||||||
|  |    "", | ||||||
|  |    "", | ||||||
|  |    "", | ||||||
|  | @@ -84,11 +88,18 @@ test_child (int off)
 | ||||||
|  |    const char *val = getenv ("GLIBC_TUNABLES"); | ||||||
|  |   | ||||||
|  |  #if HAVE_TUNABLES | ||||||
|  | +  printf ("    [%d] GLIBC_TUNABLES is %s\n", off, val);
 | ||||||
|  | +  fflush (stdout);
 | ||||||
|  |    if (val != NULL && strcmp (val, resultstrings[off]) == 0) | ||||||
|  |      return 0; | ||||||
|  |   | ||||||
|  |    if (val != NULL) | ||||||
|  | -    printf ("[%d] Unexpected GLIBC_TUNABLES VALUE %s\n", off, val);
 | ||||||
|  | +    printf ("    [%d] Unexpected GLIBC_TUNABLES VALUE %s, expected %s\n",
 | ||||||
|  | +	    off, val, resultstrings[off]);
 | ||||||
|  | +  else
 | ||||||
|  | +    printf ("    [%d] GLIBC_TUNABLES environment variable absent\n", off);
 | ||||||
|  | +
 | ||||||
|  | +  fflush (stdout);
 | ||||||
|  |   | ||||||
|  |    return 1; | ||||||
|  |  #else | ||||||
|  | @@ -117,21 +128,26 @@ do_test (int argc, char **argv)
 | ||||||
|  |        if (ret != 0) | ||||||
|  |  	exit (1); | ||||||
|  |   | ||||||
|  | -      exit (EXIT_SUCCESS);
 | ||||||
|  | +      /* Special return code to make sure that the child executed all the way
 | ||||||
|  | +	 through.  */
 | ||||||
|  | +      exit (42);
 | ||||||
|  |      } | ||||||
|  |    else | ||||||
|  |      { | ||||||
|  | -      int ret = 0;
 | ||||||
|  | -
 | ||||||
|  |        /* Spawn tests.  */ | ||||||
|  |        for (int i = 0; i < array_length (teststrings); i++) | ||||||
|  |  	{ | ||||||
|  |  	  char buf[INT_BUFSIZE_BOUND (int)]; | ||||||
|  |   | ||||||
|  | -	  printf ("Spawned test for %s (%d)\n", teststrings[i], i);
 | ||||||
|  | +	  printf ("[%d] Spawned test for %s\n", i, teststrings[i]);
 | ||||||
|  |  	  snprintf (buf, sizeof (buf), "%d\n", i); | ||||||
|  | +	  fflush (stdout);
 | ||||||
|  |  	  if (setenv ("GLIBC_TUNABLES", teststrings[i], 1) != 0) | ||||||
|  | -	    exit (1);
 | ||||||
|  | +	    {
 | ||||||
|  | +	      printf ("    [%d] Failed to set GLIBC_TUNABLES: %m", i);
 | ||||||
|  | +	      support_record_failure ();
 | ||||||
|  | +	      continue;
 | ||||||
|  | +	    }
 | ||||||
|  |   | ||||||
|  |  	  int status = support_capture_subprogram_self_sgid (buf); | ||||||
|  |   | ||||||
|  | @@ -139,9 +155,14 @@ do_test (int argc, char **argv)
 | ||||||
|  |  	  if (WEXITSTATUS (status) == EXIT_UNSUPPORTED) | ||||||
|  |  	    return EXIT_UNSUPPORTED; | ||||||
|  |   | ||||||
|  | -	  ret |= status;
 | ||||||
|  | +	  if (WEXITSTATUS (status) != 42)
 | ||||||
|  | +	    {
 | ||||||
|  | +	      printf ("    [%d] child failed with status %d\n", i,
 | ||||||
|  | +		      WEXITSTATUS (status));
 | ||||||
|  | +	      support_record_failure ();
 | ||||||
|  | +	    }
 | ||||||
|  |  	} | ||||||
|  | -      return ret;
 | ||||||
|  | +      return 0;
 | ||||||
|  |      } | ||||||
|  |  } | ||||||
|  |   | ||||||
| @ -132,7 +132,7 @@ end \ | |||||||
| Summary: The GNU libc libraries | Summary: The GNU libc libraries | ||||||
| Name: glibc | Name: glibc | ||||||
| Version: %{glibcversion} | Version: %{glibcversion} | ||||||
| Release: %{glibcrelease}.6 | Release: %{glibcrelease}.7 | ||||||
| 
 | 
 | ||||||
| # In general, GPLv2+ is used by programs, LGPLv2+ is used for | # In general, GPLv2+ is used by programs, LGPLv2+ is used for | ||||||
| # libraries. | # libraries. | ||||||
| @ -1052,6 +1052,7 @@ Patch864: glibc-rh2234714.patch | |||||||
| Patch865: glibc-RHEL-2435.patch | Patch865: glibc-RHEL-2435.patch | ||||||
| Patch866: glibc-RHEL-2435-2.patch | Patch866: glibc-RHEL-2435-2.patch | ||||||
| Patch867: glibc-RHEL-2423.patch | Patch867: glibc-RHEL-2423.patch | ||||||
|  | Patch868: glibc-RHEL-3036.patch | ||||||
| 
 | 
 | ||||||
| ############################################################################## | ############################################################################## | ||||||
| # Continued list of core "glibc" package information: | # Continued list of core "glibc" package information: | ||||||
| @ -2882,6 +2883,9 @@ fi | |||||||
| %files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared | %files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared | ||||||
| 
 | 
 | ||||||
| %changelog | %changelog | ||||||
|  | * Wed Sep 20 2023 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.28-236.7 | ||||||
|  | - CVE-2023-4911 glibc: buffer overflow in ld.so leading to privilege escalation (RHEL-3036) | ||||||
|  | 
 | ||||||
| * Tue Sep 19 2023 Carlos O'Donell <carlos@redhat.com> - 2.28-236.6 | * Tue Sep 19 2023 Carlos O'Donell <carlos@redhat.com> - 2.28-236.6 | ||||||
| - Revert: Always call destructors in reverse constructor order (#2233338) | - Revert: Always call destructors in reverse constructor order (#2233338) | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user