diff options
author | Bruno Haible <bruno@clisp.org> | 2020-01-17 21:56:01 +0100 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2020-01-17 21:56:01 +0100 |
commit | 717766da8926e36cf86015c4a49554baa854e8e6 (patch) | |
tree | 9e2b35c4f78edd673ca687fe876d348942df8aca /lib/glob.c | |
parent | 020f5190955808cafb670d2be6afb7d5faf69621 (diff) | |
download | gnulib-717766da8926e36cf86015c4a49554baa854e8e6.tar.gz |
glob: Fix use-after-free bug.
Reported by Tim Rühsen <tim.ruehsen@gmx.de> in
<https://lists.gnu.org/archive/html/bug-gnulib/2020-01/msg00102.html>.
* lib/glob.c (__glob): Delay freeing dirname until after the use of
end_name.
Diffstat (limited to 'lib/glob.c')
-rw-r--r-- | lib/glob.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/lib/glob.c b/lib/glob.c index a67cbb67e0..add5d939d2 100644 --- a/lib/glob.c +++ b/lib/glob.c @@ -843,10 +843,11 @@ __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); + /* dirname contains end_name; we can't free it now. */ + char *prev_dirname = + (__glibc_unlikely (malloc_dirname) ? dirname : NULL); char *d; - if (__glibc_unlikely (malloc_dirname)) - free (dirname); malloc_dirname = 0; if (glob_use_alloca (alloca_used, home_len + rest_len + 1)) @@ -857,6 +858,7 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), dirname = malloc (home_len + rest_len + 1); if (dirname == NULL) { + free (prev_dirname); scratch_buffer_free (&pwtmpbuf); retval = GLOB_NOSPACE; goto out; @@ -868,6 +870,8 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), d = mempcpy (d, end_name, rest_len); *d = '\0'; + free (prev_dirname); + dirlen = home_len + rest_len; dirname_modified = 1; } |