DF-2229 / run.log
DF-2229 reproduction + fix validation: prop_array_iterator(NULL) via dm ioctl.
== PoC (df2229.c) ==
Builds a prop_dictionary { command="reload", version=[4,16,0], name="df2229dev",
flags=0 } WITHOUT a "cmd_data" key, sends it via NETBSD_DM_IOCTL
(_IOWR(0xfd,0,struct plistref)=0xc010fd00) to /dev/mapper/control. The dm
"reload" -> dm_table_load_ioctl at sys/dev/disk/dm/dm_ioctl.c:707-708:
cmd_array = prop_dictionary_get(dm_dict, DM_IOCTL_CMD_DATA); // NULL
iter = prop_array_iterator(cmd_array); // NULL deref
runs BEFORE the device-lookup check (line 711). prop_array_iterator()
(prop_array.c:538) derefs pa->pa_rwlock with NO prop_object_is_array() guard.
== BASELINE (unpatched #0 kernel, stock) ==
df2229: sending NETBSD_DM_IOCTL reload WITHOUT cmd_data
(ssh hung -> guest down; boot.log:)
Fatal trap 12: page fault while in kernel mode
cpuid = 4
fault virtual address = 0x40 <-- pa_rwlock offset from NULL pa
fault code = supervisor write data, page not present
Stopped at prop_array_iterator+0x1b: lock cmpxchgl %edx,0x40(%rdi)
db>
(reproduced on 2 independent fresh vm.sh reset with-src runs)
== FIXED (#1 kernel, fix.diff applied: prop_object_is_array() guard added to
prop_array_iterator / make_immutable / mutable / externalize, sha256
9fb1b67f...) ==
df2229: sending NETBSD_DM_IOCTL reload WITHOUT cmd_data
df2229: prop_dictionary_send_ioctl returned 2 (ENOENT -- guarded
prop_array_iterator returns NULL, then dm_dev_lookup(name) fails)
PATCHED_RC=0
--- guest up? ---
11:16AM up 25 secs, 0 users, load averages: 0.18, 0.05, 0.02
# NO PANIC. Guest healthy. Fix closes the NULL deref.