View Issue Details

IDProjectCategoryView StatusLast Update
0000481fileGeneralpublic2024-02-04 19:27
Reporterpromptfuzz Assigned Tochristos  
PrioritynormalSeveritycrashReproducibilityalways
Status resolvedResolutionfixed 
PlatformLinuxOSubuntuOS Version22.04
Product Version5.45 
Fixed in VersionHEAD 
Summary0000481: A heap-buffer-underflow in mkdbname (apprentice.c:3485:10)
DescriptionHi,
   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 ReproduceFirstly, 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
Tagsbug, filename

Activities

christos

2024-02-04 19:27

manager   ~0003998

Fixed, thanks!

Issue History

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