[PATCH 1/2] landlock: Fix unmarked concurrent access to socket family

Matthieu Buffet matthieu at buffet.re
Tue Jun 9 21:15:10 UTC 2026


Socket family is read (twice) in a context where the socket is not
locked, so another thread can setsockopt(IPV6_ADDRFORM) to write it
concurrently. Add needed READ_ONCE() annotation.

Fixes: fff69fb03dde ("landlock: Support network rules with TCP bind and connect")
Signed-off-by: Matthieu Buffet <matthieu at buffet.re>
---
 security/landlock/net.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/security/landlock/net.c b/security/landlock/net.c
index a38bdfcffc22..111e58fd9325 100644
--- a/security/landlock/net.c
+++ b/security/landlock/net.c
@@ -55,6 +55,7 @@ static int current_check_access_socket(struct socket *const sock,
 	const struct access_masks masks = {
 		.net = access_request,
 	};
+	unsigned short sock_family;
 	const struct landlock_cred_security *const subject =
 		landlock_get_applicable_subject(current_cred(), masks, NULL);
 	struct lsm_network_audit audit_net = {};
@@ -66,6 +67,12 @@ static int current_check_access_socket(struct socket *const sock,
 	if (addrlen < offsetofend(typeof(*address), sa_family))
 		return -EINVAL;
 
+	/*
+	 * The socket is not locked, so sk_family can change concurrently
+	 * due to e.g. setsockopt(IPV6_ADDRFORM).
+	 */
+	sock_family = READ_ONCE(sock->sk->__sk_common.skc_family);
+
 	switch (address->sa_family) {
 	case AF_UNSPEC:
 		if (access_request == LANDLOCK_ACCESS_NET_CONNECT_TCP) {
@@ -102,7 +109,7 @@ static int current_check_access_socket(struct socket *const sock,
 			 * these checks, but it is safer to return a proper
 			 * error and test consistency thanks to kselftest.
 			 */
-			if (sock->sk->__sk_common.skc_family == AF_INET) {
+			if (sock_family == AF_INET) {
 				const struct sockaddr_in *const sockaddr =
 					(struct sockaddr_in *)address;
 
@@ -180,7 +187,7 @@ static int current_check_access_socket(struct socket *const sock,
 	 * check, but it is safer to return a proper error and test
 	 * consistency thanks to kselftest.
 	 */
-	if (address->sa_family != sock->sk->__sk_common.skc_family &&
+	if (address->sa_family != sock_family &&
 	    address->sa_family != AF_UNSPEC)
 		return -EINVAL;
 

base-commit: 4c403b9ffc86358d5ae50e4121aaf541bdab04d8
-- 
2.47.3




More information about the Linux-security-module-archive mailing list