DragonFlyBSD Kernel Audit
DF-2622 / console_excerpts.txt
← back to finding ↓ download raw
DF-2622 console evidence (verbatim from the QEMU serial console + ssh runs)

=== [A] STOCK kernel #0 -- run_2622.sh (root, direct mount(2) via mnt2622) ===

$ ./mnt2622 '@' /mnt/h2x      ->  mount FAILED errno=2
$ ./mnt2622 ''  /mnt/h2x      ->  mount FAILED errno=2

console:
hammer2_mount: devstr="@"
hammer2_mount: device="" label="DATA" rdonly=0
hammer2_mount: PFS label "DATA" not found
hammer2_mount: devstr=""
hammer2_mount: device="" label="DATA" rdonly=0
hammer2_mount: PFS label "DATA" not found

# For volume="@": strchr finds '@' at devstr[0], label[1]==0 -> *label='\0'
# -> devstr becomes "" and label==devstr -> slice=label[-1]=devstr[-1]
# READS ONE BYTE BELOW the devstr[MNAMELEN] stack array (vfsops.c:1020).
# For volume="": label==NULL -> label=devstr+0 -> same OOB read.
# The byte decides the printed label: 'a'->BOOT, 'd'->ROOT, else DATA
# (~1.6-bit oracle of the stack byte printed to the console).

=== [B] INSTRUMENTED kernel #1 -- same two triggers ===

DF2622: label=0xfffff80116c0dda0 devstr=0xfffff80116c0dda0 devstr="" label==devstr=1 devstr[-1]=00 (OUT-OF-BOUNDS byte below devstr[])
hammer2_mount: device="" label="DATA" rdonly=0

DF2622: label=0xfffff80116c0dda0 devstr=0xfffff80116c0dda0 devstr="" label==devstr=1 devstr[-1]=ff (OUT-OF-BOUNDS byte below devstr[])
hammer2_mount: device="" label="DATA" rdonly=0

# NOTE: the byte below devstr[] was 0x00 in the first call and 0xff in the
# second -- it is live stack garbage below the array, varying with the
# call's stack history.  Neither value is 'a'/'d' so both prints chose
# DATA, but had the stale byte been 0x61/0x64 the console label (and the
# PFS the mount then searches for) would flip to BOOT/ROOT.

# In-bounds reference captures from the same hooks:
DF2622: label=0xffffffff817ad5af devstr=0xffffffff817ad5a8 devstr="vbd0s1d" label==devstr=0 devstr[-1]=ff (in-bounds last char of device string)
	# boot root mount: label=devstr+7 -> label[-1]='d' -> label=ROOT (correct)
DF2622: label=0xfffff80118422da8 devstr=0xfffff80118422da0 devstr="/dev/vn0" label==devstr=0 devstr[-1]=00 (in-bounds last char of device string)
	# mount "/dev/vn0@": label=devstr+8 -> label[-1]='0' -> DATA (correct)

=== [C] FIX kernel #2 -- same triggers ===

hammer2_mount: devstr="@"
hammer2_mount: device="" label="DATA" rdonly=0
hammer2_mount: devstr=""
hammer2_mount: device="" label="DATA" rdonly=0

# Identical user-visible behavior (default label DATA, mount still fails
# ENOENT because the device string is empty), but slice is now assigned
# 0 when label==devstr -- devstr[-1] is never dereferenced.