[PATCH 19/19] smack: deduplicate strcmp(name, XATTR_{,NAME_}SMACK*)
Konstantin Andreev
andreev at swemel.ru
Thu Jul 24 13:09:52 UTC 2025
Signed-off-by: Konstantin Andreev <andreev at swemel.ru>
---
security/smack/smack_lsm.c | 170 ++++++++++++++++++++++++-------------
1 file changed, 109 insertions(+), 61 deletions(-)
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 6c529de00584..81c0f69202ea 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -96,6 +96,49 @@ static int match_opt_prefix(char *s, int l, char **arg)
return Opt_error;
}
+enum smack_xa {
+ SMK_XA_OBJECT, // security.SMACK64
+ SMK_XA_IPIN, // security.SMACK64IPIN
+ SMK_XA_IPOUT, // security.SMACK64IPOUT
+ SMK_XA_EXEC, // security.SMACK64EXEC
+ SMK_XA_MMAP, // security.SMACK64MMAP
+ SMK_XA_TRANSMUTE, // security.SMACK64TRANSMUTE
+};
+
+static const char * const
+smk_xa_suffix[] = {
+ [SMK_XA_OBJECT] = "",
+ [SMK_XA_IPIN] = "IPIN",
+ [SMK_XA_IPOUT] = "IPOUT",
+ [SMK_XA_EXEC] = "EXEC",
+ [SMK_XA_MMAP] = "MMAP",
+ [SMK_XA_TRANSMUTE] = "TRANSMUTE",
+};
+
+static int
+smk_xa_suffix_to_id(const char *suffix)
+{
+ return match_string(smk_xa_suffix, ARRAY_SIZE(smk_xa_suffix), suffix);
+}
+
+static int
+smk_xa_name_to_id(const char *name)
+{
+ if (strncmp(name, XATTR_NAME_SMACK, sizeof(XATTR_NAME_SMACK) - 1))
+ return -EINVAL;
+
+ return smk_xa_suffix_to_id(name + (sizeof(XATTR_NAME_SMACK) - 1));
+}
+
+static int
+smk_xa_secname_to_id(const char *name)
+{
+ if (strncmp(name, XATTR_SMACK_SUFFIX, sizeof(XATTR_SMACK_SUFFIX) - 1))
+ return -EINVAL;
+
+ return smk_xa_suffix_to_id(name + (sizeof(XATTR_SMACK_SUFFIX) - 1));
+}
+
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
static char *smk_bu_mess[] = {
"Bringup Error", /* Unused */
@@ -1355,18 +1398,7 @@ static int smack_inode_getattr(const struct path *path)
*/
static int smack_inode_xattr_skipcap(const char *name)
{
- if (strncmp(name, XATTR_NAME_SMACK, sizeof(XATTR_NAME_SMACK) - 1))
- return 0;
-
- if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
- strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
- strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 ||
- strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
- strcmp(name, XATTR_NAME_SMACKMMAP) == 0 ||
- strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0)
- return 1;
-
- return 0;
+ return (smk_xa_name_to_id(name) >= 0);
}
/*
@@ -1406,15 +1438,17 @@ static int smack_inode_setxattr(struct mnt_idmap *idmap,
struct inode * const inode = d_backing_inode(dentry);
umode_t const i_mode = inode->i_mode;
- if (strcmp(name, XATTR_NAME_SMACK) == 0) {
+ switch (smk_xa_name_to_id(name)) {
+ case SMK_XA_OBJECT:
/*
* inode of socket file descriptor (sockfs inode) and
* UDS inode have fixed label
*/
if (S_ISSOCK(i_mode))
return -EOPNOTSUPP;
- } else if (strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
- strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) {
+ break;
+ case SMK_XA_IPIN:
+ case SMK_XA_IPOUT:
/*
* inode of socket file descriptor (sockfs inode) only
*/
@@ -1423,19 +1457,22 @@ static int smack_inode_setxattr(struct mnt_idmap *idmap,
if (SOCKET_I(inode)->sk == NULL)
return -EOPNOTSUPP;
- } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
- strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
+ break;
+ case SMK_XA_EXEC:
+ case SMK_XA_MMAP:
if (!S_ISREG(i_mode))
return -EOPNOTSUPP;
task_label = true;
- } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
+ break;
+ case SMK_XA_TRANSMUTE:
if (!S_ISDIR(i_mode))
return -EOPNOTSUPP;
if (size != TRANS_TRUE_SIZE ||
strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
return -EINVAL;
label_inside = false;
- } else {
+ break;
+ default: {
/*
* treat other xattrs as labeled data
*/
@@ -1447,6 +1484,7 @@ static int smack_inode_setxattr(struct mnt_idmap *idmap,
return smk_bu_inode(inode, MAY_WRITE,
smk_curacc(smk_of_inode(inode), MAY_WRITE, &ad));
}
+ }
if (!smack_privileged(CAP_MAC_ADMIN))
return -EPERM;
@@ -1487,17 +1525,21 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
struct smack_known **skpp = NULL;
struct inode_smack *isp = smack_inode(d_backing_inode(dentry));
- if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
+ switch (smk_xa_name_to_id(name)) {
+ case SMK_XA_TRANSMUTE:
isp->smk_flags |= SMK_INODE_TRANSMUTE;
return;
+ case SMK_XA_OBJECT:
+ skpp = &isp->smk_inode;
+ break;
+ case SMK_XA_EXEC:
+ skpp = &isp->smk_task;
+ break;
+ case SMK_XA_MMAP:
+ skpp = &isp->smk_mmap;
+ break;
}
- if (strcmp(name, XATTR_NAME_SMACK) == 0)
- skpp = &isp->smk_inode;
- else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0)
- skpp = &isp->smk_task;
- else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0)
- skpp = &isp->smk_mmap;
/*
* Label has been imported by smack_inode_setxattr, just find it
*/
@@ -1545,16 +1587,9 @@ static int smack_inode_removexattr(struct mnt_idmap *idmap,
{
const struct inode * const inode = d_backing_inode(dentry);
struct inode_smack * const isp = smack_inode(inode);
+ int const xa_id = smk_xa_name_to_id(name);
- if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
- strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
- strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 ||
- strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
- strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 ||
- strcmp(name, XATTR_NAME_SMACKMMAP) == 0) {
- if (!smack_privileged(CAP_MAC_ADMIN))
- return -EPERM;
- } else {
+ if (xa_id < 0) {
/*
* treat other xattrs as labeled data
*/
@@ -1567,25 +1602,34 @@ static int smack_inode_removexattr(struct mnt_idmap *idmap,
smk_curacc(isp->smk_inode, MAY_WRITE, &ad));
}
+ if (!smack_privileged(CAP_MAC_ADMIN))
+ return -EPERM;
+
/*
* Don't do anything special for these.
* XATTR_NAME_SMACKIPIN
* XATTR_NAME_SMACKIPOUT
* XATTR_NAME_SMACK if S_ISSOCK (UDS inode has fixed label)
*/
- if (strcmp(name, XATTR_NAME_SMACK) == 0) {
+ switch (xa_id) {
+ case SMK_XA_OBJECT:
if (!S_ISSOCK(inode->i_mode)) {
struct super_block *sbp = dentry->d_sb;
struct superblock_smack *sbsp = smack_superblock(sbp);
isp->smk_inode = sbsp->smk_default;
}
- } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0)
+ break;
+ case SMK_XA_EXEC:
isp->smk_task = NULL;
- else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0)
+ break;
+ case SMK_XA_MMAP:
isp->smk_mmap = NULL;
- else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0)
+ break;
+ case SMK_XA_TRANSMUTE:
isp->smk_flags &= ~SMK_INODE_TRANSMUTE;
+ break;
+ }
return 0;
}
@@ -1676,20 +1720,26 @@ static int smack_inode_getsecurity(struct mnt_idmap *idmap,
const struct inode_smack * const isp = smack_inode(inode);
const char *value = NULL;
int value_len;
+ int const xa_id = smk_xa_secname_to_id(name);
- if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
+ switch (xa_id) {
+ case SMK_XA_OBJECT:
skp = isp->smk_inode;
- } else if (strcmp(name, XATTR_SMACK_EXEC) == 0) {
+ break;
+ case SMK_XA_EXEC:
skp = isp->smk_task;
- } else if (strcmp(name, XATTR_SMACK_MMAP) == 0) {
+ break;
+ case SMK_XA_MMAP:
skp = isp->smk_mmap;
- } else if (strcmp(name, XATTR_SMACK_TRANSMUTE) == 0) {
+ break;
+ case SMK_XA_TRANSMUTE:
if (isp->smk_flags & SMK_INODE_TRANSMUTE)
value = TRANS_TRUE;
else
return -ENODATA;
- } else if (strcmp(name, XATTR_SMACK_IPIN) == 0 ||
- strcmp(name, XATTR_SMACK_IPOUT) == 0) {
+ break;
+ case SMK_XA_IPIN:
+ case SMK_XA_IPOUT: {
/*
* These Smack xattrs are only on sockets.
*/
@@ -1705,12 +1755,15 @@ static int smack_inode_getsecurity(struct mnt_idmap *idmap,
ssp = smack_sock(sk);
- if (strcmp(name, XATTR_SMACK_IPIN) == 0)
+ if (xa_id == SMK_XA_IPIN)
skp = ssp->smk_in;
else
skp = ssp->smk_out;
- } else
+ break;
+ }
+ default:
return -EOPNOTSUPP;
+ }
if (!value) {
if (!skp)
@@ -2986,28 +3039,23 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
struct socket_smack *ssp;
struct socket *sock;
int rc = 0;
+ int const xa_id = smk_xa_secname_to_id(name);
- if (!(strcmp(name, XATTR_SMACK_SUFFIX) == 0 ||
- strcmp(name, XATTR_SMACK_TRANSMUTE) == 0 ||
- strcmp(name, XATTR_SMACK_EXEC) == 0 ||
- strcmp(name, XATTR_SMACK_MMAP) == 0 ||
- strcmp(name, XATTR_SMACK_IPIN) == 0 ||
- strcmp(name, XATTR_SMACK_IPOUT) == 0
- ))
+ if (xa_id < 0)
return -EOPNOTSUPP;
- if (strcmp(name, XATTR_SMACK_TRANSMUTE) == 0) {
+ switch (xa_id) {
+ case SMK_XA_TRANSMUTE:
nsp->smk_flags |= SMK_INODE_TRANSMUTE;
return 0;
- }
-
- if (strcmp(name, XATTR_SMACK_EXEC) == 0 ||
- strcmp(name, XATTR_SMACK_MMAP) == 0)
+ case SMK_XA_EXEC:
+ case SMK_XA_MMAP:
return -ENODATA;
+ }
skp = smk_find_label(value, size);
- if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
+ if (xa_id == SMK_XA_OBJECT) {
nsp->smk_inode = skp;
nsp->smk_flags |= SMK_INODE_INSTANT;
return 0;
@@ -3020,7 +3068,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
sock = SOCKET_I(inode);
ssp = smack_sock(sock->sk);
- if (strcmp(name, XATTR_SMACK_IPIN) == 0)
+ if (xa_id == SMK_XA_IPIN)
ssp->smk_in = skp;
else {
ssp->smk_out = skp;
--
2.43.0
More information about the Linux-security-module-archive
mailing list