From nobody Sat Jan 28 01:39:20 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 4P3cYh6s3vz3bpvh; Sat, 28 Jan 2023 01:39:20 +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 4P3cYh5q0rz3nN4; Sat, 28 Jan 2023 01:39:20 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1674869960; 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=8kkEqpJSfZDB/LMTVU1jFWCbfS7ilcLXTmIqMMTA9zk=; b=vHHv7xJDem3QWk29drJzakEQgQNz+OJ08VZrmbP9E/KjRHD5vGQWyggFOrP07lcVU/uN5n fdKLsYFxrUyvyIJ8bnxLdRR7AZeK8F5f0n1nQqffqvhbANfNk3Mv/Yo6hqJx2g+VQdxPjD FUUQ9eSaaLRfRsklBereGfBvT4pKzfV4gacqKpFTacYPAoQaLuHnqdS0ZEAxbtvq6cZ6cD yAsRGZ9oJhjnBprcidHsFKUF5uwMg7c7YA7r0/sYPdp/Wh246lqpL5myHW8owL/mZjgC6Y 4l2KCO94zYsuPz4Mk+daj5YwV4FiAibEkmfuZ6u8K1djFTQMqm3jm4PslfCPfg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1674869960; 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=8kkEqpJSfZDB/LMTVU1jFWCbfS7ilcLXTmIqMMTA9zk=; b=waG+1zkGYUJRLtaJJGnfMTLU8xELv/vTHoAo0TYP4q1nkiACJgPJfrbnXwepp1lnd3Fsvr Ldu8HjQSj3qR3lHEVrATrB3e3bk/Ew0eAlMhTVfD9ESzTlLeNww78H4WoJHr6yCWIZs4gk xK3r2xEdiHH6eToB2AzHQ2t/1HUvbm7krqqU67j/5dASCbmQNvc+0lEHLSQs4LzvxpgMWR 3GCpr22sr1ywfFYys9HrA7Mhw4YQTMkPwcbCKQ9o1luKQks/kVqjdKMYsXITcEth62NMAx r8GbE6h59QBBkHjOBegMTtZb7qBn2ly2qWCmf4xtMsJ1cVAHwsaxpK5gMGakWA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1674869960; a=rsa-sha256; cv=none; b=ygSVhDNwQodoD0+P3aXbUqFwtLRK9yF9A8xRAJ4Lx4B/25h6cfTDNB52tHOvl8Ti/lK3cc eQfo27EDmC9AMiKvvJcZ12DOx51tj8KNhKhpEQOBVvqiCwrkWd/UqMwkKhWFsUYniZAXW4 KjU+yVpVZfMfzUy3RubnjilVb/Fw1DBd03T7WqmI9IlxnQdyX6u74eYFNjzCa362xsmnHX yuY8fogNLrn5FftzhACGeuubbcq+urHhva5XqrMI9aJ1GHu3nxlsC4kPKcoXExIWv1HVt+ NoB1WX7jBgzRPx8yt1owTQCTZmXjIzJ+fNCiNYHwpb2Htgcqy8k7gjzG1H+dFA== 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 4P3cYh4D8VzWgD; Sat, 28 Jan 2023 01:39:20 +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 30S1dKks055994; Sat, 28 Jan 2023 01:39:20 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 30S1dKKC055981; Sat, 28 Jan 2023 01:39:20 GMT (envelope-from git) Date: Sat, 28 Jan 2023 01:39:20 GMT Message-Id: <202301280139.30S1dKKC055981@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kristof Provost Subject: git: 14f52003bd8a - stable/13 - 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/stable/13 X-Git-Reftype: branch X-Git-Commit: 14f52003bd8ae8884fcf8223e2170a7d76a39006 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=14f52003bd8ae8884fcf8223e2170a7d76a39006 commit 14f52003bd8ae8884fcf8223e2170a7d76a39006 Author: Kristof Provost AuthorDate: 2022-12-31 14:59:10 +0000 Commit: Kristof Provost CommitDate: 2023-01-28 01:34:38 +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 (cherry picked from commit 9c041b450d5e604c3e35b5799b60a2c53795feef) --- 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 a3611d49fc11..4b7f34122337 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -2108,6 +2108,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 d6c6a624d12b..c9c0995cc4e7 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -4951,9 +4951,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 6a375411d8ea..fb81f59097fb 100644 --- a/sys/netpfil/pf/pf_syncookies.c +++ b/sys/netpfil/pf/pf_syncookies.c @@ -300,8 +300,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; @@ -314,14 +314,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);