⬢ DragonFlyBSD Kernel Audit
DF-5739 / fix_run.log
← back to finding ↓ download raw
DF-5739 fix validation — patched module (fix.diff: exactly-once
atomic teardown guard + callout_drain/terminate), same race stress.

PASS 1 (100k arm / 100k discon / 50k frag rounds):
  $ sysctl hw.hlh_race_arm=5 && sleep 3 && sysctl hw.hlh_state=1   # sanity ok
  $ (sysctl hw.hlh_race_discon=100000 &); (sysctl hw.hlh_race_frag=50000 &); sleep 1
  $ sysctl hw.hlh_race_arm=100000
  PASS1_ARM_DONE
  $ dmesg | grep -ac "already freed"
  0
  guest: up
  -> the double-kfree panic did NOT recur.

PASS 2 (150k arm / 150k discon / 100k frag rounds):
  $ (sysctl hw.hlh_race_discon=150000 &); (sysctl hw.hlh_race_frag=100000 &); sleep 1
  $ sysctl hw.hlh_race_arm=150000
  ... guest died during the pass; serial console (fix_panic_patched.txt):

  hcih0: dropped incomplete ACL packet        (rx-path prints, concurrent)
  ...
  panic with 1 spinlocks held
  panic: Bad link elm 0xfffff8011954ee28 next->prev != elm
  cpuid = 0
  Trace beginning at frame 0xfffff8008d1f8a50
  lwkt_spin_getport() at lwkt_spin_getport+0x134   (mis-symbolized module frames)
  lwkt_spin_getport() at lwkt_spin_getport+0x134
  netmsg_service_loop() at netmsg_service_loop+0xaf
  Debugger("panic")

  -> QUEUEDEBUG list-consistency panic (sys/sys/queue.h:392/525): the
     still-unserialized TAILQ_INSERT_HEAD in hci_link_alloc() (arm
     thread) raced TAILQ_REMOVE in hci_link_free() (netisr/softclock)
     on unit->hci_links — a SIBLING manifestation of the same missing
     serialization, not the patched double-kfree path.

CONCLUSION: fix is PARTIAL.
  - the demonstrated primitive (double kfree from two hci_link_free()
    contexts) did not recur under the patched build;
  - the same stress still corrupts the system through other
    unsynchronized entry points (link-list mutation);
  - full remediation = serialize the netbt link lifecycle + refcount
    handle-lookup users (upstream design change).
fix_status: inconclusive