[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