]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ipv6: inet6_csk_xmit() and inet6_csk_update_pmtu() use inet->cork.fl.u.ip6
authorEric Dumazet <edumazet@google.com>
Fri, 6 Feb 2026 17:34:23 +0000 (17:34 +0000)
committerJakub Kicinski <kuba@kernel.org>
Wed, 11 Feb 2026 04:57:50 +0000 (20:57 -0800)
Convert inet6_csk_route_socket() to use np->final instead of an
automatic variable to get rid of a stack canary.

Convert inet6_csk_xmit() and inet6_csk_update_pmtu() to use
inet->cork.fl.u.ip6 instead of @fl6 automatic variable.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260206173426.1638518-5-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/ipv6/inet6_connection_sock.c

index e30172e634a64d85cc774d1cdcad1ee36c1f7e7a..03e307d5b6b9a2085b1e6b3e3c743795aa16879c 100644 (file)
@@ -60,7 +60,7 @@ static struct dst_entry *inet6_csk_route_socket(struct sock *sk,
 {
        struct inet_sock *inet = inet_sk(sk);
        struct ipv6_pinfo *np = inet6_sk(sk);
-       struct in6_addr *final_p, final;
+       struct in6_addr *final_p;
        struct dst_entry *dst;
 
        memset(fl6, 0, sizeof(*fl6));
@@ -77,7 +77,7 @@ static struct dst_entry *inet6_csk_route_socket(struct sock *sk,
        security_sk_classify_flow(sk, flowi6_to_flowi_common(fl6));
 
        rcu_read_lock();
-       final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final);
+       final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &np->final);
        rcu_read_unlock();
 
        dst = __sk_dst_check(sk, np->dst_cookie);
@@ -92,12 +92,12 @@ static struct dst_entry *inet6_csk_route_socket(struct sock *sk,
 
 int inet6_csk_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl_unused)
 {
+       struct flowi6 *fl6 = &inet_sk(sk)->cork.fl.u.ip6;
        struct ipv6_pinfo *np = inet6_sk(sk);
-       struct flowi6 fl6;
        struct dst_entry *dst;
        int res;
 
-       dst = inet6_csk_route_socket(sk, &fl6);
+       dst = inet6_csk_route_socket(sk, fl6);
        if (IS_ERR(dst)) {
                WRITE_ONCE(sk->sk_err_soft, -PTR_ERR(dst));
                sk->sk_route_caps = 0;
@@ -109,9 +109,9 @@ int inet6_csk_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl_unused
        skb_dst_set_noref(skb, dst);
 
        /* Restore final destination back after routing done */
-       fl6.daddr = sk->sk_v6_daddr;
+       fl6->daddr = sk->sk_v6_daddr;
 
-       res = ip6_xmit(sk, skb, &fl6, sk->sk_mark, rcu_dereference(np->opt),
+       res = ip6_xmit(sk, skb, fl6, sk->sk_mark, rcu_dereference(np->opt),
                       np->tclass, READ_ONCE(sk->sk_priority));
        rcu_read_unlock();
        return res;
@@ -120,13 +120,15 @@ EXPORT_SYMBOL_GPL(inet6_csk_xmit);
 
 struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu)
 {
-       struct flowi6 fl6;
-       struct dst_entry *dst = inet6_csk_route_socket(sk, &fl6);
+       struct flowi6 *fl6 = &inet_sk(sk)->cork.fl.u.ip6;
+       struct dst_entry *dst;
+
+       dst = inet6_csk_route_socket(sk, fl6);
 
        if (IS_ERR(dst))
                return NULL;
        dst->ops->update_pmtu(dst, sk, NULL, mtu, true);
 
-       dst = inet6_csk_route_socket(sk, &fl6);
+       dst = inet6_csk_route_socket(sk, fl6);
        return IS_ERR(dst) ? NULL : dst;
 }