View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0000481 | file | General | public | 2023-10-07 08:31 | 2024-02-04 19:27 |
Reporter | promptfuzz | Assigned To | christos | ||
Priority | normal | Severity | crash | Reproducibility | always |
Status | resolved | Resolution | fixed | ||
Platform | Linux | OS | ubuntu | OS Version | 22.04 |
Product Version | 5.45 | ||||
Fixed in Version | HEAD | ||||
Summary | 0000481: A heap-buffer-underflow in mkdbname (apprentice.c:3485:10) | ||||
Description | Hi, I found a heap buffer underflow bug in function mkdbname(), where it is located at src/apprentice.c:3485:10 in version 5.45. ---------- ==1794476==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000000f at pc 0x55cb80a2b659 bp 0x7ffec566cdf0 sp 0x7ffec566cde8 READ of size 1 at 0x60200000000f thread T0 #0 0x55cb80a2b658 in mkdbname /data/home/loydlv/vbd/llm_fuzz/output/build/libmagic/src/libmagic/build/src/../../src/apprentice.c:3485:10 0000001 0x55cb80a06956 in apprentice_map /data/home/loydlv/vbd/llm_fuzz/output/build/libmagic/src/libmagic/build/src/../../src/apprentice.c:3289:11 0000002 0x55cb80a06956 in apprentice_1 /data/home/loydlv/vbd/llm_fuzz/output/build/libmagic/src/libmagic/build/src/../../src/apprentice.c:496:8 0000003 0x55cb80a06956 in file_apprentice /data/home/loydlv/vbd/llm_fuzz/output/build/libmagic/src/libmagic/build/src/../../src/apprentice.c:772:13 0000004 0x55cb809ff997 in main /data/home/loydlv/test_dir/crash/libmagic/crash1/poc.cc:17:9 0000005 0x7f7ffecc9d84 in __libc_start_main ../csu/libc-start.c:302:16 0000006 0x55cb8093e5dd in _start (/data/home/loydlv/test_dir/crash/libmagic/crash1/poc.out+0xd05dd) ----------- This bug can be triggered by passing a magic file name with length shorter than 4 to the magic_load(struct magic_set *ms, const char *magicfile) public API. For example, here is an poc file. ``` // poc.cc #include <magic.h> int main() { magic_t magic = magic_open(MAGIC_NONE); if (magic == NULL) { return -1; } if (magic_load(magic, "gc") == -1) { magic_close(magic); return -1; } magic_close(magic); return 0; } ``` The root cause of the bug is the incomplete logic in `mkdbname()` to make the .mgc suffix. See the below code, the `ext=".mgc"` and `fn="gc"`, for the poc.cc. Let assume `fn` point to 0x602000000010. ``` 3478 /* Look for .mgc */ 3479 for (p = ext + sizeof(ext) - 1; p >= ext && q >= fn; p--, q--) 3480 if (*p != *q) 3481 break; ``` Because `ext` is longer than `fn`, when `q` is decreased to `0x60200000000f `, where `q` does not satisify `q>=fn`, the loop finished. However, the code below does not check whether `q` is still valid (line 3483), and the access of `q` (line 3485) cause an heap buffer underflow bug. ``` 3483 /* Did not find .mgc, restore q */ 3484 if (p >= ext) 3485 while (*q). // <---- heap buffer underflow 3486 q++; ``` As magic_load() is a public API, although the community has already provided a magic file named "magic.mgc" and most time it does not cause serious impacts, it is necessary to fix the bug to avoid the undefined behaviors or further security issues. | ||||
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 | ||||
Tags | bug, filename | ||||
Date Modified | Username | Field | Change |
---|---|---|---|
2023-10-07 08:31 | promptfuzz | New Issue | |
2023-10-07 08:31 | promptfuzz | Tag Attached: bug | |
2023-10-07 08:31 | promptfuzz | Tag Attached: filename | |
2024-02-04 19:27 | christos | Assigned To | => christos |
2024-02-04 19:27 | christos | Status | new => assigned |
2024-02-04 19:27 | christos | Status | assigned => resolved |
2024-02-04 19:27 | christos | Resolution | open => fixed |
2024-02-04 19:27 | christos | Fixed in Version | => HEAD |
2024-02-04 19:27 | christos | Note Added: 0003998 |