From: Fernando Fernandez Mancera SYNPROXY is resetting conntrack seqadj when a closed connection is re-opened, but it was using nf_ct_seqadj_init() which is a no-op for a zero offset. This patch introduces nf_ct_seqadj_reset() which sets the offset values directly to zero and avoid setting IPS_SEQ_ADJUST_BIT flag, it changes SYNPROXY code to use it when needed. Fixes: 48b1de4c110a ("netfilter: add SYNPROXY core/target") Signed-off-by: Fernando Fernandez Mancera Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_conntrack_seqadj.h | 1 + net/netfilter/nf_conntrack_seqadj.c | 17 +++++++++++++++++ net/netfilter/nf_synproxy_core.c | 4 ++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_seqadj.h b/include/net/netfilter/nf_conntrack_seqadj.h index 883c414b768e..0f5bbb14a25a 100644 --- a/include/net/netfilter/nf_conntrack_seqadj.h +++ b/include/net/netfilter/nf_conntrack_seqadj.h @@ -33,6 +33,7 @@ static inline struct nf_conn_seqadj *nfct_seqadj_ext_add(struct nf_conn *ct) int nf_ct_seqadj_init(struct nf_conn *ct, enum ip_conntrack_info ctinfo, s32 off); +void nf_ct_seqadj_reset(struct nf_conn *ct, enum ip_conntrack_info ctinfo); int nf_ct_seqadj_set(struct nf_conn *ct, enum ip_conntrack_info ctinfo, __be32 seq, s32 off); void nf_ct_tcp_seqadj_set(struct sk_buff *skb, struct nf_conn *ct, diff --git a/net/netfilter/nf_conntrack_seqadj.c b/net/netfilter/nf_conntrack_seqadj.c index d75e8dafb189..b7b166a8ad58 100644 --- a/net/netfilter/nf_conntrack_seqadj.c +++ b/net/netfilter/nf_conntrack_seqadj.c @@ -31,6 +31,23 @@ int nf_ct_seqadj_init(struct nf_conn *ct, enum ip_conntrack_info ctinfo, } EXPORT_SYMBOL_GPL(nf_ct_seqadj_init); +void nf_ct_seqadj_reset(struct nf_conn *ct, enum ip_conntrack_info ctinfo) +{ + struct nf_conn_seqadj *seqadj = nfct_seqadj(ct); + enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); + struct nf_ct_seqadj *this_way; + + if (unlikely(!seqadj)) + return; + + spin_lock_bh(&ct->lock); + this_way = &seqadj->seq[dir]; + this_way->offset_before = 0; + this_way->offset_after = 0; + spin_unlock_bh(&ct->lock); +} +EXPORT_SYMBOL_GPL(nf_ct_seqadj_reset); + int nf_ct_seqadj_set(struct nf_conn *ct, enum ip_conntrack_info ctinfo, __be32 seq, s32 off) { diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c index 9fc959ba2030..401ce5a13f3f 100644 --- a/net/netfilter/nf_synproxy_core.c +++ b/net/netfilter/nf_synproxy_core.c @@ -686,7 +686,7 @@ ipv4_synproxy_hook(void *priv, struct sk_buff *skb, * adjustments, they will get initialized once the connection is * reestablished. */ - nf_ct_seqadj_init(ct, ctinfo, 0); + nf_ct_seqadj_reset(ct, ctinfo); synproxy->tsoff = 0; this_cpu_inc(snet->stats->conn_reopened); fallthrough; @@ -1116,7 +1116,7 @@ ipv6_synproxy_hook(void *priv, struct sk_buff *skb, * adjustments, they will get initialized once the connection is * reestablished. */ - nf_ct_seqadj_init(ct, ctinfo, 0); + nf_ct_seqadj_reset(ct, ctinfo); synproxy->tsoff = 0; this_cpu_inc(snet->stats->conn_reopened); fallthrough; -- 2.47.3