From: Frank Lichtenheld Date: Fri, 31 Jul 2026 11:45:54 +0000 (+0200) Subject: ssl: Ignore hard reset packets with a non-zero packet id X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;p=thirdparty%2Fopenvpn.git ssl: Ignore hard reset packets with a non-zero packet id A hard reset is always the first packet of a session, so it always carries reliable packet id 0. tls_process_state() relies on that when it treats a received reset as the early negotiation packet only for packet id 0, and the stateless three-way handshake relies on it as well (see the comment in session_skip_to_pre_start()). A reset claiming a different id is therefore bogus. We had a bug that could cause hard reset replays with packet id 1 in specific scenarios (P2P TCP). In that case we accepted the packet id at face value and then ignored the control packet that actually had id 1 as an replay. This caused a difficult to diagnose dead connection that was stuck just before TLS negotiation. The check added handles this specific scenario well in that we just ignore the bogus reset but do not abort the connection attempt. Starting fresh might retrigger the bug. If there would be a separate bug where the client only sends hard resets with packet id 1 we will still get logging on the server side now. Change-Id: I3c7d1f9e5b2a4c6d8e1f3a5b7c9d2e4f6a8b1c3d Signed-off-by: Frank Lichtenheld Acked-by: Arne Schwabe Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1832 Message-Id: <20260731114605.11596-1-gert@greenie.muc.de> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg38098.html Signed-off-by: Gert Doering --- diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index 60df7ce84..ccd8264cc 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -3896,8 +3896,22 @@ tls_pre_decrypt(struct tls_multi *multi, const struct link_socket_actual *from, /* Extract the packet ID from the packet */ if (reliable_ack_read_packet_id(buf, &id)) { + /* A hard reset always is the first packet of a session, so it + * always must use packet id 0. Ignore it if it claims another id. + * In a specific existing bug these packets were replays of an + * already handled reset, so ignoring it is better than aborting + * the connection attempt. + */ + if (is_hard_reset_method2(op) && id != 0) + { + msg(D_TLS_ERRORS, + "TLS Error: received %s with packet id " packet_id_format + " from %s -- 0 was expected, ignoring packet", + packet_opcode_name(op), (packet_id_print_type)id, + print_link_socket_actual(from, &gc)); + } /* Avoid deadlock by rejecting packet that would de-sequentialize receive buffer */ - if (reliable_wont_break_sequentiality(ks->rec_reliable, id)) + else if (reliable_wont_break_sequentiality(ks->rec_reliable, id)) { if (reliable_not_replay(ks->rec_reliable, id)) {