FAILED: patch "[PATCH] landlock: Fix TCP Fast Open connection bypass" failed to apply to 6.12-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x 33cb713db0161b54f04fe830e062c9e102c29a04
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026072134-equate-depraved-19f6@gregkh' --subject-prefix 'PATCH 6.12.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 33cb713db0161b54f04fe830e062c9e102c29a04 Mon Sep 17 00:00:00 2001
From: Matthieu Buffet <[email protected]>
Date: Wed, 1 Jul 2026 23:46:27 +0200
Subject: [PATCH] landlock: Fix TCP Fast Open connection bypass
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The documentation of the socket_connect() LSM hook states that it controls connecting a socket to a remote address. It has not been the case since the addition of TCP Fast Open (RFC 7413) support, which allows opening a TCP connection (thus, setting a socket's destination address) via the MSG_FASTOPEN flag passed to sendto()/sendmsg()/sendmmsg(). The problem then got duplicated into MPTCP.
Landlock did not take it into account when its TCP support was added, leaving a bypass of TCP connect policy.
Ideally a call to the LSM hook would be added in the fastopen code path, in order to fix this generically. But connect() hooks are designed to run with the socket locked, unlike sendmsg() hooks.
security/landlock/net.c +8 -0
@@ -351,6 +351,14 @@ static int hook_socket_sendmsg(struct socket *const sock,access_mask_t access_request;int ret =0 ; +if ((msg->msg_flags &MSG_FASTOPEN ) && address &&sk_is_tcp (sock->sk)) { + ret =current_check_access_socket ( + sock, address, addrlen,LANDLOCK_ACCESS_NET_CONNECT_TCP , + true); +if (ret !=0 ) +return ret; + } +if (sk_is_udp (sock->sk)) access_request =LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP ;else
Mickaël Salaün
maintainerPATCH 1/2 landlock: Fix TCP Fast Open connection bypass
From: Matthieu Buffet <[email protected]>
[ Upstream commit 33cb713db0161b54f04fe830e062c9e102c29a04 ]
The documentation of the socket_connect() LSM hook states that it controls connecting a socket to a remote address. It has not been the case since the addition of TCP Fast Open (RFC 7413) support, which allows opening a TCP connection (thus, setting a socket's destination address) via the MSG_FASTOPEN flag passed to sendto()/sendmsg()/sendmmsg(). The problem then got duplicated into MPTCP.
Landlock did not take it into account when its TCP support was added, leaving a bypass of TCP connect policy.
Ideally a call to the LSM hook would be added in the fastopen code path, in order to fix this generically. But connect() hooks are designed to run with the socket locked, unlike sendmsg() hooks.
[mic: Backport: adapt the TCP Fast Open check to the TCP-only network hooks]
--- security/landlock/net.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
security/landlock/net.c +14 -0
@@ -193,9 +193,23 @@ static int hook_socket_connect(struct socket *const sock, LANDLOCK_ACCESS_NET_CONNECT_TCP); } +static int hook_socket_sendmsg (struct socket *const sock, +struct msghdr *const msg,const int size) +{ +struct sockaddr *const address = msg->msg_name; + +if ((msg->msg_flags &MSG_FASTOPEN ) && address) +return current_check_access_socket ( + sock, address, msg->msg_namelen, +LANDLOCK_ACCESS_NET_CONNECT_TCP ); + +return 0 ; +} +static struct security_hook_list landlock_hooks[]__ro_after_init = {LSM_HOOK_INIT (socket_bind, hook_socket_bind),LSM_HOOK_INIT (socket_connect, hook_socket_connect), +LSM_HOOK_INIT (socket_sendmsg, hook_socket_sendmsg), };__init void landlock_add_net_hooks (void )
Mickaël Salaün
maintainerPATCH 2/2 selftests/landlock: Add test for TCP fast open
In reply to [email protected]From: Matthieu Buffet <[email protected]>
[ Upstream commit f4b30e0b1d488e7ffd8ea28d1365b9ba8e551edb ]
Enforce that TCP Fast Open is controlled by LANDLOCK_ACCESS_NET_CONNECT_TCP. Semantics of connect() and sendmsg(MSG_FASTOPEN) should be identical from Landlock's perspective. Also enforce error code consistency, since UDP sockets ignore the MSG_FASTOPEN flag while Unix sockets reject it.
[mic: Backport: adapt the test to the older network fixture and add the required send helper]
--- tools/testing/selftests/landlock/net_test.c | 155 ++++++++++++++++++++ 1 file changed, 155 insertions(+)
tools/testing/selftests/landlock/net_test.c +155 -0
@@ -257,6 +257,64 @@ static int connect_variant(const int sock_fd,return connect_variant_addrlen (sock_fd, srv,get_addrlen (srv, false)); } +static int sendto_variant_addrlen (const int sock_fd, +const struct service_fixture *const srv, +const socklen_t addrlen,void *buf, +size_t len,size_t flags) +{ +const struct sockaddr *dst =NULL ; +ssize_t ret; + +/* +* We never want our processes to be killed by SIGPIPE: we check return +* codes and errno, so that we have actual error messages. +*/ + flags |=MSG_NOSIGNAL ; + +if (srv !=NULL ) { +switch (srv->protocol.domain) { +case AF_UNSPEC : +case AF_INET : + dst = (const struct sockaddr *)&srv->ipv4_addr; +break ; + +case AF_INET6 : + dst = (const struct sockaddr *)&srv->ipv6_addr; +break ; + +case AF_UNIX : + dst = (const struct sockaddr *)&srv->unix_addr; +break ; + +default : + errno =EAFNOSUPPORT ; +return -errno; + } + } + + ret =sendto (sock_fd, buf, len, flags, dst, addrlen); +if (ret <0 ) +return -errno; + +/* errno is not set in cases of partial writes. */ +if (ret != len) +return -EINTR ; + +return 0 ; +} + +static int sendto_variant (const int sock_fd, +const struct service_fixture *const srv,void *buf, +size_t len,size_t flags) +{ +socklen_t addrlen =0 ; + +if (srv !=NULL ) + addrlen =get_addrlen (srv, false); + +return sendto_variant_addrlen (sock_fd, srv, addrlen, buf, len, flags); +} +FIXTURE (protocol) {struct service_fixture srv0, srv1, srv2, unspec_any0, unspec_srv0;
@@ -949,6 +1007,103 @@ TEST_F(protocol, connect_unspec)EXPECT_EQ (0 ,close (bind_fd)); } +TEST_F(protocol, tcp_fastopen) +{ +const bool restricted = variant->sandbox ==TCP_SANDBOX && + variant->prot.type ==SOCK_STREAM && + (variant->prot.protocol ==IPPROTO_TCP || + variant->prot.protocol ==IPPROTO_IP ) && + (variant->prot.domain ==AF_INET || + variant->prot.domain ==AF_INET6 ); +const struct landlock_ruleset_attr ruleset_attr = { + .handled_access_net =LANDLOCK_ACCESS_NET_CONNECT_TCP , + }; +int bind_fd, client_fd, status; +char buf; +pid_t child; + + bind_fd =socket_variant (&self->srv0); +ASSERT_LE (0 , bind_fd); +EXPECT_EQ (0 ,bind_variant (bind_fd, &self->srv0)); +if (self->srv0.protocol.type ==SOCK_STREAM ) +EXPECT_EQ (0 ,listen (bind_fd, backlog)); + + child =fork (); +ASSERT_LE (0 , child); +if (child ==0 ) { +int connect_fd, ret; + +/* Closes listening socket for the child. */ +EXPECT_EQ (0 ,close (bind_fd)); + + connect_fd =socket_variant (&self->srv0); +ASSERT_LE (0 , connect_fd); + +if (variant->sandbox ==TCP_SANDBOX ) { +const int ruleset_fd =landlock_create_ruleset ( + &ruleset_attr,sizeof (ruleset_attr),0 ); +ASSERT_LE (0 , ruleset_fd); + +enforce_ruleset (_metadata, ruleset_fd); +EXPECT_EQ (0 ,close (ruleset_fd)); + } + +/* Fast Open with no address. */ + ret =sendto_variant (connect_fd,NULL ,NULL ,0 ,MSG_FASTOPEN ); +if (self->srv0.protocol.domain ==AF_UNIX ) { +EXPECT_EQ (-ENOTCONN , ret); + }else if (self->srv0.protocol.type ==SOCK_DGRAM ) { +EXPECT_EQ (-EDESTADDRREQ , ret); + }else { +EXPECT_EQ (-EINVAL , ret); + } + +/* Fast Open to a denied address. */ + ret =sendto_variant (connect_fd, &self->srv0,"A" ,1 , +MSG_FASTOPEN ); +if (restricted) { +EXPECT_EQ (-EACCES , ret); + }else if (self->srv0.protocol.domain ==AF_UNIX && + self->srv0.protocol.type ==SOCK_STREAM ) { +EXPECT_EQ (-EOPNOTSUPP , ret); + }else { +EXPECT_EQ (0 , ret); + } + +EXPECT_EQ (0 ,close (connect_fd)); +_exit (_metadata->exit_code); +return ; + } + + client_fd = bind_fd; +if (!restricted && self->srv0.protocol.type ==SOCK_STREAM && + self->srv0.protocol.domain !=AF_UNIX ) { + client_fd =accept (bind_fd,NULL ,0 ); +ASSERT_LE (0 , client_fd); + } + +if (restricted) { +EXPECT_EQ (-1 ,read (client_fd, &buf,1 )); +EXPECT_EQ (ENOTCONN , errno); + }else if (self->srv0.protocol.domain ==AF_UNIX && + self->srv0.protocol.type ==SOCK_STREAM ) { +EXPECT_EQ (-1 ,read (client_fd, &buf,1 )); +EXPECT_EQ (EINVAL , errno); + }else { +EXPECT_EQ (1 ,read (client_fd, &buf,1 )); +EXPECT_EQ ('A' , buf); + } + +EXPECT_EQ (child,waitpid (child, &status,0 )); +EXPECT_EQ (1 ,WIFEXITED (status)); +EXPECT_EQ (EXIT_SUCCESS ,WEXITSTATUS (status)); + +if (client_fd != bind_fd) +EXPECT_LE (0 ,close (client_fd)); + +EXPECT_EQ (0 ,close (bind_fd)); +} +FIXTURE (ipv4) {struct service_fixture srv0, srv1;
Re: [PATCH 6.12.y 2/2] selftests/landlock: Add test for TCP fast open
Quoted 4 lines
[ Upstream commit
f4b30e0b1d488e7ffd8ea28d1365b9ba8e551edb]Enforce that TCP Fast Open is controlled by
LANDLOCK_ACCESS_NET_CONNECT_TCP.
Queued the series for 6.18 and 6.12, thanks. 6.18 was missing the fix as well, and your patches apply there unchanged.
Signature · 2 lines
Thanks, Sasha