[PATCH 07/19] smack: deduplicate task label validation

Konstantin Andreev andreev at swemel.ru
Thu Jul 24 13:09:40 UTC 2025


The part of the description of smk_task_invalid_label()
("Smack prohibits ... explicitly.")
was taken verbatim from the commit message of:

2013-12-16 Casey Schaufler
commit 19760ad03cc6 ("Smack: Prevent the * and @ labels
                      from being used in SMACK64EXEC")

Signed-off-by: Konstantin Andreev <andreev at swemel.ru>
---
 security/smack/smack_lsm.c | 47 +++++++++++++++++++++-----------------
 1 file changed, 26 insertions(+), 21 deletions(-)

diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 052404e2fda6..39e2e7b5bc3c 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -1369,6 +1369,21 @@ static int smack_inode_xattr_skipcap(const char *name)
 	return 0;
 }
 
+/*
+ * Smack prohibits processes from using the star ("*") and web ("@") labels
+ * because we don't want files with those labels getting created implicitly.
+ * All setting of those labels should be done explicitly.
+ *
+ * Comparing smack_known's assumes label has been imported. Until only builtin
+ * labels are prohibited, just imported label is not eligible for rejection.
+ */
+static bool
+smk_task_invalid_label(const struct smack_known * const skp)
+{
+	return skp == &smack_known_web ||
+	       skp == &smack_known_star;
+}
+
 /**
  * smack_inode_setxattr - Smack check for setting xattrs
  * @idmap: idmap of the mount
@@ -1387,7 +1402,7 @@ static int smack_inode_setxattr(struct mnt_idmap *idmap,
 				const void *value, size_t size, int flags)
 {
 	bool label_inside = true;
-	int check_star = 0;
+	bool task_label = false;
 	struct inode * const inode = d_backing_inode(dentry);
 	umode_t const i_mode = inode->i_mode;
 
@@ -1403,7 +1418,7 @@ static int smack_inode_setxattr(struct mnt_idmap *idmap,
 		;
 	} else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
 		   strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
-		check_star = 1;
+		task_label = true;
 	} else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
 		if (!S_ISDIR(i_mode) ||
 		    size != TRANS_TRUE_SIZE ||
@@ -1436,10 +1451,10 @@ static int smack_inode_setxattr(struct mnt_idmap *idmap,
 		if (IS_ERR(skp))
 			return PTR_ERR(skp);
 
-		if (check_star &&
-		    (skp == &smack_known_star ||
-		     skp == &smack_known_web))
-			return -EINVAL;
+		if (task_label) {
+			if (smk_task_invalid_label(skp))
+				return -EINVAL;
+		}
 	}
 
 	return 0;
@@ -3726,14 +3741,12 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
 		 * Don't let the exec or mmap label be "*" or "@".
 		 */
 		skp = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp);
-		if (IS_ERR(skp) || skp == &smack_known_star ||
-		    skp == &smack_known_web)
+		if (IS_ERR(skp) || smk_task_invalid_label(skp))
 			skp = NULL;
 		isp->smk_task = skp;
 
 		skp = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp);
-		if (IS_ERR(skp) || skp == &smack_known_star ||
-		    skp == &smack_known_web)
+		if (IS_ERR(skp) || smk_task_invalid_label(skp))
 			skp = NULL;
 		isp->smk_mmap = skp;
 
@@ -3830,17 +3843,6 @@ static int do_setattr(unsigned int attr, void *value, size_t size)
 	 */
 	if (smk_parse_label(value, size))
 		return -EINVAL;
-	/*
-	 * No process is ever allowed the web ("@") label
-	 * and the star ("*") label.
-	 */
-	if (size == 1 /* '@', '*' */) {
-		const char c = *(const char *)value;
-
-		if (c == *smack_known_web.smk_known ||
-		    c == *smack_known_star.smk_known)
-			return -EPERM;
-	}
 
 	if (!smack_privileged(CAP_MAC_ADMIN)) {
 		const struct smack_known_list_elem *sklep;
@@ -3860,6 +3862,9 @@ static int do_setattr(unsigned int attr, void *value, size_t size)
 	if (IS_ERR(skp))
 		return PTR_ERR(skp);
 
+	if (smk_task_invalid_label(skp))
+		return -EPERM;
+
 	new = prepare_creds();
 	if (new == NULL)
 		return -ENOMEM;
-- 
2.43.0




More information about the Linux-security-module-archive mailing list