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.
This commit is contained in:
Andreas Schwab 2020-02-19 17:21:46 +01:00
parent f2323817dd
commit ddc650e9b3
1 changed files with 13 additions and 12 deletions

View File

@ -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 home_len = strlen (p->pw_dir);
size_t rest_len = end_name == NULL ? 0 : strlen (end_name); 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)) if (use_alloca)
free (dirname); newp = alloca_account (home_len + rest_len + 1, alloca_used);
malloc_dirname = 0;
if (glob_use_alloca (alloca_used, home_len + rest_len + 1))
dirname = alloca_account (home_len + rest_len + 1,
alloca_used);
else else
{ {
dirname = malloc (home_len + rest_len + 1); newp = malloc (home_len + rest_len + 1);
if (dirname == NULL) if (newp == NULL)
{ {
scratch_buffer_free (&pwtmpbuf); scratch_buffer_free (&pwtmpbuf);
retval = GLOB_NOSPACE; retval = GLOB_NOSPACE;
goto out; 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) if (end_name != NULL)
d = mempcpy (d, end_name, rest_len); d = mempcpy (d, end_name, rest_len);
*d = '\0'; *d = '\0';
if (__glibc_unlikely (malloc_dirname))
free (dirname);
dirname = newp;
malloc_dirname = !use_alloca;
dirlen = home_len + rest_len; dirlen = home_len + rest_len;
dirname_modified = 1; dirname_modified = 1;
} }