Hello, I found a UAF when running the following fuzz driver in OSS-Fuzz environment.
#include "config.h"
#include "augeas.h"
#include "internal.h"
#include "memory.h"
#include "syntax.h"
#include "transform.h"
#include "errcode.h"
#include <fnmatch.h>
#include <argz.h>
#include <string.h>
#include <stdarg.h>
#include <locale.h>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if(size<3){
return 0;
}
char *loadpath = NULL;
char *new_str = (char *)malloc(size+1);
if (new_str == NULL){
return 0;
}
memcpy(new_str, data, size);
new_str[size] = '\0';
struct augeas *aug = aug_init(new_str, loadpath, AUG_NO_STDINC|AUG_NO_LOAD);
aug_rm(aug, new_str);
free(new_str);
aug_close(aug);
return 0;
}
==11==ERROR: AddressSanitizer: heap-use-after-free on address 0x506000147e68 at pc 0x56103e2834df bp 0x7ffc83afceb0 sp 0x7ffc83afcea8
READ of size 8 at 0x506000147e68 thread T0
SCARINESS: 51 (8-byte-read-heap-use-after-free)
#0 0x56103e2834de in tree_unlink_raw /src/augeas/src/augeas.c:661:5
#1 0x56103e287b0f in tree_rm /src/augeas/src/augeas.c:1184:20
#2 0x56103e287e65 in aug_rm /src/augeas/src/augeas.c:1201:14
#3 0x56103e27c9fe in LLVMFuzzerTestOneInput /src/augeas/augeas_aug_rm_fuzzer.cc:33:2
#4 0x56103e1314d0 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:614:13
#5 0x56103e130cf5 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:516:7
#6 0x56103e1324d5 in fuzzer::Fuzzer::MutateAndTestOne() /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:760:19
#7 0x56103e133265 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, std::__Fuzzer::allocator<fuzzer::SizedFile>>&) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:905:5
#8 0x56103e1220ab in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:914:6
#9 0x56103e14d482 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
#10 0x7fc6ba0e1082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) (BuildId: 0323ab4806bee6f846d9ad4bccfc29afdca49a58)
#11 0x56103e11492d in _start (/out/augeas_aug_rm_fuzzer+0xb792d)
DEDUP_TOKEN: tree_unlink_raw--tree_rm--aug_rm
0x506000147e68 is located 8 bytes inside of 56-byte region [0x506000147e60,0x506000147e98)
freed by thread T0 here:
#0 0x56103e23d006 in free /src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:52:3
#1 0x56103e34a7fa in rpl_free /src/augeas/gnulib/lib/free.c:48:3
#2 0x56103e280f77 in free_tree_node /src/augeas/src/augeas.c:654:5
#3 0x56103e280f77 in free_tree /src/augeas/src/augeas.c:1132:9
#4 0x56103e2833e5 in tree_unlink_raw /src/augeas/src/augeas.c:664:14
#5 0x56103e287b0f in tree_rm /src/augeas/src/augeas.c:1184:20
#6 0x56103e287e65 in aug_rm /src/augeas/src/augeas.c:1201:14
#7 0x56103e27c9fe in LLVMFuzzerTestOneInput /src/augeas/augeas_aug_rm_fuzzer.cc:33:2
#8 0x56103e1314d0 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:614:13
#9 0x56103e130cf5 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:516:7
#10 0x56103e1324d5 in fuzzer::Fuzzer::MutateAndTestOne() /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:760:19
#11 0x56103e133265 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, std::__Fuzzer::allocator<fuzzer::SizedFile>>&) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:905:5
#12 0x56103e1220ab in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:914:6
#13 0x56103e14d482 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
#14 0x7fc6ba0e1082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) (BuildId: 0323ab4806bee6f846d9ad4bccfc29afdca49a58)
DEDUP_TOKEN: __interceptor_free--rpl_free--free_tree_node
previously allocated by thread T0 here:
#0 0x56103e23d469 in calloc /src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:75:3
#1 0x56103e2bcadd in mem_alloc_n /src/augeas/src/memory.c:66:23
#2 0x56103e27eecb in make_tree /src/augeas/src/augeas.c:1097:9
#3 0x56103e298368 in pathx_expand_tree /src/augeas/src/pathx.c:2998:26
#4 0x56103e281292 in tree_set /src/augeas/src/augeas.c:965:9
#5 0x56103e281292 in aug_set /src/augeas/src/augeas.c:989:14
#6 0x56103e28052f in aug_init /src/augeas/src/augeas.c:607:9
#7 0x56103e27c9f0 in LLVMFuzzerTestOneInput /src/augeas/augeas_aug_rm_fuzzer.cc:32:23
#8 0x56103e1314d0 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:614:13
#9 0x56103e130cf5 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:516:7
#10 0x56103e1324d5 in fuzzer::Fuzzer::MutateAndTestOne() /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:760:19
#11 0x56103e133265 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, std::__Fuzzer::allocator<fuzzer::SizedFile>>&) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:905:5
#12 0x56103e1220ab in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:914:6
#13 0x56103e14d482 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
#14 0x7fc6ba0e1082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) (BuildId: 0323ab4806bee6f846d9ad4bccfc29afdca49a58)
DEDUP_TOKEN: __interceptor_calloc--mem_alloc_n--make_tree
SUMMARY: AddressSanitizer: heap-use-after-free /src/augeas/src/augeas.c:661:5 in tree_unlink_raw
Shadow bytes around the buggy address:
0x506000147b80: fd fd fd fd fa fa fa fa fd fd fd fd fd fd fd fd
0x506000147c00: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa
0x506000147c80: fd fd fd fd fd fd fd fa fa fa fa fa fd fd fd fd
0x506000147d00: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fa
0x506000147d80: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa
=>0x506000147e00: fa fa fa fa fa fa fa fa fa fa fa fa fd[fd]fd fd
0x506000147e80: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fd
0x506000147f00: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa
0x506000147f80: fd fd fd fd fd fd fd fa fa fa fa fa fd fd fd fd
0x506000148000: fd fd fd fd fa fa fa fa fd fd fd fd fd fd fd fd
0x506000148080: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==11==ABORTING
MS: 1 ShuffleBytes-; base unit: cceaf8eed18b308397589ad7341a5a5127ce7b5c
0x2f,0x2f,0xa,0xa,0x2e,0x2e,
//\012\012..
artifact_prefix='augeas_aug_rm_fuzzer_'; Test unit written to augeas_aug_rm_fuzzer_crash-1d2f309e3dfeb731daa3b2517730aab159e35696
Base64: Ly8KCi4u
Hello, I found a UAF when running the following fuzz driver in OSS-Fuzz environment.
Here is the ASAN log: