[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: heap-use-after-free in rpl_glob
From: |
Bruno Haible |
Subject: |
Re: heap-use-after-free in rpl_glob |
Date: |
Fri, 17 Jan 2020 18:00:35 +0100 |
User-agent: |
KMail/5.1.3 (Linux/4.4.0-171-generic; KDE/5.18.0; x86_64; ; ) |
Hi Tim,
> The continuous fuzzer at OSS-Fuzz today reported an issue in rpl_glob.
>
> To reproduce with attached C code (on Debian unstable here, same result
> on Ubuntu 16.04.6 docker container with clang 10):
>
> export CC=gcc
> export CFLAGS="-O1 -g -fno-omit-frame-pointer -fsanitize=address
> -fsanitize-address-use-after-scope"
> # ... build gnulib ...
> $CC $CFLAGS -I. -Ilib glob_crash2.c -o glob_crash2 lib/.libs/libgnu.a
> ./glob_crash2
>
> =================================================================
> ==1671628==ERROR: AddressSanitizer: heap-use-after-free on address
> 0x604000000013 at pc 0x55fa90a36ecd bp 0x7ffe68412980 sp 0x7ffe68412978
> READ of size 44 at 0x604000000013 thread T0
> #0 0x55fa90a36ecc in rpl_glob /home/tim/src/wget2/lib/glob.c:868
> #1 0x55fa90a334eb in main /home/tim/src/wget2/glob_crash2.c:35
> #2 0x7fdafafabbba in __libc_start_main ../csu/libc-start.c:308
> #3 0x55fa90a332f9 in _start (/home/tim/src/wget2/glob_crash2+0x22f9)
>
> 0x604000000013 is located 3 bytes inside of 48-byte region
> [0x604000000010,0x604000000040)
> freed by thread T0 here:
> #0 0x7fdafb24c277 in __interceptor_free
> (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x107277)
> #1 0x55fa90a36e31 in rpl_glob /home/tim/src/wget2/lib/glob.c:849
> #2 0x55fa90a334eb in main /home/tim/src/wget2/glob_crash2.c:35
> #3 0x7fdafafabbba in __libc_start_main ../csu/libc-start.c:308
>
> previously allocated by thread T0 here:
> #0 0x7fdafb24c628 in malloc
> (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x107628)
> #1 0x55fa90a35311 in rpl_glob /home/tim/src/wget2/lib/glob.c:565
> #2 0x55fa90a334eb in main /home/tim/src/wget2/glob_crash2.c:35
> #3 0x7fdafafabbba in __libc_start_main ../csu/libc-start.c:308
I can't reproduce the crashes. But the line numbers (565, 849, 868)
from the output above are clearly indicating the problem:
- end_name is part of dirname,
- dirname is freed,
- after dirname is freed, the code still accesses end_name.
Can you please test this patch?
Thank you very much for this report! I expect that the fix will also need
to go into glibc.
2020-01-17 Bruno Haible <address@hidden>
glob: Fix use-after-free bug.
Reported by Tim Rühsen <address@hidden> 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.
diff --git a/lib/glob.c b/lib/glob.c
index a67cbb6..5b34939 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))
@@ -868,6 +869,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;
}