⬢ DragonFlyBSD Kernel Audit
DF-2834 / run.fixed.log
← back to finding ↓ download raw
=== FIXED KERNEL (fix.diff applied in guest scratch /usr/src, built via
=== make nativekernel KERNCONF=X86_64_GENERIC, 6.1 min, installed, rebooted)
uname -v: DragonFly 6.5-DEVELOPMENT #1: Tue Oct 20 11:55:22 UTC 2026  root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC
sysctl vm.max_vkernel_vmspaces: 64        <- new tunable present
sysctl vm.vkernel_enable: 0 -> 1

=== [A] unpriv create loop hits the cap cleanly ===
(command: /tmp/vmsp_grow 100000 1000 -u   [run_root; binary self-drops to uid 65534])
# uid=65534 count=100000 sample_every=1000 base_id=0x10000000
# ITER WIRE KVM_FREE FREE_COUNT ELAPSED_MS
0 142648 8791374426112 849671 0
FAILED iter=64 rc=-1 errno=59 (Too many references: can't splice)
1 142648 8791374426112 849671 1
GROW_EXIT=2
wire_after=142706
    -> allocation stops at 64 live vmspaces with a CLEAN error return
       (ETOOMANYREFS); wire count stays at baseline; no runaway.

=== [B] cap arithmetic: destroy frees a slot ===
(command: /tmp/vmsp_cap as unpriv uid 1001)
uid=1001
create #65 -> rc=-1 errno=59 (Too many references: can't splice)  [cap hit]
destroy(id=0x20000000) -> rc=0 errno=0
create after destroy     -> rc=0 errno=0 (OK)  [want 0: slot freed]

=== [C] legitimate usage unchanged: root raises the cap ===
vm.max_vkernel_vmspaces: 64 -> 100000
(command: /tmp/vmsp_grow 5000 1000 -u)
# uid=65534 count=5000 sample_every=1000 base_id=0x10000000
# ITER WIRE KVM_FREE FREE_COUNT ELAPSED_MS
0 142762 8791374426112 849816 0
1000 144565 8791363940352 847825 97
2000 147155 8791355551744 845234 161
3000 149789 8791345065984 842600 209
4000 151589 8791334580224 840800 266
5000 154331 8791324094464 838058 313
# DONE created=5000 uid=65534 elapsed=313ms -- exiting, vkernel_exit must now reclaim all of it
GROW_EXIT=0
vm.max_vkernel_vmspaces: 100000 -> 64
wire=144196
    -> with the operator-set cap, an unpriv process creates 5000 vmspaces
       successfully; everything reclaimed at exit (wire back ~baseline).

=== [D] cap is per-process: two concurrent fillers ===
(command: /tmp/vmsp_cap & /tmp/vmsp_cap & wait)
uid=0
create #65 -> rc=-1 errno=59 (Too many references: can't splice)  [cap hit]
destroy(id=0x20000000) -> rc=0 errno=0
create after destroy     -> rc=0 errno=0 (OK)  [want 0: slot freed]
uid=0
create #65 -> rc=-1 errno=59 (Too many references: can't splice)  [cap hit]
destroy(id=0x20000000) -> rc=0 errno=0
create after destroy     -> rc=0 errno=0 (OK)  [want 0: slot freed]
    -> each process has its own limit; no cross-process interference.

=== restore ===
sysctl vm.vkernel_enable: 1 -> 0
(then: vm.sh reset with-src -- guest returned to clean snapshot kernel)