Cap retained guest-to-host TCP payload across flows so a stalled sink cannot grow the supervisor toward the per-flow limit times the maximum flow count.
The guest is untrusted and fully controls the acknowledgement number of
every TCP segment it emits. tcp_process_data() accepted any forward ACK
(acked_bytes > 0) without checking that it stayed within the send window,
so the guest could acknowledge data that was never sent.
Each such ACK advances tx_acked_offset by up to 2^31-1. When tx_buffer is
empty the erase step below is a no-op, so tx_acked_offset accumulates and
can be driven past 2^32 with a few pure ACK segments. push_to_guest() then
computes:
int32_t available = tx_buffer.size() - tx_acked_offset;
const uint8_t* data = tx_buffer.data() + tx_acked_offset + in_flight;
available is an int32_t truncation of a size_t subtraction, so an oversized
tx_acked_offset wraps it back positive and defeats the in_flight >= available
guard. data then points at least 2 GB past the heap buffer and
tcp_send_packet() reads up to NSTUN_MTU bytes from it.
The nstun network loop runs in the nsjail parent (supervisor) process, and
SIGSEGV is not handled, so the out of bounds read lets an untrusted jailed
process crash its own supervisor. The minimum out of bounds distance is 2 GB,
so under ASLR the access reliably faults rather than returning data.
Add the RFC 793 receive check (SEG.ACK <= SND.NXT): reject ACKs whose
sequence is beyond seq_to_guest. This keeps tx_acked_offset within
tx_buffer.size(), which the framing in push_to_guest() relies on.
- Migrate TCP/UDP flow management to std::unique_ptr and packet parsing to std::span
- Add mandatory checksum validation for UDP (IPv4 optional, IPv6 per RFC 8200), closing parity with TCP/ICMP
- Handle IPv6 Authentication Header (AH) in extension header parser to prevent firewall rule bypass
- Add defense-in-depth MTU cap in tcp_process_data to prevent int32_t overflow in sequence arithmetic
- Fix uint16_t port loop overflow in HOST_TO_GUEST listener setup (infinite loop when dport_end=65535)
- Block SSRF via forged loopback/v4mapped destinations in both IPv4 and IPv6 TCP/UDP paths
- Extract policy evaluation and proxy encapsulation into standalone policy.cc and encap.cc modules
- Replace all raw inet_ntop+char[] patterns with ip4_to_string/ip6_to_string helpers
It provides lightweight IP-level connectivity for jailed processes via a TUN device and an epoll-based NAT proxy thread, as an alternative to pasta.
Supports TCP, UDP, and ICMP proxying with per-flow tracking, configurable firewall/redirect rules, SOCKS5 encapsulation for TCP and UDP.