Details
-
Bug
-
Resolution: Unresolved
-
Major
-
None
-
None
Description
- Description
-
- Test environment
- ReactOS revision: `0.4.17-dev-694-g606b2e9`
- Commit: `606b2e96207ca98d43b2e1345bcf07b8990a2e05`
- Guest build text: `Build 20260823-0.4.17-dev-694-g606b2e9`
- VM: QEMU `11.1.0`, machine type `pc`
- Guest memory: 768 MiB
- Guest Additions: none installed
- ReactOS system volume: FAT32
- Additional test volume: crafted NTFS raw image
- Host: Windows
-
- What I was doing
I booted ReactOS in QEMU with a secondary crafted NTFS volume attached. The
volume contains a malformed MFT record 3 (`$Volume`) with an excessive USA
count. The test image preserves a valid NTFS boot sector and partition layout,
so ReactOS detects it as an NTFS volume and attempts to mount it.
-
- Steps to reproduce
For deterministic confirmation, use the attached diagnostic x86 ReactOS guest
and the attached test image:
1. Start QEMU with snapshot mode and attach the test image as a second disk:
```text
qemu-system-i386w.exe -m 768 -M pc -vga std -snapshot \
-hda reactos-usa-trap-guest-01.vhd \
-drive file=ntfs-usa-oobw-volume03-triggerable-01.vhd,format=raw,if=ide,index=1,media=disk \
-boot order=c -no-reboot -no-shutdown
```
2. Allow ReactOS to boot and enumerate/mount the secondary volume.
3. No `dir` command or other filesystem operation is required in the observed
run.
4. ReactOS reaches the diagnostic stop screen.
The reproducer image is raw and must be passed to QEMU with `format=raw`.
-
- Expected result
ReactOS should reject the malformed NTFS record safely and return an error. It
should not read or write outside the bounds of the MFT record or the input
buffer, and the system should remain running.
-
- Actual result
The NTFS driver reaches the original write in
`drivers/filesystems/ntfs/mft.c`, function
`FixupUpdateSequenceArray()`:
```c
*Block = *(USA++);
```
The diagnostic build reports:
```text
STOP: 0x4F4F4257 (0xB1D391FE, 0x00000000, 0x0000CCCC, 0xB1D38C00)
```
The diagnostic values show that `0xCCCC` was written to a target at offset
`0x5FE` from the MFT record base. The MFT record is `0x400` bytes long, so the
target is outside the record. This is an out-of-bounds write, not only an
out-of-bounds read.
Screenshot: `qemu-triggerable-03.png`.
-
- Why this happens
The function uses attacker-controlled record fields without validating their
bounds:
1. `UsaOffset` is added directly to `Record`.
2. `UsaCount - 1` is used directly as the loop count.
3. `Block` is advanced by `BytesPerSector` without a record-length check.
4. The replacement value is written without checking the destination range.
With `UsaCount = 4`, a 1024-byte record, and 512-byte sectors, the third
fixup target is `Record + 0x5FE`, beyond the end of the record.
-
- Debug information
The following debug output and evidence are attached:
- `qemu-triggerable-02.serial.log` — QEMU serial/debug output.
- `qemu-triggerable-03.png` — ReactOS diagnostic stop screen.
- `qemu-triggerable-01-result.md` — image correction and reproduction record.
The reproducer image is:
```text
ntfs-usa-oobw-volume03-triggerable-01.vhd
SHA256: 3F745195B76B38929911292B16DFC194C0904D6015B2AEE48C45095FC2C49E1C
```
-
- Clean nightly observation
The same volume was tested against the uninstrumented official nightly ISO
`reactos-bootcd-0.4.17-dev-694-g606b2e9-x86-msvc-win-dbg.iso`. That run did
not show a natural BSOD. The clean build has no diagnostic bugcheck, and an
out-of-bounds kernel write does not necessarily crash immediately. The
diagnostic stop screen above is intentionally generated after the original
write in the diagnostic build to make the write boundary observable.
-
- Impact
A crafted NTFS volume can cause kernel memory corruption when ReactOS mounts
it. The demonstrated impact is a memory-safety violation and potential kernel
crash/denial of service.