[File] Security report: uninitialized read in libmagic conditional parser (check_cond / last_cond)

jiami3us at icloud.com jiami3us at icloud.com
Wed May 13 08:29:44 EDT 2026


Hello,

We found an uninitialized memory use in libmagic's source-text magic database parser. The issue is in the conditional continuation parser for `if` / `elif` / `else`, not in ordinary target-file classification.

We traced the affected range to commit `65c81154fcf085c1560577f6dc69a6b840336844` from 2007-01-18, which introduced the optional conditional field. Based on the tags we checked, this specific issue affects `FILE4_20` and later releases through `FILE5_47`, as well as current GitHub `master` as of 2026-05-13; `FILE4_19` is not affected by this specific issue.

The root cause is that `ms->c.li` is allocated with `malloc()`:

```c
/* src/apprentice.c */
len = (ms->c.len = 10) * sizeof(*ms->c.li);
if ((ms->c.li = CAST(struct level_info *, malloc(len))) == NULL)
    goto free;
```

The relevant state is `last_cond`:

```c
/* src/file.h */
struct level_info {
    int32_t off;
    int got_match;
#ifdef ENABLE_CONDITIONALS
    int last_match;
    int last_cond;  /* used for error checking by parse() */
#endif
};
```

`parse()` only initializes the current continuation level when the level is 0 or deeper than the previous line:

```c
/* src/apprentice.c */
if (cont_level == 0 || cont_level > last_cont_level)
    if (file_check_mem(ms, cont_level) == -1)
        return -1;
last_cont_level = cont_level;
```

`file_check_mem()` initializes only the single level passed to it:

```c
/* src/funcs.c */
ms->c.li[level].got_match = 0;
#ifdef ENABLE_CONDITIONALS
ms->c.li[level].last_match = 0;
ms->c.li[level].last_cond = COND_NONE;
#endif
```

A source magic database can use continuation levels `0 -> 2 -> 1`:

```text
0    string  x  ROOT
>>0  string  x  LEVEL2
>0   elif    string x ELIF_ACCEPTED
```

This initializes `li[0]` and `li[2]`, but not `li[1]`. The third line then reaches `check_cond()`, which reads `li[1].last_cond`:

```c
/* src/apprentice.c */
last_cond = ms->c.li[cont_level].last_cond;
```

That uninitialized value controls whether `if` / `elif` / `else` syntax is accepted.

We verified the following effects with a clean non-sanitized upstream build:

- an invalid standalone `elif` rule can be accepted and compiled into a persistent `.mgc` file when stale heap contents make `last_cond` look like `COND_IF` or `COND_ELIF`;
- a valid `if` rule can be rejected depending on stale heap contents;
- applying the included `fix.patch` makes invalid `elif` examples consistently rejected and valid `if` examples consistently accepted.

The attached package contains a Docker-based PoC, a proposed fix patch, and a short report with reproduction instructions. The PoC builds clean upstream libmagic, runs the unpatched case, applies `fix.patch`, rebuilds, and runs the patched case. It does not depend on AFL, DMSAN, MSan, Valgrind, or local absolute paths. The report also includes short DMSAN/MSan/Memcheck evidence pointing to the same parser state and allocation origin.

We believe the relevant attack surface is parsing, validating, compiling, or loading source-text magic databases from untrusted or semi-trusted sources. We are not claiming that ordinary classification of attacker-controlled files with a trusted system `.mgc` database reaches this bug.

This issue was found by DMSAN, our uninitialized-memory detection tool, during fuzzing. Could you please review the report and let us know whether you consider this a security issue? If so, would you prefer to request a CVE from MITRE, or would you like us to file the request on your behalf with attribution to the project? We would like to include confirmed findings in the evaluation section of our DMSAN paper.

The attached files are:

- `UPSTREAM_REPORT.md`
- `README.md`
- `Dockerfile`
- `run_docker_demo.sh`
- `heap_control_poc.c`
- `fix.patch`

Thank you,
DMSAN (Differential Memory Sanitizer)

-------------- next part --------------
A non-text attachment was scrubbed...
Name: libmagic-source-parser-uum-poc.tar.gz
Type: application/x-gzip
Size: 8287 bytes
Desc: not available
URL: <http://mailman.astron.com/pipermail/file/attachments/20260513/bcb39671/attachment-0001.bin>


More information about the File mailing list