DF-2624 / console_excerpts.txt
DF-2624 console evidence (verbatim from the QEMU serial console)
=== [A] STOCK kernel #0 -- RO mount of craft2624.img (poison PFS "LOCAL"
with filename array + blockset bytes all 0x50, inode block relocated
to the tail of a 64KB window) ===
hammer2_mount: devstr="/dev/vn0@testvol"
hammer2_mount: device="/dev/vn0" label="testvol" rdonly=1
hammer2_ondisk: "/dev/vn0" zone=0 id=0 offset=0x0000000000000000 size=0x0000000004000000
hammer2_mount: hmp=0xfffff801192e4000 pmp=0xfffff8011872d000
# Mount SUCCEEDS: hammer2_update_pmps() (vfsops.c:1552-1571) pfsallocs
# EVERY PFS under the sroot, so pfsalloc() ran kstrdup() on the poison
# filename with no NUL anywhere in [0x100,0x400) of the inode block at
# the DIO window tail -> strlen ran off the end of the 64KB buffer.
# Silent on stock (adjacent page mapped, NUL found 4 bytes past the
# buffer). hammer2 pfs-list shows the poison PFS (label column reads
# the on-disk name via meta.name_len=5):
MASTER cd630e99-a334-11f1-a070-010000000000 PPPPP
=== [B] INSTRUMENTED kernel #1 -- same mount, adjacent page UNMAPPED:
the kstrdup's strlen faults past the DIO buffer ===
Fatal trap 12: page fault while in kernel mode
cpuid = 3; lapic id = 3
fault virtual address = 0xfffff80055af6000
fault code = supervisor read data, page not present
...
panic: page fault
...
strlen() at strlen+0x14
hammer2_pfsalloc() at hammer2_pfsalloc+0x157
boot() called on cpu#3
# Fault VA is page-granular (end of the 64KB DIO buffer that holds the
# poison inode block). The instrumentation only ADDED a report AFTER
# the kstrdup returns -- the faulting strlen is the stock kstrdup at
# vfsops.c:495, so this panic is a stock-code behavior (memory-layout
# dependent: silent overread when the adjacent page is mapped, panic
# when it is not).
=== [C] INSTRUMENTED kernel #1 -- adjacent page mapped (retry) ===
DF2624: pfsalloc filename has NO NUL in 256-byte array; kstrdup result len=772 (516 bytes past array)
tail bytes: 50 50 50 ... 50
# 772 = 256 (filename array) + 512 (inode blockset area at
# [0x200,0x400)) + 4 bytes read PAST THE END OF THE 64KB DIO BUFFER
# (the inode block sits at window offset 0xFC00, so byte 768 of the
# walk is the first byte past the buffer). Those 4 adjacent-kernel-
# memory bytes (plus the NUL that stopped the walk) were copied into
# pmp->pfs_names[0] of the poison pmp. (The hexdump window printed
# only array+96 bytes, all 0x50 filler; the past-buffer bytes are
# result[768..771].)
=== [D] FIX kernel #2 -- same image, mounted 3 times ===
hammer2_pfsalloc: PFS filename not NUL-terminated (truncated to 256)
hammer2_pfsalloc: PFS filename not NUL-terminated (truncated to 256)
hammer2_pfsalloc: PFS filename not NUL-terminated (truncated to 256)
# 3/3 mounts succeed, NO panic, warning fires each time; pfs-list
# unchanged (PPPPP), testvol mount unaffected.