DF-0598 / run.1000.log
+ ./leak 1000
[harness] vclist head-order: carol@c bob@b alice@a
[harness] 1000 failing lookups (username 'nobody@nowhere' matches none)
=== VULNERABLE smb_sm_lookupint (sys/netproto/smb/smb_conn.c:123-180) ===
call #0: rc=1 (nonzero => lookup FAILED), but *vcpp=alice@a (NOT NULL!)
after 1000 failed lookups:
usecount[alice@a] = 1001 (baseline 1, delta +1000)
usecount[bob@b] = 1 (baseline 1, delta +0)
usecount[carol@c] = 1 (baseline 1, delta +0)
TOTAL leaked refs across all VCs = 1000 (expected 1000)
every miss returned *vcpp=alice@a (WRONG VC: caller gets a ref to a VC
that does NOT match the lookup, and never releases it)
=== FIXED smb_sm_lookupint (fix.diff applied) ===
call #0: rc=1 (nonzero => lookup FAILED), *vcpp=(null) — correct: miss leaves caller's NULL intact
after 1000 failed lookups:
usecount[alice@a] = 1 (baseline 1, delta +0)
usecount[bob@b] = 1 (baseline 1, delta +0)
usecount[carol@c] = 1 (baseline 1, delta +0)
TOTAL leaked refs across all VCs = 0 (expected 0)
every miss returned *vcpp=(null) — caller cannot confuse a NULL VC for a real one
=== RESULT ===
REPRODUCED: vulnerable lookupint leaked 1000 VC ref(s) across 1000 miss(es);
FIXED: patched lookupint leaked 0 ref(s) across 1000 miss(es).
The stale `vcp` post-loop in sys/netproto/smb/smb_conn.c:175-178 is
the root cause; fix.diff closes it.
RUN_EXIT=0