[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250613222411.1216170-3-kuni1840@gmail.com>
Date: Fri, 13 Jun 2025 15:22:14 -0700
From: Kuniyuki Iwashima <kuni1840@...il.com>
To: Martin KaFai Lau <martin.lau@...ux.dev>,
Daniel Borkmann <daniel@...earbox.net>,
John Fastabend <john.fastabend@...il.com>,
Alexei Starovoitov <ast@...nel.org>,
Andrii Nakryiko <andrii@...nel.org>
Cc: Eduard Zingerman <eddyz87@...il.com>,
Song Liu <song@...nel.org>,
Yonghong Song <yonghong.song@...ux.dev>,
KP Singh <kpsingh@...nel.org>,
Stanislav Fomichev <sdf@...ichev.me>,
Hao Luo <haoluo@...gle.com>,
Jiri Olsa <jolsa@...nel.org>,
Kumar Kartikeya Dwivedi <memxor@...il.com>,
Paul Moore <paul@...l-moore.com>,
James Morris <jmorris@...ei.org>,
"Serge E. Hallyn" <serge@...lyn.com>,
Mickaël Salaün <mic@...ikod.net>,
Günther Noack <gnoack@...gle.com>,
Stephen Smalley <stephen.smalley.work@...il.com>,
Ondrej Mosnacek <omosnace@...hat.com>,
Casey Schaufler <casey@...aufler-ca.com>,
Kuniyuki Iwashima <kuniyu@...gle.com>,
Kuniyuki Iwashima <kuni1840@...il.com>,
bpf@...r.kernel.org,
linux-security-module@...r.kernel.org,
selinux@...r.kernel.org,
netdev@...r.kernel.org
Subject: [PATCH v2 bpf-next 2/4] af_unix: Call security_unix_may_send() in sendmsg() for all socket types
From: Kuniyuki Iwashima <kuniyu@...gle.com>
Currently, security_unix_may_send() is invoked only for SOCK_DGRAM
sockets during connect() and sendmsg().
For SOCK_STREAM and SOCK_SEQPACKET sockets, an equivalent check
already occurs during connect(), making an additional hook in
sendmsg() unnecessary.
However, we want to leverage BPF LSM to inspect UNIXCB(skb) during
sendmsg().
As a preparation, let's call security_unix_may_send() for SOCK_STREAM
and SOCK_SEQPACKET in sendmsg().
Note that SELinux, SMACK, and Landlock use security_unix_may_send().
To avoid unintentionally triggering the hook for SOCK_STREAM and
SOCK_SEQPACKET, the socket type check is added in each LSM hooks.
Signed-off-by: Kuniyuki Iwashima <kuniyu@...gle.com>
---
net/unix/af_unix.c | 30 +++++++++++++++++++++---------
security/landlock/task.c | 3 +++
security/selinux/hooks.c | 3 +++
security/smack/smack_lsm.c | 3 +++
4 files changed, 30 insertions(+), 9 deletions(-)
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 6865da79ad1c..bcbe0c86e001 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -2170,11 +2170,9 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg,
goto out_unlock;
}
- if (sk->sk_type != SOCK_SEQPACKET) {
- err = security_unix_may_send(sk, other);
- if (err)
- goto out_unlock;
- }
+ err = security_unix_may_send(sk, other);
+ if (err)
+ goto out_unlock;
/* other == sk && unix_peer(other) != sk if
* - unix_peer(sk) == NULL, destination address bound to sk
@@ -2280,6 +2278,12 @@ static int queue_oob(struct sock *sk, struct msghdr *msg, struct sock *other,
goto out_unlock;
}
+ if (!fds_sent) {
+ err = security_unix_may_send(sk, other);
+ if (err)
+ goto out_unlock;
+ }
+
unix_maybe_add_creds(skb, sk, other);
scm_stat_add(other, skb);
@@ -2372,8 +2376,6 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,
if (err < 0)
goto out_free;
- fds_sent = true;
-
if (unlikely(msg->msg_flags & MSG_SPLICE_PAGES)) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
err = skb_splice_from_iter(skb, &msg->msg_iter, size,
@@ -2399,9 +2401,16 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,
goto out_pipe_unlock;
if (UNIXCB(skb).fp && !other->sk_scm_rights) {
- unix_state_unlock(other);
err = -EPERM;
- goto out_free;
+ goto out_unlock;
+ }
+
+ if (!fds_sent) {
+ err = security_unix_may_send(sk, other);
+ if (err)
+ goto out_unlock;
+
+ fds_sent = true;
}
unix_maybe_add_creds(skb, sk, other);
@@ -2425,6 +2434,9 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,
return sent;
+out_unlock:
+ unix_state_unlock(other);
+ goto out_free;
out_pipe_unlock:
unix_state_unlock(other);
out_pipe:
diff --git a/security/landlock/task.c b/security/landlock/task.c
index d7db70790a33..6bc6f3027790 100644
--- a/security/landlock/task.c
+++ b/security/landlock/task.c
@@ -305,6 +305,9 @@ static int hook_unix_may_send(struct sock *const sk,
if (!subject)
return 0;
+ if (sk->sk_type != SOCK_DGRAM)
+ return 0;
+
/*
* Checks if this datagram socket was already allowed to be connected
* to other.
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 07101a2bf942..904926ef9ee8 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -5184,6 +5184,9 @@ static int selinux_socket_unix_may_send(struct sock *sk,
struct common_audit_data ad;
struct lsm_network_audit net;
+ if (sk->sk_type != SOCK_DGRAM)
+ return 0;
+
ad_net_init_from_sk(&ad, &net, other);
return avc_has_perm(ssec->sid, osec->sid, osec->sclass, SOCKET__SENDTO,
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 9bb00c0df373..20fe1d22210e 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -3903,6 +3903,9 @@ static int smack_unix_may_send(struct sock *sk, struct sock *other)
smk_ad_setfield_u_net_sk(&ad, other);
#endif
+ if (sk->sk_type != SOCK_DGRAM)
+ return 0;
+
if (smack_privileged(CAP_MAC_OVERRIDE))
return 0;
--
2.49.0
Powered by blists - more mailing lists