netfilter: synproxy: drop packets if timestamp adjustment fails

If a packet was malformed or if skb_ensure_writable() failed, the
synproxy_tstamp_adjust() function returned 0 indicating an error but it
was ignored on the callers.

Make the function return a boolean instead to clarify the result and
drop the packet if synproxy_tstamp_adjust() failed due to ENOMEM from
skb_ensure_writable(). In addition, if there are malformed options, skip
the tstamp update but do not drop the packet as that should be done by
the policy directly.

Fixes: 48b1de4c11 ("netfilter: add SYNPROXY core/target")
Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
Fernando Fernandez Mancera 2026-05-26 23:58:27 +02:00 committed by Pablo Neira Ayuso
parent f8bf5edf71
commit 63d29ee95c

View File

@ -184,7 +184,7 @@ synproxy_check_timestamp_cookie(struct synproxy_options *opts)
opts->options |= opts->tsecr & (1 << 5) ? NF_SYNPROXY_OPT_ECN : 0;
}
static unsigned int
static bool
synproxy_tstamp_adjust(struct sk_buff *skb, unsigned int protoff,
struct tcphdr *th, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
@ -194,13 +194,13 @@ synproxy_tstamp_adjust(struct sk_buff *skb, unsigned int protoff,
__be32 *ptr, old;
if (synproxy->tsoff == 0)
return 1;
return true;
optoff = protoff + sizeof(struct tcphdr);
optend = protoff + th->doff * 4;
if (skb_ensure_writable(skb, optend))
return 0;
return false;
th = (struct tcphdr *)(skb->data + protoff);
@ -209,7 +209,7 @@ synproxy_tstamp_adjust(struct sk_buff *skb, unsigned int protoff,
switch (op[0]) {
case TCPOPT_EOL:
return 1;
return true;
case TCPOPT_NOP:
optoff++;
continue;
@ -217,7 +217,7 @@ synproxy_tstamp_adjust(struct sk_buff *skb, unsigned int protoff,
if (optoff + 1 == optend ||
optoff + op[1] > optend ||
op[1] < 2)
return 0;
return true;
if (op[0] == TCPOPT_TIMESTAMP &&
op[1] == TCPOLEN_TIMESTAMP) {
if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
@ -233,12 +233,12 @@ synproxy_tstamp_adjust(struct sk_buff *skb, unsigned int protoff,
}
inet_proto_csum_replace4(&th->check, skb,
old, *ptr, false);
return 1;
return true;
}
optoff += op[1];
}
}
return 1;
return true;
}
#ifdef CONFIG_PROC_FS
@ -749,7 +749,9 @@ ipv4_synproxy_hook(void *priv, struct sk_buff *skb,
break;
}
synproxy_tstamp_adjust(skb, thoff, th, ct, ctinfo, synproxy);
if (!synproxy_tstamp_adjust(skb, thoff, th, ct, ctinfo, synproxy))
return NF_DROP_REASON(skb, SKB_DROP_REASON_NETFILTER_DROP, ENOMEM);
return NF_ACCEPT;
}
EXPORT_SYMBOL_GPL(ipv4_synproxy_hook);
@ -1177,7 +1179,9 @@ ipv6_synproxy_hook(void *priv, struct sk_buff *skb,
break;
}
synproxy_tstamp_adjust(skb, thoff, th, ct, ctinfo, synproxy);
if (!synproxy_tstamp_adjust(skb, thoff, th, ct, ctinfo, synproxy))
return NF_DROP_REASON(skb, SKB_DROP_REASON_NETFILTER_DROP, ENOMEM);
return NF_ACCEPT;
}
EXPORT_SYMBOL_GPL(ipv6_synproxy_hook);