Thread (2 messages) 2 messages, 2 authors, 2025-05-08

Re: [PATCH] net: ipv4: Fix destination address determination in flowi4_init_output

flat view

From: Ozgur Kara <hidden>
Date: 2025-05-08 13:28:42
Also in: lkml

Neal Cardwell [off-list ref], 8 May 2025 Per, 15:54 tarihinde
şunu yazdı:
On Thu, May 8, 2025 at 6:21 AM Ozgur Kara [off-list ref] wrote:
quoted
From: Ozgur Karatas <redacted>

flowi4_init_output() function returns an argument and if opt->srr is
true and opt->faddr is assigned to be checked before opt->faddr is
used but if opt->srr seems to be true and opt->faddr is not set
properly yet.

opt itself will be an incompletely initialized struct and this access
may cause a crash.
* added daddr
* like readability by passing a single daddr argument to
flowi4_init_output() call.

Signed-off-by: Ozgur Karatas <redacted>
For bug fixes, please include a Fixes: footer; there are more details here:
   https://www.kernel.org/doc/html/v6.12/process/submitting-patches.html
Hello Neal, I will pay attention to this sorry.
quoted
---
 net/ipv4/syncookies.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 5459a78b9809..2ff92d512825 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -408,6 +408,7 @@ struct sock *cookie_v4_check(struct sock *sk,
struct sk_buff *skb)
        struct flowi4 fl4;
        struct rtable *rt;
        __u8 rcv_wscale;
+       __be32 daddr;
        int full_space;
        SKB_DR(reason);
@@ -442,6 +443,17 @@ struct sock *cookie_v4_check(struct sock *sk,
struct sk_buff *skb)
                goto out_free;
        }

+        /* Safely determine destination address considered SRR option.
+         * The flowi4 destination address is derived from opt->faddr
if opt->srr is set.
+         * However IP options are not always present in the skb and
accessing opt->faddr
+         * without validating opt->optlen and opt->srr can lead to
undefined behavior.
+         */
+        if (opt && opt->optlen && opt->srr) {
+                daddr = opt->faddr;
+        } else {
+                daddr = ireq->ir_rmt_addr;
+        }
Can you please explain how opt could be NULL, given how it is
initialized, like this:
        struct ip_options *opt = &TCP_SKB_CB(skb)->header.h4.opt;
?

And can you please explain how opt->srr could be set if opt->optlen is
0? I'm not seeing how it's possible, given how the
__ip_options_compile() code is structured. But perhaps I am missing
something.
The issue is more nuanced than opt being only NULL, while opt =
&TCP_SKB_CB(skb)->header.h4.opt gives a valid pointer to a structure
and the contents of that structure might be uninitialized or invalid
in certain code paths.
My patch adds defensive programming by checking three conditions
before accessing opt->faddr: whether opt itself is valid, opt->optlen
is non-zero and opt->srr is set.
This prevents undefined behavior when accessing opt->faddr in cases
where the structure's fields haven't been properly initialized.

The previous code (opt->srr ? opt->faddr : ireq->ir_rmt_addr) assumed
opt->srr was always valid, while the new code safely establishes daddr
= ireq->ir_rmt_addr as the default, only using opt->faddr when all
safety conditions are met.
 However, the issue lies in the validity of the struct ip_options
content, particularly opt->srr and opt->faddr. If the
TCP_SKB_CB(skb)->header.h4.opt structure is uninitialized or reset
(e.g., via memset or incomplete parsing), fields like opt->optlen and
opt->srr may contain garbage values, leading to undefined behavior
when accessed.

A specific example of this vulnerability occurs during early SYN
transactions, particularly if tcp_v4_cookie_check() is called
directly. In this scenario, opt->optlen might be zero while other
fields contain garbage values, which could lead to memory corruption
or security issues.
So this patch ensures robustness against invalid options, especially
in edge cases like malformed SYN packets, with minimal overhead.

am i mistaken? if there is missing information please forward it.

Regards

Ozgur
thanks,
neal
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help