A remote, unauthenticated attacker can permanently pin a worker thread at 100% CPU by sending a single 4-byte SSTP packet with length=0 after completing only the TLS handshake and HTTP upgrade (no SSTP or PPP authentication required). Repeating once per worker thread achieves full denial of service for the SSTP VPN. Closing the TCP connection does not free the stuck thread — the daemon must be killed to recover.
Affected code: ctrl/sstp/sstp.c, lines 1906–1922 (sstp_handler while-loop).
The sstp_handler() function processes SSTP packets in a while (buf->len >= sizeof(*hdr)) loop. When hdr->length == 0:
n = ntohs(hdr->length) evaluates to 0.
The max-size guard (n > SSTP_MAX_PACKET_SIZE) passes — 0 is not > 4095.
The incomplete-packet guard (n > buf->len) passes — 0 is not > 4 (minimum buf->len with a header present).
sstp_recv_packet() dispatches on the reserved/type field. For unrecognized types (0x02–0xFF) it returns 0 (success), consuming nothing.
buf_pull(buf, 0) is a no-op — the buffer pointer and length are unchanged.
The loop condition buf->len >= sizeof(*hdr) remains true since nothing was consumed.
Result: infinite tight loop on the same 4 bytes, burning the CPU core permanently.
The root cause is the missing minimum-length validation — the code never checks that the declared packet length is at least as large as the header itself. A zero (or sub-header) length is silently accepted, creating a zero-advance iteration.