From: Bryam Vargas <hexlabsecurity@proton.me>
To: John Johansen <john.johansen@canonical.com>,
linux-security-module@vger.kernel.org, apparmor@lists.ubuntu.com
Cc: Paul Moore <paul@paul-moore.com>,
James Morris <jmorris@namei.org>,
"Serge E . Hallyn" <serge@hallyn.com>,
Mickael Salaun <mic@digikod.net>,
Stephen Smalley <stephen.smalley.work@gmail.com>,
Matthieu Buffet <matthieu@buffet.re>,
Mikhail Ivanov <ivanov.mikhail1@huawei-partners.com>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: AppArmor: TCP Fast Open bypasses connect mediation (last unaddressed LSM)
Date: Fri, 19 Jun 2026 01:11:45 +0000 [thread overview]
Message-ID: <20260619011138.264578-1-hexlabsecurity@proton.me> (raw)
Hello John, and LSM folks,
I have been working on the Landlock TCP Fast Open connect bypass [1]. Stephen
Smalley's SELinux fix for the same issue [3] -- "Similar to Landlock, SELinux was
not updated when TCP Fast Open support was introduced ..." -- made me go back and
check the rest of the connect-mediating LSMs, since I had only been looking at
Landlock. With Landlock [2], SELinux [3], and now TOMOYO [4] all getting fixes,
AppArmor is the last one with the same gap and no fix yet.
Root cause (shared with the others)
-----------------------------------
security_socket_connect() has a single call site, net/socket.c (the connect(2)
syscall). TCP Fast Open performs an implicit connect inside sendmsg:
tcp_sendmsg -> tcp_sendmsg_fastopen -> __inet_stream_connect(..., is_sendmsg=1)
-> sk->sk_prot->connect() net/ipv4/{tcp.c,af_inet.c}
This never calls security_socket_connect(); the only LSM hook on the path is
security_socket_sendmsg(). mptcp_sendmsg_fastopen reaches the same code and is a
second producer.
AppArmor
--------
apparmor_socket_connect() requests AA_MAY_CONNECT; apparmor_socket_sendmsg() (via
aa_sock_msg_perm) requests AA_MAY_SEND. These are distinct bits, and apparmor_parser
compiles them independently: "network send inet stream," yields accept mask 0x02
while "network connect inet stream," yields 0x40. So an egress-restriction profile
that grants send but not connect is bypassed by MSG_FASTOPEN.
Reproduced on 6.12.88 with apparmor active. Under a profile granting the inet/inet6
stream lifecycle except connect:
aa-exec -p egress_restricted -- ./probe
[TCP ] connect(2)=EACCES(blocked) sendto(MSG_FASTOPEN)=OK(reached) => connection established
[TCP6] connect(2)=EACCES(blocked) sendto(MSG_FASTOPEN)=OK(reached) => connection established
(The coarse "network inet stream," idiom grants connect anyway, so this only bites the
fine-grained "allow send, deny connect" policy that the asymmetry is meant to serve.)
Fix
---
Same shape as the TOMOYO [4] and SELinux [3] fixes: in apparmor_socket_sendmsg (or
aa_sock_msg_perm), when MSG_FASTOPEN is set and msg_name carries a destination on a
not-yet-connected stream socket, additionally require aa_sk_perm(OP_CONNECT,
AA_MAY_CONNECT, sk). I am happy to send that patch and the reproducer.
(A single core check in __inet_stream_connect(), gated on is_sendmsg, would have
covered all five LSMs and both the TCP and MPTCP producers in one place -- the kernel
already mediates the analogous implicit-connect-on-send for AF_UNIX via
security_unix_may_send and for SCTP via security_sctp_bind_connect. But since the
other four LSMs are taking per-hook fixes, AppArmor matching them is the consistent
move; mentioning the core option only in case it is preferred.)
[1] Landlock: LANDLOCK_ACCESS_NET_CONNECT_TCP bypass via TCP Fast Open (report)
https://lore.kernel.org/r/20260616201615.275032-1-hexlabsecurity@proton.me
[2] landlock: fix TCP Fast Open connection bypass (Matthieu Buffet)
https://lore.kernel.org/r/20260617180526.15627-2-matthieu@buffet.re
[3] selinux: check connect-related permissions on TCP Fast Open (Stephen Smalley)
https://lore.kernel.org/r/20260618175513.112443-2-stephen.smalley.work@gmail.com
[4] tomoyo: Enforce connect policy in TCP Fast Open (Matthieu Buffet)
https://lore.kernel.org/r/20260619002207.61104-1-matthieu@buffet.re
Thanks,
Bryam Vargas
reply other threads:[~2026-06-19 1:12 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260619011138.264578-1-hexlabsecurity@proton.me \
--to=hexlabsecurity@proton.me \
--cc=apparmor@lists.ubuntu.com \
--cc=edumazet@google.com \
--cc=ivanov.mikhail1@huawei-partners.com \
--cc=jmorris@namei.org \
--cc=john.johansen@canonical.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=matthieu@buffet.re \
--cc=mic@digikod.net \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=paul@paul-moore.com \
--cc=serge@hallyn.com \
--cc=stephen.smalley.work@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox