From nobody Fri Jan 13 10:16:04 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Ntckr5Jzbz2p2f6; Fri, 13 Jan 2023 10:16:04 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Ntckr4mnNz3jyc; Fri, 13 Jan 2023 10:16:04 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1673604964; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=xmc0UBYu5rjde5IOwxqh5GD2VxtP91a57pf6qYIzSoc=; b=Occil8qct9v1MfOqs12SxihmwM7FpYebPiQpiezdYcsNcCZ4wzX9ymMo1FDVYMx0Vcu+xz FzQNyR4MpK1IHXlGdErPNYD5vucXQmCc+E1K/KLna/9PXuGP6Z9F+HuSrvTasMCQv9sQ65 2JIgqKOn9MkFsAJq45nOKP1BhsKPpTPZjAgH5sZ851Y2xP4qWDgpG0isTEyuf/5bdJkHER v/1pihF6qUiupiQnb3XxUgxZDq42/qpmUuUG+2TLJXrqMBnsTXmWRWl2Cb1FrZTI1rRChJ jTcAr6zyJXIOuJuK/A8yB2H4AnKFkHM5EAXLR5h21xFq+q36DS1L5XKa8DtCbg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1673604964; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=xmc0UBYu5rjde5IOwxqh5GD2VxtP91a57pf6qYIzSoc=; b=X0Y2utaYcy6JWCWguF0OWD5bafb/j3Ip0/Lj52ogCReLa7UaEdbeCG76DAzS//wW1HHtLQ +/JGYPqrkBTCdm8dqTEXr+g35WqjeyxybAQgVVtY19HFTzhMagapeRDNA/x4jAYtpVyS05 4UQtXv1KA8P0dw6ofuCHiB6DMPZBDdspagJbvojo12Zrmz7S7WSv8VEhq+vNavwA8cRhhB pbq6QEgSneQDz9/FeSqi9w/NtJl8SBr30JFDbCuJ/TPyH6jc26pOj0nK9Mau//b7Nr7Hlx T1EGl/FlSYMNSP7PnXf+QyPrYXd9akFfD1uSlMyFwPk3DtNcPtPmYEQEl5upqA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1673604964; a=rsa-sha256; cv=none; b=E4Z7KLiD/WffNCHtTlZpTcmpwmDpjAcoB9hve/wAoesCwyGYDMdUuK4oPfBt+ftr6wnX0D RTcZ3eY+R93XBqU4utN1eDhfEjOWk1pOTG10MowTeGb590qCOoDyVPKYoq9qUQk9Ky0zCP SlD3VNRJtbwfClFCBhqjsb9VSAIi5lOSIq69dTT7XIhlMQGtUBcYAVOc5Ap2Y/Eibg5WrJ xaZmoh4stWNbynsWm1pcuxdAJWfRHULijMhnycZt14m0VWM07Y5ijNqghiR+x4z8uTcrAt 7goyApPNSWpclHRmSIOcM8a0cptRju8vOwV25eQofWLEfP5e+hj4mB0tZMhFCw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4Ntckr3fGpz146H; Fri, 13 Jan 2023 10:16:04 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 30DAG4nA081314; Fri, 13 Jan 2023 10:16:04 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 30DAG42q081313; Fri, 13 Jan 2023 10:16:04 GMT (envelope-from git) Date: Fri, 13 Jan 2023 10:16:04 GMT Message-Id: <202301131016.30DAG42q081313@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kristof Provost Subject: git: 9c041b450d5e - main - pf: fix syncookies in conjunction with tcp fast port reuse List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kp X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 9c041b450d5e604c3e35b5799b60a2c53795feef Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=9c041b450d5e604c3e35b5799b60a2c53795feef commit 9c041b450d5e604c3e35b5799b60a2c53795feef Author: Kristof Provost AuthorDate: 2022-12-31 14:59:10 +0000 Commit: Kristof Provost CommitDate: 2023-01-13 22:14:12 +0000 pf: fix syncookies in conjunction with tcp fast port reuse Basic scenario: we have a closed connection (In TCPS_FIN_WAIT_2), and get a new connection (i.e. SYN) re-using the tuple. Without syncookies we look at the SYN, and completely unlink the old, closed state on the SYN. With syncookies we send a generated SYN|ACK back, and drop the SYN, never looking at the state table. So when the ACK (i.e. the third step in the three way handshake for connection setup) turns up, we’ve not actually removed the old state, so we find it, and don’t do the syncookie dance, or allow the new connection to get set up. Explicitly check for this in pf_test_state_tcp(). If we find a state in TCPS_FIN_WAIT_2 and the syncookie is valid we delete the existing state so we can set up the new state. Note that when we verify the syncookie in pf_test_state_tcp() we don't decrement the number of half-open connections to avoid an incorrect double decrement. MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D37919 --- sys/net/pfvar.h | 1 + sys/netpfil/pf/pf.c | 8 +++++--- sys/netpfil/pf/pf_syncookies.c | 23 +++++++++++++++++++---- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index f08ef0d0bfa0..bb058c8e8ae6 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -2263,6 +2263,7 @@ int pf_set_syncookies(struct pfioc_nv *); int pf_synflood_check(struct pf_pdesc *); void pf_syncookie_send(struct mbuf *m, int off, struct pf_pdesc *); +bool pf_syncookie_check(struct pf_pdesc *); u_int8_t pf_syncookie_validate(struct pf_pdesc *); struct mbuf * pf_syncookie_recreate_syn(uint8_t, int, struct pf_pdesc *); diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index c0c34fba0409..ca08023ea05d 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -5446,9 +5446,11 @@ pf_test_state_tcp(struct pf_kstate **state, int direction, struct pfi_kkif *kif, if ((action = pf_synproxy(pd, state, reason)) != PF_PASS) return (action); - if (((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN) && - dst->state >= TCPS_FIN_WAIT_2 && - src->state >= TCPS_FIN_WAIT_2) { + if (dst->state >= TCPS_FIN_WAIT_2 && + src->state >= TCPS_FIN_WAIT_2 && + (((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN) || + ((th->th_flags & (TH_SYN|TH_ACK|TH_RST)) == TH_ACK && + pf_syncookie_check(pd) && pd->dir == PF_IN))) { if (V_pf_status.debug >= PF_DEBUG_MISC) { printf("pf: state reuse "); pf_print_state(*state); diff --git a/sys/netpfil/pf/pf_syncookies.c b/sys/netpfil/pf/pf_syncookies.c index 0c9b5a459301..db232579d595 100644 --- a/sys/netpfil/pf/pf_syncookies.c +++ b/sys/netpfil/pf/pf_syncookies.c @@ -301,8 +301,8 @@ pf_syncookie_send(struct mbuf *m, int off, struct pf_pdesc *pd) 1); } -uint8_t -pf_syncookie_validate(struct pf_pdesc *pd) +bool +pf_syncookie_check(struct pf_pdesc *pd) { uint32_t hash, ack, seq; union pf_syncookie cookie; @@ -315,14 +315,29 @@ pf_syncookie_validate(struct pf_pdesc *pd) cookie.cookie = (ack & 0xff) ^ (ack >> 24); /* we don't know oddeven before setting the cookie (union) */ - if (atomic_load_64(&V_pf_status.syncookies_inflight[cookie.flags.oddeven]) + if (atomic_load_64(&V_pf_status.syncookies_inflight[cookie.flags.oddeven]) == 0) - return (0); + return (0); hash = pf_syncookie_mac(pd, cookie, seq); if ((ack & ~0xff) != (hash & ~0xff)) + return (false); + + return (true); +} + +uint8_t +pf_syncookie_validate(struct pf_pdesc *pd) +{ + uint32_t ack; + union pf_syncookie cookie; + + if (! pf_syncookie_check(pd)) return (0); + ack = ntohl(pd->hdr.tcp.th_ack) - 1; + cookie.cookie = (ack & 0xff) ^ (ack >> 24); + counter_u64_add(V_pf_status.lcounters[KLCNT_SYNCOOKIES_VALID], 1); atomic_add_64(&V_pf_status.syncookies_inflight[cookie.flags.oddeven], -1);