DragonFlyBSD Kernel Audit
DF-2229 / run.log
← back to finding ↓ download raw
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.