diff options
author | Andreas Schwab <schwab@suse.de> | 2020-02-19 17:21:46 +0100 |
---|---|---|
committer | Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com> | 2020-03-20 15:23:11 -0300 |
commit | 21344a3d62a29406fddeec069ee4eb3c341369f9 (patch) | |
tree | bffa7bd9e01b3038205e147e7c0eeb7f7a8ef766 | |
parent | 0478174d1e2c2a894a35b1cdffc573dca310b438 (diff) | |
download | glibc-21344a3d62a29406fddeec069ee4eb3c341369f9.tar.gz glibc-21344a3d62a29406fddeec069ee4eb3c341369f9.tar.xz glibc-21344a3d62a29406fddeec069ee4eb3c341369f9.zip |
Fix use-after-free in glob when expanding ~user (bug 25414)
The value of `end_name' points into the value of `dirname', thus don't deallocate the latter before the last use of the former. (cherry picked from commit ddc650e9b3dc916eab417ce9f79e67337b05035c)
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | posix/glob.c | 25 |
2 files changed, 17 insertions, 12 deletions
diff --git a/NEWS b/NEWS index 038541c83b..1d00542a5d 100644 --- a/NEWS +++ b/NEWS @@ -73,6 +73,7 @@ The following bugs are resolved with this release: [25204] Ignore LD_PREFER_MAP_32BIT_EXEC for SUID programs [25225] ld.so fails to link on x86 if GCC defaults to -fcf-protection [25232] No const correctness for strchr et al. for Clang++ + [25414] 'glob' use-after-free bug (CVE-2020-1752) [25423] Array overflow in backtrace on powerpc Security related changes: @@ -109,6 +110,9 @@ Security related changes: addresses for loaded libraries and thus bypass ASLR for a setuid program. Reported by Marcin KoĆcielnicki. + CVE-2020-1752: A use-after-free vulnerability in the glob function when + expanding ~user has been fixed. + Version 2.28 diff --git a/posix/glob.c b/posix/glob.c index 8444b2f79e..1b389d2da1 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -827,31 +827,32 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), { size_t home_len = strlen (p->pw_dir); size_t rest_len = end_name == NULL ? 0 : strlen (end_name); - char *d; + char *d, *newp; + bool use_alloca = glob_use_alloca (alloca_used, + home_len + rest_len + 1); - if (__glibc_unlikely (malloc_dirname)) - free (dirname); - malloc_dirname = 0; - - if (glob_use_alloca (alloca_used, home_len + rest_len + 1)) - dirname = alloca_account (home_len + rest_len + 1, - alloca_used); + if (use_alloca) + newp = alloca_account (home_len + rest_len + 1, alloca_used); else { - dirname = malloc (home_len + rest_len + 1); - if (dirname == NULL) + newp = malloc (home_len + rest_len + 1); + if (newp == NULL) { scratch_buffer_free (&pwtmpbuf); retval = GLOB_NOSPACE; goto out; } - malloc_dirname = 1; } - d = mempcpy (dirname, p->pw_dir, home_len); + d = mempcpy (newp, p->pw_dir, home_len); if (end_name != NULL) d = mempcpy (d, end_name, rest_len); *d = '\0'; + if (__glibc_unlikely (malloc_dirname)) + free (dirname); + dirname = newp; + malloc_dirname = !use_alloca; + dirlen = home_len + rest_len; dirname_modified = 1; } |