From: Eric Dumazet <edumazet@kernel.org>
To: "David S . Miller" <davem@davemloft.net>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>
Cc: Kuniyuki Iwashima <kuniyu@google.com>,
Neal Cardwell <ncardwell@google.com>,
Ido Schimmel <idosch@nvidia.com>,
Theodor Arsenij Larionov Trichkine <theodorlarionov@gmail.com>,
Simon Horman <horms@kernel.org>,
netdev@vger.kernel.org, Eric Dumazet <edumazet@kernel.org>
Subject: [PATCH v3 net 2/2] tcp: use the echoed source route in cookie_v4_check()
Date: Mon, 12 Oct 2026 12:10:29 +0200 [thread overview]
Message-ID: <20261012101029.927296-3-edumazet@kernel.org> (raw)
In-Reply-To: <20261012101029.927296-1-edumazet@kernel.org>
When the ACK carries a source route option, cookie_v4_check() routes
the new socket to opt->faddr, where opt points to the options of the
received packet.
ip_options_compile() only fills faddr for options given by
setsockopt() (when called without an skb), so on receive faddr is 0
and the lookup is done for daddr 0, which gives a local route.
Use the options echoed by tcp_v4_save_options() instead, as
inet_csk_route_req() and inet_csk_route_child_sock() do with
ireq->ireq_opt. Read them after security_inet_conn_request(),
since CIPSO can replace ireq->ireq_opt there.
The route now goes to the first hop of the source route, so also
refuse a strict source route through a gateway, as
inet_csk_route_req() does.
Found by sashiko while reviewing the sk_mc_loop() fix.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Eric Dumazet <edumazet@kernel.org>
---
v3: new patch.
net/ipv4/syncookies.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 73e12976818473277e83ab47f271a43991217e3e..8c9691569e01af0140b8db8990ceeddc3c5fd8fb 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -404,12 +404,12 @@ static struct request_sock *cookie_tcp_check(struct net *net, struct sock *sk,
*/
struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
{
- struct ip_options *opt = &TCP_SKB_CB(skb)->header.h4.opt;
const struct tcphdr *th = tcp_hdr(skb);
struct tcp_sock *tp = tcp_sk(sk);
struct inet_request_sock *ireq;
struct net *net = sock_net(sk);
struct tcp_request_sock *treq;
+ struct ip_options_rcu *opt;
struct request_sock *req;
struct sock *ret = sk;
struct flowi4 fl4;
@@ -449,6 +449,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
SKB_DR_SET(reason, SECURITY_HOOK);
goto out_free;
}
+ /* Load ireq->ireq_opt after the LSM hook, which can replace it. */
+ opt = rcu_dereference_protected(ireq->ireq_opt, true);
tcp_ao_syncookie(sk, skb, req, AF_INET);
@@ -461,7 +463,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
flowi4_init_output(&fl4, ireq->ir_iif, ireq->ir_mark,
ip_sock_rt_tos(sk), ip_sock_rt_scope(sk),
IPPROTO_TCP, inet_sk_flowi_flags(sk),
- opt->srr ? opt->faddr : ireq->ir_rmt_addr,
+ (opt && opt->opt.srr) ? opt->opt.faddr : ireq->ir_rmt_addr,
ireq->ir_loc_addr, th->source, th->dest,
sk_uid(sk));
security_req_classify_flow(req, flowi4_to_flowi_common(&fl4));
@@ -470,6 +472,12 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
SKB_DR_SET(reason, IP_OUTNOROUTES);
goto out_free;
}
+ /* Same check as in inet_csk_route_req(). */
+ if (opt && opt->opt.is_strictroute && rt->rt_uses_gateway) {
+ ip_rt_put(rt);
+ SKB_DR_SET(reason, IP_OUTNOROUTES);
+ goto out_free;
+ }
/* Try to redo what tcp_v4_send_synack did. */
req->rsk_window_clamp = READ_ONCE(tp->window_clamp) ? :
--
2.53.0
next prev parent reply other threads:[~2026-10-12 10:10 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-12 10:10 [PATCH v3 net 0/2] net: fix sk_mc_loop() with request and timewait sockets Eric Dumazet
2026-10-12 10:10 ` [PATCH v3 net 1/2] net: use the full socket in sk_mc_loop() Eric Dumazet
2026-10-13 1:09 ` Kuniyuki Iwashima
2026-10-12 10:10 ` Eric Dumazet [this message]
2026-10-13 1:25 ` [PATCH v3 net 2/2] tcp: use the echoed source route in cookie_v4_check() Kuniyuki Iwashima
2026-10-12 10:14 ` [PATCH v3 net 0/2] net: fix sk_mc_loop() with request and timewait sockets netdev-bot+sinfo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261012101029.927296-3-edumazet@kernel.org \
--to=edumazet@kernel.org \
--cc=davem@davemloft.net \
--cc=horms@kernel.org \
--cc=idosch@nvidia.com \
--cc=kuba@kernel.org \
--cc=kuniyu@google.com \
--cc=ncardwell@google.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=theodorlarionov@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox