lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20251001215643.31465-3-casey@schaufler-ca.com>
Date: Wed,  1 Oct 2025 14:56:43 -0700
From: Casey Schaufler <casey@...aufler-ca.com>
To: casey@...aufler-ca.com,
	paul@...l-moore.com,
	linux-security-module@...r.kernel.org
Cc: jmorris@...ei.org,
	serge@...lyn.com,
	keescook@...omium.org,
	john.johansen@...onical.com,
	penguin-kernel@...ove.sakura.ne.jp,
	stephen.smalley.work@...il.com,
	linux-kernel@...r.kernel.org,
	selinux@...r.kernel.org
Subject: [PATCH 2/2] LSM: Allow reservation of netlabel

Allow LSMs to request exclusive access to the netlabel facility.
Provide mechanism for LSMs to determine if they have access to
netlabel. Update the current users of netlabel, SELinux and Smack,
to use and respect the exclusive use of netlabel.

Signed-off-by: Casey Schaufler <casey@...aufler-ca.com>
---
 include/linux/lsm_hooks.h           |  1 +
 security/security.c                 |  6 +++++
 security/selinux/hooks.c            |  7 +++---
 security/selinux/include/netlabel.h |  5 ++++
 security/selinux/netlabel.c         |  4 ++--
 security/smack/smack.h              |  5 ++++
 security/smack/smack_lsm.c          | 36 +++++++++++++++++++++--------
 security/smack/smackfs.c            | 20 +++++++++++++++-
 8 files changed, 69 insertions(+), 15 deletions(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 69c1b509577a..e49b5617383f 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -117,6 +117,7 @@ struct lsm_blob_sizes {
 	int lbs_tun_dev;
 	int lbs_bdev;
 	bool lbs_secmark; /* expressed desire for secmark use */
+	bool lbs_netlabel; /* expressed desire for netlabel use */
 };
 
 /*
diff --git a/security/security.c b/security/security.c
index e59e3d403de6..9eca10844b56 100644
--- a/security/security.c
+++ b/security/security.c
@@ -289,6 +289,12 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)
 		else
 			blob_sizes.lbs_secmark = true;
 	}
+	if (needed->lbs_netlabel) {
+		if (blob_sizes.lbs_netlabel)
+			needed->lbs_netlabel = false;
+		else
+			blob_sizes.lbs_netlabel = true;
+	}
 }
 
 /* Prepare LSM for initialization. */
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 5b6db7d8effb..24edeef41d25 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -182,7 +182,7 @@ static int selinux_secmark_enabled(void)
 static int selinux_peerlbl_enabled(void)
 {
 	return (selinux_policycap_alwaysnetwork() ||
-		netlbl_enabled() || selinux_xfrm_enabled());
+		selinux_netlbl_enabled() || selinux_xfrm_enabled());
 }
 
 static int selinux_netcache_avc_callback(u32 event)
@@ -5863,7 +5863,7 @@ static unsigned int selinux_ip_forward(void *priv, struct sk_buff *skb,
 				 SECCLASS_PACKET, PACKET__FORWARD_IN, &ad))
 			return NF_DROP;
 
-	if (netlbl_enabled())
+	if (selinux_netlbl_enabled())
 		/* we do this in the FORWARD path and not the POST_ROUTING
 		 * path because we want to make sure we apply the necessary
 		 * labeling before IPsec is applied so we can leverage AH
@@ -5880,7 +5880,7 @@ static unsigned int selinux_ip_output(void *priv, struct sk_buff *skb,
 	struct sock *sk;
 	u32 sid;
 
-	if (!netlbl_enabled())
+	if (!selinux_netlbl_enabled())
 		return NF_ACCEPT;
 
 	/* we do this in the LOCAL_OUT path and not the POST_ROUTING path
@@ -7185,6 +7185,7 @@ struct lsm_blob_sizes selinux_blob_sizes __ro_after_init = {
 	.lbs_tun_dev = sizeof(struct tun_security_struct),
 	.lbs_ib = sizeof(struct ib_security_struct),
 	.lbs_secmark = true,
+	.lbs_netlabel = true,
 };
 
 #ifdef CONFIG_PERF_EVENTS
diff --git a/security/selinux/include/netlabel.h b/security/selinux/include/netlabel.h
index 5731c0dcd3e8..5be82aa8e7ca 100644
--- a/security/selinux/include/netlabel.h
+++ b/security/selinux/include/netlabel.h
@@ -134,4 +134,9 @@ static inline int selinux_netlbl_socket_connect_locked(struct sock *sk,
 }
 #endif /* CONFIG_NETLABEL */
 
+static inline bool selinux_netlbl_enabled(void)
+{
+	return selinux_blob_sizes.lbs_netlabel && netlbl_enabled();
+}
+
 #endif
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index d51dfe892312..a6c58b8e7bfd 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -199,7 +199,7 @@ int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
 	int rc;
 	struct netlbl_lsm_secattr secattr;
 
-	if (!netlbl_enabled()) {
+	if (!selinux_netlbl_enabled()) {
 		*type = NETLBL_NLTYPE_NONE;
 		*sid = SECSID_NULL;
 		return 0;
@@ -444,7 +444,7 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
 	u32 perm;
 	struct netlbl_lsm_secattr secattr;
 
-	if (!netlbl_enabled())
+	if (!selinux_netlbl_enabled())
 		return 0;
 
 	netlbl_secattr_init(&secattr);
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 89bf62ad60f1..46e513f27e0a 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -374,6 +374,11 @@ static inline struct smack_known **smack_key(const struct key *key)
 }
 #endif /* CONFIG_KEYS */
 
+static inline bool smack_netlabel(void)
+{
+	return smack_blob_sizes.lbs_netlabel;
+}
+
 /*
  * Is the directory transmuting?
  */
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index ee86818633c1..4cbdb8c91a07 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -2575,6 +2575,9 @@ static int smack_netlbl_add(struct sock *sk)
 	struct smack_known *skp = ssp->smk_out;
 	int rc;
 
+	if (!smack_netlabel())
+		return 0;
+
 	local_bh_disable();
 	bh_lock_sock_nested(sk);
 
@@ -2606,6 +2609,9 @@ static void smack_netlbl_delete(struct sock *sk)
 {
 	struct socket_smack *ssp = smack_sock(sk);
 
+	if (!smack_netlabel())
+		return;
+
 	/*
 	 * Take the label off the socket if one is set.
 	 */
@@ -2656,7 +2662,7 @@ static int smk_ipv4_check(struct sock *sk, struct sockaddr_in *sap)
 		/*
 		 * Clear the socket netlabel if it's set.
 		 */
-		if (!rc)
+		if (!rc && smack_netlabel())
 			smack_netlbl_delete(sk);
 	}
 	rcu_read_unlock();
@@ -3982,6 +3988,8 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
 	int acat;
 	int kcat;
 
+	if (!smack_netlabel())
+		return smack_net_ambient;
 	/*
 	 * Netlabel found it in the cache.
 	 */
@@ -4132,6 +4140,9 @@ static struct smack_known *smack_from_netlbl(const struct sock *sk, u16 family,
 	struct socket_smack *ssp = NULL;
 	struct smack_known *skp = NULL;
 
+	if (!smack_netlabel())
+		return NULL;
+
 	netlbl_secattr_init(&secattr);
 
 	if (sk)
@@ -4202,7 +4213,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
 		rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad);
 		rc = smk_bu_note("IPv4 delivery", skp, ssp->smk_in,
 					MAY_WRITE, rc);
-		if (rc != 0)
+		if (rc != 0 && smack_netlabel())
 			netlbl_skbuff_err(skb, family, rc, 0);
 		break;
 #if IS_ENABLED(CONFIG_IPV6)
@@ -4390,7 +4401,7 @@ static int smack_inet_conn_request(const struct sock *sk, struct sk_buff *skb,
 	if (skp == NULL) {
 		skp = smack_from_netlbl(sk, family, skb);
 		if (skp == NULL)
-			skp = &smack_known_huh;
+			skp = smack_net_ambient;
 	}
 
 #ifdef CONFIG_AUDIT
@@ -4411,8 +4422,11 @@ static int smack_inet_conn_request(const struct sock *sk, struct sk_buff *skb,
 	/*
 	 * Save the peer's label in the request_sock so we can later setup
 	 * smk_packet in the child socket so that SO_PEERCRED can report it.
+	 *
+	 * Only do this if Smack is using netlabel.
 	 */
-	req->peer_secid = skp->smk_secid;
+	if (smack_netlabel())
+		req->peer_secid = skp->smk_secid;
 
 	/*
 	 * We need to decide if we want to label the incoming connection here
@@ -4425,10 +4439,13 @@ static int smack_inet_conn_request(const struct sock *sk, struct sk_buff *skb,
 	hskp = smack_ipv4host_label(&addr);
 	rcu_read_unlock();
 
-	if (hskp == NULL)
-		rc = netlbl_req_setattr(req, &ssp->smk_out->smk_netlabel);
-	else
-		netlbl_req_delattr(req);
+	if (smack_netlabel()) {
+		if (hskp == NULL)
+			rc = netlbl_req_setattr(req,
+						&ssp->smk_out->smk_netlabel);
+		else
+			netlbl_req_delattr(req);
+	}
 
 	return rc;
 }
@@ -4446,7 +4463,7 @@ static void smack_inet_csk_clone(struct sock *sk,
 	struct socket_smack *ssp = smack_sock(sk);
 	struct smack_known *skp;
 
-	if (req->peer_secid != 0) {
+	if (smack_netlabel() && req->peer_secid != 0) {
 		skp = smack_from_secid(req->peer_secid);
 		ssp->smk_packet = skp;
 	} else
@@ -5031,6 +5048,7 @@ struct lsm_blob_sizes smack_blob_sizes __ro_after_init = {
 	.lbs_superblock = sizeof(struct superblock_smack),
 	.lbs_xattr_count = SMACK_INODE_INIT_XATTRS,
 	.lbs_secmark = true,
+	.lbs_netlabel = true,
 };
 
 static const struct lsm_id smack_lsmid = {
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index b1e5e62f5cbd..b2487f676e0a 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -79,7 +79,7 @@ static DEFINE_MUTEX(smk_net6addr_lock);
  * If it isn't somehow marked, use this.
  * It can be reset via smackfs/ambient
  */
-struct smack_known *smack_net_ambient;
+struct smack_known *smack_net_ambient = &smack_known_floor;
 
 /*
  * This is the level in a CIPSO header that indicates a
@@ -671,6 +671,9 @@ static void smk_cipso_doi(void)
 	struct cipso_v4_doi *doip;
 	struct netlbl_audit nai;
 
+	if (!smack_netlabel())
+		return;
+
 	smk_netlabel_audit_set(&nai);
 
 	rc = netlbl_cfg_map_del(NULL, PF_INET, NULL, NULL, &nai);
@@ -711,6 +714,9 @@ static void smk_unlbl_ambient(char *oldambient)
 	int rc;
 	struct netlbl_audit nai;
 
+	if (!smack_netlabel())
+		return;
+
 	smk_netlabel_audit_set(&nai);
 
 	if (oldambient != NULL) {
@@ -834,6 +840,8 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
 	 */
 	if (!smack_privileged(CAP_MAC_ADMIN))
 		return -EPERM;
+	if (!smack_netlabel())
+		return -EINVAL;
 	if (*ppos != 0)
 		return -EINVAL;
 	if (format == SMK_FIXED24_FMT &&
@@ -1156,6 +1164,8 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf,
 	 */
 	if (!smack_privileged(CAP_MAC_ADMIN))
 		return -EPERM;
+	if (!smack_netlabel())
+		return -EINVAL;
 	if (*ppos != 0)
 		return -EINVAL;
 	if (count < SMK_NETLBLADDRMIN || count > PAGE_SIZE - 1)
@@ -1414,6 +1424,8 @@ static ssize_t smk_write_net6addr(struct file *file, const char __user *buf,
 	 */
 	if (!smack_privileged(CAP_MAC_ADMIN))
 		return -EPERM;
+	if (!smack_netlabel())
+		return -EINVAL;
 	if (*ppos != 0)
 		return -EINVAL;
 	if (count < SMK_NETLBLADDRMIN || count > PAGE_SIZE - 1)
@@ -1585,6 +1597,8 @@ static ssize_t smk_write_doi(struct file *file, const char __user *buf,
 
 	if (!smack_privileged(CAP_MAC_ADMIN))
 		return -EPERM;
+	if (!smack_netlabel())
+		return -EINVAL;
 
 	if (count >= sizeof(temp) || count == 0)
 		return -EINVAL;
@@ -1652,6 +1666,8 @@ static ssize_t smk_write_direct(struct file *file, const char __user *buf,
 
 	if (!smack_privileged(CAP_MAC_ADMIN))
 		return -EPERM;
+	if (!smack_netlabel())
+		return -EINVAL;
 
 	if (count >= sizeof(temp) || count == 0)
 		return -EINVAL;
@@ -1730,6 +1746,8 @@ static ssize_t smk_write_mapped(struct file *file, const char __user *buf,
 
 	if (!smack_privileged(CAP_MAC_ADMIN))
 		return -EPERM;
+	if (!smack_netlabel())
+		return -EINVAL;
 
 	if (count >= sizeof(temp) || count == 0)
 		return -EINVAL;
-- 
2.51.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ