View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0000483 | file | General | public | 2023-10-08 08:37 | 2023-12-20 21:28 |
Reporter | promptfuzz | Assigned To | christos | ||
Priority | high | Severity | crash | Reproducibility | always |
Status | feedback | Resolution | open | ||
Platform | Linux | OS | Ubuntu | OS Version | 22.04 |
Product Version | 5.45 | ||||
Summary | 0000483: Buffer-overflow in check_buffer() (apprentice.c:3358:6) | ||||
Description | Hi, I found a heap buffer overflow bug in function check_buffer() (at file apprentice.c:3358:6), triggered via the public API : file_public int magic_load_buffers(struct magic_set *ms, void **bufs, size_t *sizes, size_t nbufs). This bug can be cause an out-of-bound read issue via craft magic files. A poc file is: ``` // poc.cc extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { magic_t magic = magic_open(MAGIC_NONE); if (magic == NULL) { return -1; } // Load buffers void* buffers[] = { (void*)data }; size_t buffer_sizes[] = { size }; if (magic_load_buffers(magic, buffers, buffer_sizes, 1) == -1) { // Error handling } magic_close(magic); return 0; } ``` In the poc file, magic_load_buffers() will finally call `check_buffer(ms, map, "buffer")`, where map->p = data. In the code below, if the data is passed with length of 1 byte, the data with 1 byte lengh is cast to a type of 2 byte lengh (line 3357) first, and then it is accessed with 2 bytes in line 3358 where an one byte out-of-read happened. ``` check_buffer(struct magic_set *ms, struct magic_map *map, const char *dbname) { uint32_t *ptr; uint32_t entries, nentries; uint32_t version; int i, needsbyteswap; 3357 ptr = CAST(uint32_t *, map->p); 3358. if (*ptr != MAGICNO) { ``` As magic_load_buffers() is a public API, if the buffer passed in could be controlled by remote attackers, it might cause deny-of-services or information leaks. I strongly suggest you add a buffer length check in check_buffer() to avoid the potential issue. Thanks. | ||||
Steps To Reproduce | Firstly, compile the libmagic with ASAN: ``` export CC=clang export CXX=clang++ SANITIZER_FLAGS="-O0 -fsanitize=address,undefined -fsanitize-address-use-after-scope -g " export CFLAGS="${CFLAGS:-} $SANITIZER_FLAGS" export CXXFLAGS="${CXXFLAGS:-} $SANITIZER_FLAGS -stdlib=libc++" cd $SRC/libmagic rm -rf build mkdir -p build autoreconf -i cd build ../configure --enable-static --enable-fsect-man5 --disable-libseccomp --disable-xzlib --disable-bzlib --disable-zlib make V=1 all ``` Then, compile the poc program: clang++ -fsanitize=address -g -O0 -I/libmagic/include poc.cc -o poc.out /libmagic/lib/libmagic.a Just run `./poc.out` is enough to reproduce this issue. | ||||
Additional Information | ==767084==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000090 at pc 0x5555557b502c bp 0x7fffffffcc40 sp 0x7fffffffcc38 READ of size 4 at 0x602000000090 thread T0 [Detaching after fork from child process 767104] #0 0x5555557b502b in check_buffer /libmagic/build/src/../../src/apprentice.c:3358:6 0000001 0x55555578bef8 in apprentice_buf /ibmagic/build/src/../../src/apprentice.c:3262:6 0000002 0x55555578bef8 in buffer_apprentice /libmagic/build/src/../../src/apprentice.c:713:9 0000003 0x5555557870d7 in LLVMFuzzerTestOneInput /poc.cc:44:9 | ||||
Tags | bug | ||||
Date Modified | Username | Field | Change |
---|---|---|---|
2023-10-08 08:37 | promptfuzz | New Issue | |
2023-10-08 08:37 | promptfuzz | Tag Attached: bug | |
2023-12-20 21:28 | christos | Assigned To | => christos |
2023-12-20 21:28 | christos | Status | new => assigned |
2023-12-20 21:28 | christos | Status | assigned => feedback |
2023-12-20 21:28 | christos | Note Added: 0003988 |