- shovel(): fd2fd() returns FD_NODATA (-1) when a spurious wakeup
meets an empty socket (EAGAIN), but the switch treated -1 like
FD_CNXCLOSED and tore down a healthy connection. Only FD_CNXCLOSED
closes now.
- decrease_forked_connection(): hash_find() can return NULL (stale
SIGCHLD after a fork-limit rejection); dereferencing it crashed.
Guard and log instead.
- hexdump(): sprintf() into a 76-byte stack buffer with a "%06x"
offset that needs 12 chars once the dump passes 16 MB. Enlarge the
buffer and bound all writes with snprintf().
- printsettings(): sprintf() of config-supplied host strings into a
fixed buffer; use snprintf().
- echosrv: recvfrom() into data+prefix_len with size
sizeof(data)-prefix_len lets the terminating NUL write land one
byte past the stack buffer (verified with ASan at udp_echo, and a
>64KB prefix overflows the memcpy). Bound the prefix, reserve one
byte for the terminator, and skip the echo on recvfrom() error
instead of writing data[prefix_len-1].
- msg_int_error used verbose_system_error, leaving the documented
--verbose-int-error option dead. Point it at its own setting.
- Remove "echoѕrv-conf.h" (with Cyrillic ѕ, U+0455): a stale 2020
sslh-conf.h copy committed under a filename that is visually
identical to echosrv-conf.h but referenced by nothing.
- is_msrdp_protocol() stored the 16-bit TPKT length in a char, so a
packet claiming length 263 (0x0107) but carrying only 7 bytes
compared 7 == 7 and matched - any sufficiently short packet whose
declared length low byte equals its size is accepted as RDP.
Keep the declared length in a uint16_t. Verified with a harness:
{0x03 0x00 0x01 0x07 ...} no longer matches.
- is_teamspeak_protocol() used strncmp(p, "TS3INIT1", len): for the
first datagram of a real TS3 client (len > 8) this compares the
string literal's terminating NUL against packet byte 8, which is a
version field, so it could never match real traffic (and reads
past the literal for len > 9). Use a fixed 8-byte memcmp prefix.
- is_openvpn_protocol() and is_wireguard_protocol() dereferenced the
packet buffer through uint16_t*/uint32_t* casts; the buffer is not
aligned, which is UB and traps on strict-alignment targets (ARM).
Use memcpy() instead, as already done elsewhere in this file.