In the Linux kernel, the following vulnerability has been resolved:
tls: fix missing memory barrier in tls_init
In tlsinit(), a write memory barrier is missing, and store-store reordering may cause NULL dereference in tls{setsockopt,getsockopt}.
CPU0 CPU1 ----- ----- // In tlsinit() // In tlsctxcreate() ctx = kzalloc() ctx->skproto = READONCE(sk->skprot) -(1)
// In updateskprot() WRITEONCE(sk->skprot, 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 rcuassignpointer() which implies the release barrier semantic. By moving rcuassignpointer() after ctx->skproto is initialized, we can ensure that ctx->skproto are visible when changing sk->sk_prot.