mirror of
https://github.com/torvalds/linux
synced 2026-07-22 02:00:44 +09:00
netfilter: nft_synproxy: stop bypassing the priv->info snapshot
nft_synproxy_eval_v4() and nft_synproxy_eval_v6() already take a
whole-object READ_ONCE() snapshot of the shared priv->info state before
building the SYNACK reply, but nft_synproxy_tcp_options() still masks
opts->options with priv->info.options from the live shared object.
When a named synproxy object is updated concurrently with SYN traffic,
the eval path can then mix mss and timestamp handling from the local
snapshot with an options mask taken from a newer configuration, so one
SYNACK no longer reflects a coherent synproxy configuration.
Use info->options so nft_synproxy_tcp_options() stays on the same local
snapshot that the eval path already copied from priv->info.
Fixes: ee394f96ad ("netfilter: nft_synproxy: add synproxy stateful object support")
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
committed by
Pablo Neira Ayuso
parent
22f9dbed18
commit
11d4bc4e26
@@ -24,14 +24,13 @@ static const struct nla_policy nft_synproxy_policy[NFTA_SYNPROXY_MAX + 1] = {
|
||||
static void nft_synproxy_tcp_options(struct synproxy_options *opts,
|
||||
const struct tcphdr *tcp,
|
||||
struct synproxy_net *snet,
|
||||
struct nf_synproxy_info *info,
|
||||
const struct nft_synproxy *priv)
|
||||
struct nf_synproxy_info *info)
|
||||
{
|
||||
this_cpu_inc(snet->stats->syn_received);
|
||||
if (tcp->ece && tcp->cwr)
|
||||
opts->options |= NF_SYNPROXY_OPT_ECN;
|
||||
|
||||
opts->options &= priv->info.options;
|
||||
opts->options &= info->options;
|
||||
opts->mss_encode = opts->mss_option;
|
||||
opts->mss_option = info->mss;
|
||||
if (opts->options & NF_SYNPROXY_OPT_TIMESTAMP)
|
||||
@@ -56,7 +55,7 @@ static void nft_synproxy_eval_v4(const struct nft_synproxy *priv,
|
||||
|
||||
if (tcp->syn) {
|
||||
/* Initial SYN from client */
|
||||
nft_synproxy_tcp_options(opts, tcp, snet, &info, priv);
|
||||
nft_synproxy_tcp_options(opts, tcp, snet, &info);
|
||||
synproxy_send_client_synack(net, skb, tcp, opts);
|
||||
consume_skb(skb);
|
||||
regs->verdict.code = NF_STOLEN;
|
||||
@@ -87,7 +86,7 @@ static void nft_synproxy_eval_v6(const struct nft_synproxy *priv,
|
||||
|
||||
if (tcp->syn) {
|
||||
/* Initial SYN from client */
|
||||
nft_synproxy_tcp_options(opts, tcp, snet, &info, priv);
|
||||
nft_synproxy_tcp_options(opts, tcp, snet, &info);
|
||||
synproxy_send_client_synack_ipv6(net, skb, tcp, opts);
|
||||
consume_skb(skb);
|
||||
regs->verdict.code = NF_STOLEN;
|
||||
|
||||
Reference in New Issue
Block a user