Patch "tls: fix missing memory barrier in tls_init" has been added to the 6.9-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    tls: fix missing memory barrier in tls_init

to the 6.9-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     tls-fix-missing-memory-barrier-in-tls_init.patch
and it can be found in the queue-6.9 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 03064f30334e5d3b585f8b33d748d8d43dbdccef
Author: Dae R. Jeong <threeearcat@xxxxxxxxx>
Date:   Tue May 21 19:34:38 2024 +0900

    tls: fix missing memory barrier in tls_init
    
    [ Upstream commit 91e61dd7a0af660408e87372d8330ceb218be302 ]
    
    In tls_init(), a write memory barrier is missing, and store-store
    reordering may cause NULL dereference in tls_{setsockopt,getsockopt}.
    
    CPU0                               CPU1
    -----                              -----
    // In tls_init()
    // In tls_ctx_create()
    ctx = kzalloc()
    ctx->sk_proto = READ_ONCE(sk->sk_prot) -(1)
    
    // In update_sk_prot()
    WRITE_ONCE(sk->sk_prot, tls_prots)     -(2)
    
                                       // In sock_common_setsockopt()
                                       READ_ONCE(sk->sk_prot)->setsockopt()
    
                                       // In tls_{setsockopt,getsockopt}()
                                       ctx->sk_proto->setsockopt()    -(3)
    
    In the above scenario, when (1) and (2) are reordered, (3) can observe
    the NULL value of ctx->sk_proto, causing NULL dereference.
    
    To fix it, we rely on rcu_assign_pointer() which implies the release
    barrier semantic. By moving rcu_assign_pointer() after ctx->sk_proto is
    initialized, we can ensure that ctx->sk_proto are visible when
    changing sk->sk_prot.
    
    Fixes: d5bee7374b68 ("net/tls: Annotate access to sk_prot with READ_ONCE/WRITE_ONCE")
    Signed-off-by: Yewon Choi <woni9911@xxxxxxxxx>
    Signed-off-by: Dae R. Jeong <threeearcat@xxxxxxxxx>
    Link: https://lore.kernel.org/netdev/ZU4OJG56g2V9z_H7@dragonet/T/
    Link: https://lore.kernel.org/r/Zkx4vjSFp0mfpjQ2@libra05
    Signed-off-by: Paolo Abeni <pabeni@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c
index b4674f03d71a9..90b7f253d3632 100644
--- a/net/tls/tls_main.c
+++ b/net/tls/tls_main.c
@@ -816,9 +816,17 @@ struct tls_context *tls_ctx_create(struct sock *sk)
 		return NULL;
 
 	mutex_init(&ctx->tx_lock);
-	rcu_assign_pointer(icsk->icsk_ulp_data, ctx);
 	ctx->sk_proto = READ_ONCE(sk->sk_prot);
 	ctx->sk = sk;
+	/* Release semantic of rcu_assign_pointer() ensures that
+	 * ctx->sk_proto is visible before changing sk->sk_prot in
+	 * update_sk_prot(), and prevents reading uninitialized value in
+	 * tls_{getsockopt, setsockopt}. Note that we do not need a
+	 * read barrier in tls_{getsockopt,setsockopt} as there is an
+	 * address dependency between sk->sk_proto->{getsockopt,setsockopt}
+	 * and ctx->sk_proto.
+	 */
+	rcu_assign_pointer(icsk->icsk_ulp_data, ctx);
 	return ctx;
 }
 




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux