DragonFlyBSD Kernel Audit
DF-2804 / run.sh
← back to finding ↓ download raw
#!/bin/sh
# DF-2804: permanent kernel memory leak of queued-but-undelivered udev event
# dictionaries when the last reader closes without draining
# (udev_dev_close -> udev_clean_events_locked objcache_put WITHOUT
#  prop_object_release(ev->ev.ev_dict)).
#
# Runs as ROOT inside the DragonFly guest (after ./build.sh).
sample() {
	printf '== sample: %s ==\n' "$1"
	vmstat -m | egrep -w 'propdict|prop_dictionary|propnmbr|propstng|prop_string|propkeysym|udev'
}

cd /tmp
sample 'S0 baseline'

# ---- cycle 1: stalled reader + unpriv churn, then close-without-read ----
su -m maxx -c '/tmp/churn -n 30000' > /tmp/df2804_c1.log 2>&1 &
C1=$!
/tmp/harness stall 25 > /tmp/df2804_h1.log 2>&1 &
H1=$!
wait $C1; cat /tmp/df2804_c1.log
wait $H1; cat /tmp/df2804_h1.log
sample 'S1 after close-without-read (cycle 1)'
sleep 10
sample 'S2 after close + 10s idle (leak must persist)'

# ---- cycle 2: same again -> leak accumulates monotonically ----
su -m maxx -c '/tmp/churn -n 30000' > /tmp/df2804_c2.log 2>&1 &
C2=$!
/tmp/harness stall 25 > /tmp/df2804_h2.log 2>&1 &
H2=$!
wait $C2; cat /tmp/df2804_c2.log
wait $H2; cat /tmp/df2804_h2.log
sleep 5
sample 'S3 after close-without-read (cycle 2) - ~2x S1 delta expected'

# ---- control: same churn with an ACTIVE reader (drains) -> no growth ----
su -m maxx -c '/tmp/churn -n 30000' > /tmp/df2804_c3.log 2>&1 &
C3=$!
/tmp/harness read 25 > /tmp/df2804_h3.log 2>&1 &
H3=$!
wait $C3; cat /tmp/df2804_c3.log
wait $H3; tail -2 /tmp/df2804_h3.log
sleep 5
sample 'S4 after active-drain control (should stay ~= S3)'
echo DONE