⬢ DragonFlyBSD Kernel Audit
DF-5674 / run.3.log
← back to finding ↓ download raw
# run.3.log — probe (unlocked-free counter) + control + fix validation
# probe library: /tmp/proprop = /usr/src/sys/libprop with a pthread_mutex_trylock
# probe compiled into _prop_dict_keysym_free (see proprop_dictionary.c):
# it counts every keysym free that starts while _prop_dict_keysym_tree_mutex
# is NOT held by the freeing thread.

root@dfbsd:/tmp # cc -O2 -DWITH_PROBE -o race_probe race_probe.c /tmp/proprop/libprop_probe.so -lpthread -Wl,-rpath,/tmp/proprop
root@dfbsd:/tmp # cc -O2 -o race_fix race_attr.c /tmp/propfix/libprop_fix.so -lpthread -Wl,-rpath,/tmp/propfix
root@dfbsd:/tmp # for i in 1 2 3; do ./race_probe; echo "--- probe run$i exit=$?"; done
SIGSEGV in _prop_rb_tree_remove_node addr=0x8
SIGSEGV in _prop_rb_tree_insert_node addr=0x8
DF5674_unlocked_frees=1145
--- probe run1 exit=139
--- probe run2 exit=139
SIGSEGV in prop_object_iterator_release addr=0x8
DF5674_unlocked_frees=88
--- probe run3 exit=139
SIGSEGV in _prop_rb_tree_remove_node addr=0x0
DF5674_unlocked_frees=350

# (run interleaving above: each run prints its crash line(s) then the counter.)
# Note run2: the victim is _prop_rb_tree_insert_node — the MUTEX-PROTECTED
# inserter from _prop_dict_keysym_alloc walking a tree torn by the UNLOCKED
# remover. DF5674_unlocked_frees 88..1145 per short run = direct proof the
# frees execute without the tree mutex.

# ---- control: identical workload, removes disabled (all tree ops locked) ----
root@dfbsd:/tmp # ./race_attr noremove   # x3
survived
exit=0
survived
exit=0
survived
exit=0

# ---- fix validation: libprop built from /tmp/propfix (fix.diff applied) ----
root@dfbsd:/tmp # for i in 1..10: ./race_fix > fixrun.$i.log
(see fixrun.*.log summary in this pack; 10/10 runs print "survived" / exit=0)