From 14b185b35597645fd8f1e1ddde5b752876bd7a14 Mon Sep 17 00:00:00 2001 From: yasuoka Date: Sat, 3 Sep 2022 14:57:54 +0000 Subject: [PATCH] When divert-reply is used, keep some pf states after pcb is dropped if its local address is translated, to prevent its source port from being reused. regress test by blumn. ok blumn --- sys/net/pf.c | 22 ++++++++++++++++++++-- sys/net/pfvar.h | 3 ++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/sys/net/pf.c b/sys/net/pf.c index 81a53fed2b0..fd36dbd4155 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.1138 2022/08/30 11:53:03 bluhm Exp $ */ +/* $OpenBSD: pf.c,v 1.1139 2022/09/03 14:57:54 yasuoka Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -1148,6 +1148,8 @@ pf_find_state(struct pf_pdesc *pd, struct pf_state_key_cmp *key, if (s == NULL) return (PF_DROP); + if (ISSET(s->state_flags, PFSTATE_INP_UNLINKED)) + return (PF_DROP); if (s->rule.ptr->pktrate.limit && pd->dir == s->direction) { pf_add_threshold(&s->rule.ptr->pktrate); @@ -1461,7 +1463,23 @@ pf_remove_divert_state(struct pf_state_key *sk) if (sk == si->s->key[PF_SK_STACK] && si->s->rule.ptr && (si->s->rule.ptr->divert.type == PF_DIVERT_TO || si->s->rule.ptr->divert.type == PF_DIVERT_REPLY)) { - pf_remove_state(si->s); + if (si->s->key[PF_SK_STACK]->proto == IPPROTO_TCP && + si->s->key[PF_SK_WIRE] != si->s->key[PF_SK_STACK]) { + /* + * If the local address is translated, keep + * the state for "tcp.closed" seconds to + * prevent its source port from being reused. + */ + if (si->s->src.state < TCPS_FIN_WAIT_2 || + si->s->dst.state < TCPS_FIN_WAIT_2) { + pf_set_protostate(si->s, PF_PEER_BOTH, + TCPS_TIME_WAIT); + si->s->timeout = PFTM_TCP_CLOSED; + si->s->expire = getuptime(); + } + si->s->state_flags |= PFSTATE_INP_UNLINKED; + } else + pf_remove_state(si->s); break; } } diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 6f88ff687ed..174eef37fe0 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfvar.h,v 1.509 2022/07/20 09:33:11 mbuhl Exp $ */ +/* $OpenBSD: pfvar.h,v 1.510 2022/09/03 14:57:54 yasuoka Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -784,6 +784,7 @@ struct pf_state { #define PFSTATE_RANDOMID 0x0080 #define PFSTATE_SCRUB_TCP 0x0100 #define PFSTATE_SETPRIO 0x0200 +#define PFSTATE_INP_UNLINKED 0x0400 #define PFSTATE_SCRUBMASK (PFSTATE_NODF|PFSTATE_RANDOMID|PFSTATE_SCRUB_TCP) #define PFSTATE_SETMASK (PFSTATE_SETTOS|PFSTATE_SETPRIO) u_int8_t log; -- 2.20.1