| Title | nasm NASM version 2.17rc0 compiled on Jul 20 2025 and the newest master (888d9ab) Memory Corruption |
|---|
| Description | # NASM Use-After-Free Vulnerability in do_directive Function
## Vulnerability Summary
A critical use-after-free vulnerability has been discovered in the NASM (Netwide Assembler) preprocessor module. The vulnerability occurs in the `do_directive` function within `preproc.c` at line 3971, where the program attempts to access previously freed memory, leading to potential memory corruption and program crash.
## Technical Details
- **Vulnerability Type**: Use-After-Free
- **Affected Function**: `do_directive`
- **Source File**: `preproc.c`
- **Line Number**: 3971
- **Signal**: SIGABRT (6)
## Vulnerability Mechanism and Root Cause
This use-after-free vulnerability is caused by improper memory lifecycle management in the preprocessor directive processing logic. The root issue lies in the `do_directive` function where memory allocated for preprocessor data structures is freed prematurely and then accessed again.
The vulnerability occurs when:
1. Memory is allocated in `do_directive` at line 4807 using `nasm_zalloc` for directive-related data structures
2. The memory gets freed in `pp_tokline` at line 7989 during token processing
3. Later, `do_directive` at line 3971 attempts to read 4 bytes from the freed memory region (0x610000002260)
This creates a classic use-after-free condition where the program accesses memory that has been returned to the heap allocator, potentially containing stale or overwritten data. The freed memory region is 192 bytes in size, and the invalid access occurs 32 bytes into this freed region.
## AddressSanitizer Report
```
=================================================================
==427970==ERROR: AddressSanitizer: heap-use-after-free on address 0x610000002260 at pc 0x55de6b14dca7 bp 0x7ffc3d4b2030 sp 0x7ffc3d4b2028
READ of size 4 at 0x610000002260 thread T0
#0 0x55de6b14dca6 in do_directive /workspace/benchmark/program/nasm-888d9ab-Nov5-2024/asm/preproc.c:3971:48
#1 0x55de6b132692 in pp_tokline /workspace/benchmark/program/nasm-888d9ab-Nov5-2024/asm/preproc.c:8069:13
#2 0x55de6b132692 in pp_getline /workspace/benchmark/program/nasm-888d9ab-Nov5-2024/asm/preproc.c:8133:17
#3 0x55de6b08b0b9 in assemble_file /workspace/benchmark/program/nasm-888d9ab-Nov5-2024/asm/nasm.c:1734:24
#4 0x55de6b08b0b9 in main /workspace/benchmark/program/nasm-888d9ab-Nov5-2024/asm/nasm.c:716:9
#5 0x7efc80589d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#6 0x7efc80589e3f in __libc_start_main csu/../csu/libc-start.c:392:3
#7 0x55de6afba7b4 in _start (/workspace/benchmark/tmp/old-fuzzdir/fz-nasm/fz-nasm/nasm+0x1ed7b4) (BuildId: 2a14aa05a80be476)
0x610000002260 is located 32 bytes inside of 192-byte region [0x610000002240,0x610000002300)
freed by thread T0 here:
#0 0x55de6b052546 in free (/workspace/benchmark/tmp/old-fuzzdir/fz-nasm/fz-nasm/nasm+0x285546) (BuildId: 2a14aa05a80be476)
#1 0x55de6b13151d in pp_tokline /workspace/benchmark/program/nasm-888d9ab-Nov5-2024/asm/preproc.c:7989:21
#2 0x55de6b13151d in pp_getline /workspace/benchmark/program/nasm-888d9ab-Nov5-2024/asm/preproc.c:8133:17
#3 0x55de6b08b0b9 in assemble_file /workspace/benchmark/program/nasm-888d9ab-Nov5-2024/asm/nasm.c:1734:24
#4 0x55de6b08b0b9 in main /workspace/benchmark/program/nasm-888d9ab-Nov5-2024/asm/nasm.c:716:9
#5 0x7efc80589d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
previously allocated by thread T0 here:
#0 0x55de6b0529d8 in calloc (/workspace/benchmark/tmp/old-fuzzdir/fz-nasm/fz-nasm/nasm+0x2859d8) (BuildId: 2a14aa05a80be476)
#1 0x55de6b09b902 in nasm_calloc /workspace/benchmark/program/nasm-888d9ab-Nov5-2024/nasmlib/alloc.c:72:9
#2 0x55de6b09b902 in nasm_zalloc /workspace/benchmark/program/nasm-888d9ab-Nov5-2024/nasmlib/alloc.c:87:12
#3 0x55de6b145d33 in do_directive /workspace/benchmark/program/nasm-888d9ab-Nov5-2024/asm/preproc.c:4807:9
#4 0x55de6b132692 in pp_tokline /workspace/benchmark/program/nasm-888d9ab-Nov5-2024/asm/preproc.c:8069:13
#5 0x55de6b132692 in pp_getline /workspace/benchmark/program/nasm-888d9ab-Nov5-2024/asm/preproc.c:8133:17
#6 0x55de6b08b0b9 in assemble_file /workspace/benchmark/program/nasm-888d9ab-Nov5-2024/asm/nasm.c:1734:24
#7 0x55de6b08b0b9 in main /workspace/benchmark/program/nasm-888d9ab-Nov5-2024/asm/nasm.c:716:9
#8 0x7efc80589d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
SUMMARY: AddressSanitizer: heap-use-after-free /workspace/benchmark/program/nasm-888d9ab-Nov5-2024/asm/preproc.c:3971:48 in do_directive
```
## Proof of Concept
The vulnerability can be triggered by processing the malformed assembly file provided as `POC_nasm_use_after_free_do_directive`. This file contains specific preprocessor directives that cause the use-after-free condition.
**POC Download**: [Google Drive Link - POC_nasm_use_after_free_do_directive](https://drive.google.com/file/d/11vEV1vMHXO4BrDGhvWAMm0Qo1woiUwVV/view?usp=drive_link)
## Reproduction Steps
1. Compile NASM with AddressSanitizer enabled
2. Execute: `nasm -f dbg POC_nasm_use_after_free_do_directive`
3. The program will crash with a heap-use-after-free error
## Affected Versions
NASM version 2.17rc0 compiled on Jul 20 2025 and the newest master (888d9ab)
**Credit**
- Xudong Cao (UCAS)
- Yuqing Zhang (UCAS, Zhongguancun Laboratory) |
|---|
| Source | ⚠️ https://bugzilla.nasm.us/show_bug.cgi?id=3392933 |
|---|
| User | xdcao (UID 88377) |
|---|
| Submission | 07/26/2025 09:10 (9 months ago) |
|---|
| Moderation | 08/10/2025 17:56 (15 days later) |
|---|
| Status | Accepted |
|---|
| VulDB entry | 319376 [NASM Netwide Assember 2.17rc0 preproc.c do_directive use after free] |
|---|
| Points | 17 |
|---|