udp6_ctlinput returns without lwkt_replymsg, deadlocking the netisr on a single crafted ICMPv6 packet
| Field | Value |
|---|---|
| ID | DF-0630 |
| Status | new |
| Severity | High |
| CVSS 3.1 | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H |
| CWE | CWE-400 Uncontrolled Resource Consumption (netmsg reply-contract violation β permanent thread wedge) |
| File | sys/netinet6/udp6_usrreq.c |
| Lines | 434-435 (bug); 448-449 (skipped reply) |
| Area | netinet6 (UDPv6 ICMPv6-error control input) |
| Confidence | certain |
| Discovered | 2026-07-02 |
| Reported | pending |
Summary
When an ICMPv6 error quotes a UDP/IPv6 packet whose quoted UDP header is
too short to contain the two port fields, udp6_ctlinput takes an early
return; (line 435) that bypasses the out: label and the mandatory
lwkt_replymsg(&msg->ctlinput.base.lmsg, 0) at line 449. Because
udp6's pr_ctlport is cpu0_ctlport (in6_proto.c:144) and
so_pr_ctlinput dispatches the message synchronously via lwkt_domsg
with the reply port set to the caller's own netisr port
(uipc_msg.c:604-610; lwkt_domsg blocks in lwkt_waitmsg until
MSGF_REPLY per lwkt_msgport.c:185-203), the netisr thread that
received the ICMPv6 packet blocks forever. A single ~88-byte
unauthenticated ICMPv6 Destination Unreachable thus permanently wedges a
netisr CPU; a handful of such packets across CPUs freezes the whole
network stack until reboot.
Root cause
udp6_ctlinput(netmsg_t msg) (udp6_usrreq.c:384) is a DragonFly netmsg
handler. Every such handler must call lwkt_replymsg before returning,
because icmp6_notify_error (icmp6.c:1044) reaches it via
so_pr_ctlinput (uipc_msg.c:594-611) which does:
netmsg_init(&msg.base, NULL, &curthread->td_msgport, 0, pr->pr_ctlinput);
...
lwkt_domsg(port, &msg.base.lmsg, 0);
lwkt_domsg sets MSGF_SYNC and, on EASYNC from the netisr spinport,
calls lwkt_waitmsg which sleeps until the reply arrives
(lwkt_msgport.c:193-198).
Inside udp6_ctlinput, with ip6 != NULL (any ICMPv6 error that quotes an
invoking packet, icmp6.c:1030-1036), the function executes:
434: if (m->m_pkthdr.len < off + sizeof(*uhp))
435: return; /* <-- BUG: skips lwkt_replymsg */
sizeof(*uhp) is 4 (two u_int16_t ports, lines 396-399). If the
attacker truncates the ICMPv6 packet so fewer than 4 bytes of the quoted
UDP header are present, control hits return; at line 435, skipping
out: (line 448) and lwkt_replymsg(&msg->ctlinput.base.lmsg, 0) (line
449). The synchronous caller in so_pr_ctlinput therefore never observes
MSGF_DONE and sleeps in lwkt_waitmsg indefinitely.
Every other early exit in the function correctly uses goto out; (lines
403, 406, 412). This one line is the sole exception.
Threat model & preconditions
- Attacker position: any host that can deliver an IPv6 packet to a victim interface IPv6 address (global or, for on-link attackers, link-local). IPv6 is enabled by default in the DragonFly kernel and ICMPv6 cannot be broadly blocked without breaking NDP/IPv6, so this is effectively default-config remote.
- No credentials, no prior UDP traffic required β the ICMPv6 error is
processed purely on its quoted content (
icmp6.c:874walks the quoted packet's next-header chain to derivenxt, then dispatchesinet6sw[ip6_protox[nxt]]; the attacker simply sets the quoted inner IPv6 header'sip6_nxt = 17/UDP). - Trigger: send a single crafted ICMPv6 Destination Unreachable whose
quoted invoking packet is an IPv6 header with
nh=UDPand zero bytes of UDP payload (or fewer than 4 bytes), so the quote ends before the 4-byte port pair.m->m_pkthdr.lenwill be< off + 4. - Impact: permanent denial of service. One packet wedges one netisr CPU; a few packets (one per CPU) freeze all network processing on the box, killing existing sessions and preventing any new ones, recoverable only by reboot.
Proof of concept
PoC source: findings/poc/DF-0630/udp6_ctlinput_deadlock.py.
Build & run
pip install scapy # or: pkg install py311-scapy on DragonFlyBSD python3 udp6_ctlinput_deadlock.py <victim_v6>
Expected output
Immediately after sending, the victim's IPv6 (and typically all) network
traffic stalls: an in-progress ssh -6 session freezes, ping6 victim
stops receiving echo replies, and top/ps auxww shows a netisr thread
pinned in lwkt_waitmsg. The box does not self-recover and must be
rebooted. ddb> ps shows the blocked netisr thread with a
udp6_ctlinput/lwkt_waitmsg backtrace.
Recommended fix
Change the early return; to goto out; so control falls through to the
existing lwkt_replymsg at the out: label:
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -431,7 +431,7 @@ udp6_ctlinput(netmsg_t msg)
*/
/* check if we can safely examine src and dst ports */
if (m->m_pkthdr.len < off + sizeof(*uhp))
- return;
+ goto out;
bzero(&uh, sizeof(uh));
m_copydata(m, off, sizeof(*uhp), &uh);
Defense-in-depth note: the sibling handlers rip6_ctlinput
(raw_ip6.c:229) and tcp6_ctlinput (tcp_subr.c:1549) should be audited
for the same return-without-reply pattern, since they share this
netmsg-conversion heritage from KAME/FreeBSD where the originals were
plain void functions.
References
sys/netinet6/udp6_usrreq.c:434-435β thereturn;that skipslwkt_replymsg.sys/netinet6/udp6_usrreq.c:448-449β theout:label andlwkt_replymsgthat are skipped.sys/netinet6/udp6_usrreq.c:403,406,412β the correctgoto out;pattern used for every other early exit.sys/kern/uipc_msg.c:594-611βso_pr_ctlinputsynchronous dispatch vialwkt_domsg.sys/kern/lwkt_msgport.c:193-198βlwkt_waitmsgsleeps until reply.
Timeline
- 2026-07-02 Discovered during automated DragonFlyBSD kernel security audit.
- 2026-07-02 Reported to DragonFlyBSD security contact (pending).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-0630 Β· 13 files| File | Type | Description | Size | |
|---|---|---|---|---|
| trigger.c | trigger-source | in-guest raw ICMPv6 socket injector; sends crafted DestUnreach (inner IPv6 nh=UDP plen=0) to ::1 | 3.7 KB | view raw |
| udp6_ctlinput_deadlock.py | trigger-source | original scapy trigger for external attackers (host->guest IPv6) | 1.5 KB | view raw |
| build.sh | build-script | cc -o trigger trigger.c | 203 B | view raw |
| run.sh | run-script | trigger + timed ping6/ssh probes | 1.2 KB | view raw |
| fix.diff | suggested-fix | one-liner: udp6_usrreq.c:435 return; -> goto out; (git apply-able) | 357 B | view raw |
| run.log | run-log | UNPATCHED #0 decisive run: baseline + trigger -> ping6/ssh hang (rc124), vm down, no panic | 1.7 KB | view raw |
| fix_run.log | run-log | PATCHED #1 runs: 5 single-shots + 12-shot burst, ping6 <2ms/0% loss, ssh OK, vm up | 1.9 KB | view raw |
| fix_build.log | build-log | full nativekernel output for the single-fix build, rc=0 | 5.6 MB | β download |
| env.txt | environment | uname #1, cc 8.3, ncpu=6, ipv6 addrs, patched line 435 | 410 B | view raw |
| VERDICT.md | verdict | full narrative: mechanism, repro, fix, validation | 7.7 KB | β raw |
| README.md | readme | PoC overview and run instructions | 3.0 KB | β raw |
| ../fix_build_combined.log | build-log | Combined 41-finding kernel build (rc=0, -Werror clean) | 5.6 MB | β download |
| ../fix_build_summary.txt | build-summary | Summary of the combined 41-finding kernel build | 826 B | view raw |
DF-0630 β PoC: udp6_ctlinput netisr deadlock
Remote unauthenticated single-packet permanent netisr wedge via crafted ICMPv6 Destination Unreachable whose quoted UDP header is too short.
Status: REPRODUCED on unpatched #0; fix VALIDATED on single-fix #1.
See VERDICT.md for the full analysis.
Files
trigger.cβ verified in-guest injector (rawIPPROTO_ICMPV6socket, root). Sends the crafted ICMPv6 DestUnreach (inner IPv6nh=UDP,plen=0) to::1; the guest's ownicmp6_inputdispatchesudp6_ctlinput, whichreturn;s atudp6_usrreq.c:435withoutlwkt_replymsg, wedging the netisr that ran icmp6 input (self-deadlock on cpu0 viacpu0_ctlport).udp6_ctlinput_deadlock.pyβ original scapy trigger, for an external attacker with IPv6 reachability to the victim (the QEMU user-mode net is IPv4-only NAT, so the C injector is used in-guest instead).build.sh/run.shβ exact repro scripts.fix.diffβ the one-line verified fix (return;βgoto out;).run.log/fix_run.log/fix_build.log/env.txtβ full evidence.
Build & run (in-guest, as root)
./build.sh # cc -o trigger trigger.c ./run.sh # trigger ::1 1 ; then timed ping6/ssh probes ./run.sh 12 # 12-shot burst
run.sh needs root (raw ICMPv6 socket). The root requirement is an artifact of
in-guest injection; the live vulnerability is remotely triggerable by any
unauthenticated host that can deliver an IPv6 packet to the victim.
Expected outcome
Unpatched kernel (6.5-DEVELOPMENT #0) β BUG PRESENT
Immediately after sending one packet:
- ping6 ::1 hangs forever (8 s timeout, rc 124).
- ssh round-trip hangs (rc 124); vm.sh status β down.
- serial console still shows the live login prompt β no panic, no fatal
trap, no ddb> (it is a permanent netisr wedge, not a crash).
- The box must be rebooted (vm.sh reset) to recover.
Patched kernel (6.5-DEVELOPMENT #1, fix applied) β BUG GONE
After the same trigger (single-shot Γ5 and a 12-shot burst):
- ping6 ::1 replies in < 2 ms, 0% loss.
- ssh responsive; vm.sh status β up.
Attack vector
- Remote unauthenticated β any host that can deliver an IPv6 packet to a victim address (global, or link-local for on-link attackers).
- IPv6 enabled by default; ICMPv6 cannot be broadly blocked without breaking NDP/IPv6.
- No prior UDP traffic and no credentials required β
icmp6_notify_errorderives the upper-layer protocol purely from the quoted inner header (icmp6.c:874). - One packet wedges one netisr CPU permanently; ~N packets (one per CPU, varied source so RSS spreads them) freeze the entire network stack.
Fix
One line at sys/netinet6/udp6_usrreq.c:435:
- return;
+ goto out;
Routes the early exit through the existing out: label so the mandatory
lwkt_replymsg(&msg->ctlinput.base.lmsg, 0) at :449 always runs. Matches the
finding markdown's recommended fix exactly.
DF-0630 β VERDICT
Status: REPRODUCED (and fix VALIDATED on a single-fix kernel).
| Finding | udp6_ctlinput returns without lwkt_replymsg, deadlocking the netisr on a single crafted ICMPv6 packet |
| Class | Remote unauthenticated one-shot network-stack DoS (netmsg reply-contract violation) |
| Severity | High (CVSS 3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H) |
| Guest | DragonFly 6.5-DEVELOPMENT unpatched #0 β reproduced; single-fix #1 β gone |
| Impact | dos β permanent netisr wedge, box must be rebooted |
Verdict (one line)
The bug is real and exploitable as described: a single ~48-byte crafted ICMPv6
Destination Unreachable permanently wedges a DragonFly netisr CPU, and the
one-line fix (return; β goto out; at udp6_usrreq.c:435) deterministically
closes it.
Mechanism (every hop cited)
- Trigger packet. An ICMPv6 Destination Unreachable (type 1) whose quoted
inner IPv6 packet has
nh=UDP(17)andplen=0(zero UDP bytes). With the outer IPv6 header this is 88 bytes on the wire. - Dispatch into udp6_ctlinput. On input the kernel runs
icmp6_inputβicmp6_notify_error(sys/netinet6/icmp6.c:1030-1046), which derivesnxtfrom the quoted inner header (icmp6.c:874, no prior UDP traffic or credentials required), setsip6cp.ip6c_off = eoffwhereeoff = off + 8 + 40 = 88(icmp6.c:875,1033), and callsso_pr_ctlinput(&inet6sw[ip6_protox[IPPROTO_UDP]], β¦)(icmp6.c:1044). - Synchronous netmsg.
so_pr_ctlinput(sys/kern/uipc_msg.c:594-611) sets the reply port to the caller's own netisr port (netmsg_init(..., &curthread->td_msgport, ...),uipc_msg.c:604) and dispatches vialwkt_domsg(port, β¦)(uipc_msg.c:610). udp6'spr_ctlportiscpu0_ctlport(sys/netinet6/in6_proto.c:144;sys/net/netisr.c:648-654), so the message always targets cpu0's netisr. lwkt_domsgblocks the caller.lwkt_domsgsetsMSGF_SYNCand, onEASYNCfrom the target port, callslwkt_waitmsg(sys/kern/lwkt_msgport.c:184-203). The netisr thread port'smp_putport=lwkt_thread_putport, which always returnsEASYNCβ even when the target is the current CPU (lwkt_msgport.c:712-738) β andlwkt_thread_waitmsgthen sleeps inlwkt_sleep("waitmsg", β¦)untilMSGF_DONE(lwkt_msgport.c:768-798).- The bug.
udp6_ctlinput(sys/netinet6/udp6_usrreq.c:384) tests, at:434-435:c if (m->m_pkthdr.len < off + sizeof(*uhp)) /* 88 < 88+4 -> TRUE */ return; /* <-- BUG */sizeof(*uhp)is 4 (twou_int16_tports,udp6_usrreq.c:396-399). The barereturn;skips theout:label (:448) and the mandatorylwkt_replymsg(&msg->ctlinput.base.lmsg, 0)(:449). Every other early exit in the function correctly usesgoto out;(:403, :406, :412); this one line is the sole exception. - Deadlock. With
lwkt_replymsgnever called,MSGF_DONEis never set, so the caller netisr sleeps inlwkt_waitmsgforever. Because the target is always cpu0 (cpu0_ctlport), a packet whoseicmp6_inputruns on cpu0 self-deadlocks cpu0; a packet that runs on cpuN (Nβ 0) wedges cpuN while cpu0 runs the handler and returns without replying. One packet wedges one netisr permanently; a handful (one per CPU, trivially arranged by varying the source so RSS spreads them) freezes all network processing until reboot.
Reproduction (unpatched #0)
The PoC injects from inside the guest because the QEMU user-mode network is
IPv4-only NAT (no hostβguest IPv6). A root raw IPPROTO_ICMPV6 socket sends
the 48-byte payload to ::1; rip6_output auto-computes the ICMPv6 checksum
(sys/netinet6/raw_ip6.c:392-419) and the packet loops back through lo0
into icmp6_input on cpu0 β self-deadlock. The root requirement is purely an
artifact of in-guest injection; the live vuln is remotely unauthenticated.
| Step | Result |
|---|---|
baseline ping6 -c1 ::1 |
0.076 ms, 0% loss |
| baseline ssh round-trip | 0.22 s |
trigger ::1 1 |
sent 48 bytes, rc 0 |
ping6 ::1 after trigger |
HANG (8 s timeout, rc 124) |
| ssh round-trip after trigger | HANG (8 s timeout, rc 124) |
vm.sh status after trigger |
down (network stack dead) |
serial boot.log |
login prompt still up β NO panic, NO fatal trap, NO ddb> |
I.e. a single packet froze the entire guest; the kernel did not crash (it is a
permanent netisr wedge, exactly as claimed). The box required vm.sh reset to
recover. Full untrimmed log: run.log.
Exploit chain
Remote network DoS β no memory-corruption primitive, so there is no escalation
chain to develop. The realistic ceiling is: one unauthenticated IPv6 packet
permanently wedges one netisr CPU; ~6 packets (one per CPU) freeze the whole
network stack, killing existing sessions and blocking all new ones until
reboot. The original udp6_ctlinput_deadlock.py (scapy) trigger is retained
for external attackers; the in-guest C trigger is added for this QEMU setup.
Fix (authored, validated)
fix.diff β one line, minimal, targets the confirmed root cause:
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -432,7 +432,7 @@
/* check if we can safely examine src and dst ports */
if (m->m_pkthdr.len < off + sizeof(*uhp))
- return;
+ goto out;
This routes the early exit through the existing out: label so the mandatory
lwkt_replymsg(&msg->ctlinput.base.lmsg, 0) at :449 is always executed,
restoring the netmsg reply contract. This matches the finding markdown's
## Recommended fix proposal exactly (same one-liner, same rationale).
git apply --check passes against the read-only sys/ tree.
Fix validation (Phase 8)
Built a single-fix kernel on the with-src base (warm obj, .c-only change β
incremental build, ~6 min, rc 0, no errors β fix_build.log):
- unpatched
#0kern.version:DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 - patched
#1kern.version:DragonFly 6.5-DEVELOPMENT #1: Thu Jul 2 19:52:53 UTC 2026 - patched
sha256(/boot/kernel/kernel):1dfc3c91β¦b2ed - Installed as the bare
/boot/kernel/kernel(the name the DragonFly loader boots), confirmed the#0 β #1bump, then rebooted.
Re-ran the SAME trigger on the patched kernel:
Probe on #1 |
Result |
|---|---|
baseline ping6 ::1 |
0.077 ms, 0% loss |
| after single-shot trigger Γ1 (Γ5 runs) | ping6 ::1 0.08β0.20 ms, 0% loss; ssh SSH_OK; vm up |
| after 12-shot burst | ping6 ::1 0.20/1.46 ms, 0% loss; vm up |
Before/after contrast: on #0 one trigger β ssh rc 124 (8 s timeout), vm
down; on #1 five single-shots + a 12-shot burst β every follow-up ping6
< 2 ms / 0% loss, ssh responsive, vm up. The fix is deterministic and
closes the bug. Full log: fix_run.log.
PoC changes
- Added
trigger.cβ in-guest C injector (rawIPPROTO_ICMPV6socket) sending the crafted ICMPv6 DestUnreach to::1; needed because the QEMU net is IPv4-only NAT so the scapy script (which assumes hostβguest IPv6) cannot run here. Documents why root is needed in-guest vs. the remote-unauthenticated threat model. - Added
build.sh/run.shrepro scripts. - Authored
fix.diff(above). - Kept the original
udp6_ctlinput_deadlock.pyfor external-attacker use.
Notes / defense-in-depth
- Sibling handlers
rip6_ctlinput(sys/netinet6/raw_ip6.c:229) andtcp6_ctlinput(sys/netinet6/tcp_subr.c) share this netmsg-conversion heritage and use the samecpu0_ctlport; they were called out in the finding for the samereturn-without-reply pattern and are worth a separate audit pass. - Recovered the guest (
vm.sh reset with-src) at the end of Phase 8.
Fix verification
fixedVALIDATED the fix. The SAME trigger that deadlocked the unpatched #0 baseline (ping6 ::1 / ssh hang at rc=124, vm down, no panic) does NOT wedge the single-fix #1 kernel: across 5 single-shot triggers and a 12-shot burst, ping6 ::1 stayed <2 ms / 0% loss, ssh stayed responsive, vm stayed up => the one-liner (return; -> goto out;) deterministically closes the netisr deadlock by guaranteeing lwkt_replymsg on every return.
baseline #0: trigger ::1 1 -> ping6 ::1 HANG rc=124 ; ssh HANG rc=124 ; vm.sh status=down (login prompt still up, no panic). patched #1: trigger ::1 1 x5 + ::1 12 burst -> ping6 ::1 0.08-1.46 ms / 0% loss ; ssh SSH_OK rc=0 ; vm.sh status=up. nativekernel build rc=0 (no errors).
Confirmed kernel references
- sys/netinet6/udp6_usrreq.c:434
- sys/netinet6/udp6_usrreq.c:435
- sys/netinet6/udp6_usrreq.c:448
- sys/netinet6/udp6_usrreq.c:449
- sys/netinet6/udp6_usrreq.c:403
- sys/netinet6/udp6_usrreq.c:406
- sys/netinet6/udp6_usrreq.c:412
- sys/netinet6/icmp6.c:874
- sys/netinet6/icmp6.c:1033
- sys/netinet6/icmp6.c:1044
- sys/kern/uipc_msg.c:604
- sys/kern/uipc_msg.c:610
- sys/kern/lwkt_msgport.c:193
- sys/kern/lwkt_msgport.c:737
- sys/kern/lwkt_msgport.c:791
- sys/netinet6/in6_proto.c:144
- sys/net/netisr.c:648
- sys/netinet6/raw_ip6.c:418
Detail
Exploit chain
Remote unauthenticated one-shot network-stack DoS (netmsg reply-contract violation), not a memory-corruption primitive, so there is no escalation chain to develop. Ceiling: one ~48-byte ICMPv6 packet wedges one netisr CPU permanently; ~6 packets (one per CPU, source-varied so RSS spreads them) freeze the whole network stack, killing existing sessions and blocking all new ones until reboot. Original udp6_ctlinput_deadlock.py (scapy) retained for external attackers; in-guest C trigger.c added because the QEMU user-mode net is IPv4-only NAT.
Evidence (decisive lines)
UNPATCHED #0: baseline ping6 ::1 = 0.076 ms, ssh = 0.22 s; after `trigger ::1 1`: `ping6 ::1` -> HANG (timeout rc=124), ssh round-trip -> HANG (rc=124), vm.sh status -> down; boot.log shows login prompt still up (no panic). PATCHED #1: after 5 single-shot triggers + a 12-shot burst, ping6 ::1 = 0.08-1.46 ms / 0% loss, ssh SSH_OK, vm up every time.
PoC changes
Added trigger.c (in-guest raw IPPROTO_ICMPV6 socket injector sending the crafted DestUnreach to ::1 β needed because the QEMU net is IPv4-only NAT so the scapy host->guest script cannot run here; rip6_output auto-computes the ICMPv6 checksum at raw_ip6.c:418); added build.sh/run.sh repro scripts; authored fix.diff (one-liner); kept the original udp6_ctlinput_deadlock.py for external attackers. Full evidence pack in findings/poc/DF-0630/ (VERDICT.md, run.log, fix_run.log, fix_build.log, env.txt, manifest.json).
Verified recommended fix
One-line change at sys/netinet6/udp6_usrreq.c:435: return; -> goto out;, so the early exit routes through the existing out: label and the mandatory lwkt_replymsg(&msg->ctlinput.base.lmsg,0) at :449 always executes, restoring the netmsg reply contract. git apply --check passes; matches the finding markdown's ## Recommended fix proposal exactly. Full git-apply-able diff in findings/poc/DF-0630/fix.diff.
Verdict
REPRODUCED and fix VALIDATED. The bug is real exactly as claimed: udp6_ctlinput takes an early return; at sys/netinet6/udp6_usrreq.c:435 (when the quoted UDP header is <4 bytes) that bypasses the out: label and the mandatory lwkt_replymsg at :449. I confirmed in source that so_pr_ctlinput (uipc_msg.c:604-610) dispatches it synchronously via lwkt_domsg with the reply port = the caller's own netisr; lwkt_thread_putport ALWAYS returns EASYNC (lwkt_msgport.c:737, even same-CPU) and lwkt_thread_waitmsg then sleeps in lwkt_sleep until MSGF_DONE (:791) β which never arrives because lwkt_replymsg is skipped β so the calling netisr blocks forever (self-deadlock on cpu0 since udp6's pr_ctlport=cpu0_ctlport, in6_proto.c:144). Empirically, ONE 48-byte crafted ICMPv6 DestUnreach (inner IPv6 nh=UDP plen=0) injected to ::1 froze the entire guest: baseline ping6 ::1=0.076ms/ssh=0.22s, but after the trigger both ping6 ::1 and a plain ssh round-trip hung past 8s timeouts (rc=124), vm.sh status=>down, and the serial console still showed the live login prompt (NO panic/fatal trap/ddb β a permanent netisr wedge, not a crash); the box required vm.sh reset to recover.
No comments yet.