mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] selinux: use socket SID for SCTP bind/connect permission checks in softirq
@ 2026-07-15 17:45 Tristan Madani
  0 siblings, 0 replies; only message in thread
From: Tristan Madani @ 2026-07-15 17:45 UTC (permalink / raw)
  To: Paul Moore, Stephen Smalley
  Cc: Ondrej Mosnacek, Richard Haines, selinux, stable, linux-kernel,
	Tristan Madani

__selinux_socket_bind() and selinux_socket_connect_helper() call
sock_has_perm() which uses current_sid() as the AVC subject.  When
selinux_sctp_bind_connect() is invoked from the ASCONF softirq path
(sctp_process_asconf), current is whichever process was interrupted,
so the permission check uses an unrelated subject SID.

Thread an explicit caller SID through __selinux_socket_bind() and
selinux_socket_connect_helper().  The process-context wrappers
(selinux_socket_bind, selinux_socket_connect) pass current_sid(), and
selinux_sctp_bind_connect() passes the socket own SID (sksec->sid),
consistent with other softirq-context hooks such as
selinux_socket_sock_rcv_skb() and selinux_sctp_assoc_request().

Factor out __sock_has_perm() with an explicit subject SID parameter
so that sock_has_perm() remains unchanged for all other callers.

Fixes: d452930fd3b9 ("selinux: Add SCTP support")
Cc: stable@vger.kernel.org
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
---
 security/selinux/hooks.c | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8d6945edae7a..1071c304faba 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4916,7 +4916,7 @@ static bool sock_skip_has_perm(u32 sid)
 }
 
 
-static int sock_has_perm(struct sock *sk, u32 perms)
+static int __sock_has_perm(struct sock *sk, u32 sid, u32 perms)
 {
 	struct sk_security_struct *sksec = selinux_sock(sk);
 	struct common_audit_data ad;
@@ -4927,10 +4927,15 @@ static int sock_has_perm(struct sock *sk, u32 perms)
 
 	ad_net_init_from_sk(&ad, &net, sk);
 
-	return avc_has_perm(current_sid(), sksec->sid, sksec->sclass, perms,
+	return avc_has_perm(sid, sksec->sid, sksec->sclass, perms,
 			    &ad);
 }
 
+static int sock_has_perm(struct sock *sk, u32 perms)
+{
+	return __sock_has_perm(sk, current_sid(), perms);
+}
+
 static int selinux_socket_create(int family, int type,
 				 int protocol, int kern)
 {
@@ -5000,13 +5005,14 @@ static int selinux_socket_socketpair(struct socket *socka,
    Need to determine whether we should perform a name_bind
    permission check between the socket and the port number. */
 
-static int __selinux_socket_bind(struct sock *sk, struct sockaddr *address, int addrlen)
+static int __selinux_socket_bind(struct sock *sk, u32 caller_sid,
+				struct sockaddr *address, int addrlen)
 {
 	struct sk_security_struct *sksec = selinux_sock(sk);
 	u16 family;
 	int err;
 
-	err = sock_has_perm(sk, SOCKET__BIND);
+	err = __sock_has_perm(sk, caller_sid, SOCKET__BIND);
 	if (err)
 		goto out;
 
@@ -5133,19 +5139,19 @@ static int __selinux_socket_bind(struct sock *sk, struct sockaddr *address, int
 
 static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen)
 {
-	return __selinux_socket_bind(sock->sk, address, addrlen);
+	return __selinux_socket_bind(sock->sk, current_sid(), address, addrlen);
 }
 
 /* This supports connect(2) and SCTP connect services such as sctp_connectx(3)
  * and sctp_sendmsg(3) as described in Documentation/security/SCTP.rst
  */
-static int selinux_socket_connect_helper(struct sock *sk,
+static int selinux_socket_connect_helper(struct sock *sk, u32 caller_sid,
 					 struct sockaddr *address, int addrlen)
 {
 	struct sk_security_struct *sksec = selinux_sock(sk);
 	int err;
 
-	err = sock_has_perm(sk, SOCKET__CONNECT);
+	err = __sock_has_perm(sk, caller_sid, SOCKET__CONNECT);
 	if (err)
 		return err;
 	if (addrlen < offsetofend(struct sockaddr, sa_family))
@@ -5230,7 +5236,7 @@ static int selinux_socket_connect(struct socket *sock,
 	int err;
 	struct sock *sk = sock->sk;
 
-	err = selinux_socket_connect_helper(sk, address, addrlen);
+	err = selinux_socket_connect_helper(sk, current_sid(), address, addrlen);
 	if (err)
 		return err;
 
@@ -5729,6 +5735,7 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname,
 				     struct sockaddr *address,
 				     int addrlen)
 {
+	struct sk_security_struct *sksec = selinux_sock(sk);
 	int len, err = 0, walk_size = 0;
 	void *addr_buf;
 	struct sockaddr *addr;
@@ -5765,14 +5772,14 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname,
 		case SCTP_PRIMARY_ADDR:
 		case SCTP_SET_PEER_PRIMARY_ADDR:
 		case SCTP_SOCKOPT_BINDX_ADD:
-			err = __selinux_socket_bind(sk, addr, len);
+			err = __selinux_socket_bind(sk, sksec->sid, addr, len);
 			break;
 		/* Connect checks */
 		case SCTP_SOCKOPT_CONNECTX:
 		case SCTP_PARAM_SET_PRIMARY:
 		case SCTP_PARAM_ADD_IP:
 		case SCTP_SENDMSG_CONNECT:
-			err = selinux_socket_connect_helper(sk, addr, len);
+			err = selinux_socket_connect_helper(sk, sksec->sid, addr, len);
 			if (err)
 				return err;
 
-- 
2.47.3


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-07-15 17:45 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-15 17:45 [PATCH] selinux: use socket SID for SCTP bind/connect permission checks in softirq Tristan Madani

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox