[PATCH v2 bpf-next 2/4] af_unix: Call security_unix_may_send() in sendmsg() for all socket types
Kuniyuki Iwashima
kuni1840 at gmail.com
Fri Jun 13 22:22:14 UTC 2025
From: Kuniyuki Iwashima <kuniyu at google.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 at google.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
More information about the Linux-security-module-archive
mailing list