mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-08-09 09:51:49 +08:00
tlslib: harden recv_remaining() against truncated CSTP reads
recv_remaining() is used only on the non-TLS CSTP path (a UNIX socket proxying plaintext CSTP in front of ocserv). On a recv() failure or peer close mid-read, it discarded the error and returned whatever partial byte count it had accumulated so far. Since every caller only checks "ret <= 0" and otherwise trusts the count as a complete read, a truncated body could come back as a positive, non-zero total that looked like success: _cstp_recv_packet() would then report the full 8+pktlen size to its caller with only part of the buffer actually populated from the network, feeding stale/uninitialized bytes into parse_cstp_data() as if they were received client data. Make the contract unambiguous: recv_remaining() now returns either exactly the requested byte count or a negative error - never a partial positive count a caller could mistake for success. Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
This commit is contained in:
@@ -427,6 +427,33 @@ activates for that session even though `udp-port` is globally configured;
|
||||
(b) configure `udp-port = 0` and confirm the same.
|
||||
**Links:** REQ-WORKER-SEC-003
|
||||
|
||||
### REQ-WORKER-NET-004 — Non-TLS CSTP packet reassembly reports failure on incomplete reads, never a truncated packet as success
|
||||
|
||||
**Requirement:** `_cstp_recv_packet()`, when `ws->session == NULL` (CSTP
|
||||
carried in plaintext over a UNIX socket, e.g. terminated by a
|
||||
TLS-terminating proxy in front of ocserv), MUST treat any `recv()` failure
|
||||
or peer-closed condition encountered while assembling the 8-byte CSTP
|
||||
header or the declared-length body as a hard error for that read, and MUST
|
||||
NOT return a byte count implying a complete packet unless the full
|
||||
requested length was actually received. `recv_remaining()` MUST return
|
||||
either exactly the requested `left` byte count, or a negative error code
|
||||
(`GNUTLS_E_PREMATURE_TERMINATION` on peer close, or the `recv()` error
|
||||
otherwise) — it MUST NOT return a partial, positive byte count that a
|
||||
caller's `ret <= 0` check would treat as success, since that would surface
|
||||
stale/uninitialized buffer bytes to `parse_cstp_data` as if they were
|
||||
received client data.
|
||||
**Strength:** MUST
|
||||
**Status:** DERIVED
|
||||
**Source:** src/tlslib.c:158-183 (`recv_remaining`), src/tlslib.c:189-225
|
||||
(`_cstp_recv_packet`)
|
||||
**Acceptance:** negative, local, unit — `tests/cstp-recv.c`: a peer sends a
|
||||
full 8-byte CSTP header declaring an N-byte body, writes fewer than N body
|
||||
bytes, then closes the socket; confirm `_cstp_recv_packet()` returns a
|
||||
negative value, not `8+N` as if the packet were fully received.
|
||||
**Links:** REQ-PROTO-DATA-001 (this requirement supplies the precondition —
|
||||
a truthful `buf_size` — that REQ-PROTO-DATA-001's length-mismatch check
|
||||
depends on)
|
||||
|
||||
## Completeness notes
|
||||
|
||||
- **`worker-vpn.c` main loops** (`tls_mainloop`, `dtls_mainloop`,
|
||||
|
||||
@@ -459,7 +459,13 @@ OC-PROTO itself does not mandate the close-on-violation behavior (it is silent);
|
||||
OCSERV's choice (close) is the only behavior on record from any source, so there
|
||||
is no competing variant — this is "MAJORITY of 1 source that addresses the
|
||||
question at all."
|
||||
**Links**: REQ-PROTO-CONN-006
|
||||
**Note**: this requirement's `buf_size != 8 + pktlen` check can only detect a
|
||||
truncated body if `buf_size` (the worker's `data.size`, ultimately the return
|
||||
value of `_cstp_recv_packet`/`recv_remaining` in `src/tlslib.c`) truthfully
|
||||
reflects the number of bytes actually read from the socket — see
|
||||
REQ-WORKER-NET-004, which makes that precondition hold for the non-TLS
|
||||
(UNIX-socket-proxied) CSTP path.
|
||||
**Links**: REQ-PROTO-CONN-006, REQ-WORKER-NET-004
|
||||
|
||||
### REQ-PROTO-DATA-002
|
||||
**Requirement**: The CSTP/DTLS payload type byte MUST be one of `0x00` (DATA),
|
||||
|
||||
Reference in New Issue
Block a user