diff options
-rw-r--r-- | security/selinux/include/policycap.h | 1 | ||||
-rw-r--r-- | security/selinux/include/policycap_names.h | 1 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 19 |
3 files changed, 17 insertions, 4 deletions
diff --git a/security/selinux/include/policycap.h b/security/selinux/include/policycap.h index bd402d3fd3ae..7405154e6c42 100644 --- a/security/selinux/include/policycap.h +++ b/security/selinux/include/policycap.h @@ -16,6 +16,7 @@ enum { POLICYDB_CAP_USERSPACE_INITIAL_CONTEXT, POLICYDB_CAP_NETLINK_XPERM, POLICYDB_CAP_NETIF_WILDCARD, + POLICYDB_CAP_GENFS_SECLABEL_WILDCARD, __POLICYDB_CAP_MAX }; #define POLICYDB_CAP_MAX (__POLICYDB_CAP_MAX - 1) diff --git a/security/selinux/include/policycap_names.h b/security/selinux/include/policycap_names.h index ac1342d6d5bb..d8962fcf2ff9 100644 --- a/security/selinux/include/policycap_names.h +++ b/security/selinux/include/policycap_names.h @@ -19,6 +19,7 @@ const char *const selinux_policycap_names[__POLICYDB_CAP_MAX] = { "userspace_initial_context", "netlink_xperm", "netif_wildcard", + "genfs_seclabel_wildcard", }; /* clang-format on */ diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index ec9ddfccc7ee..5309bb885576 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -49,6 +49,7 @@ #include <linux/parser.h> #include <linux/vmalloc.h> #include <linux/lsm_hooks.h> +#include <linux/parser.h> #include <net/netlabel.h> #include "flask.h" @@ -2872,6 +2873,7 @@ static inline int __security_genfs_sid(struct selinux_policy *policy, struct genfs *genfs; struct ocontext *c; int cmp = 0; + bool wildcard; while (path[0] == '/' && path[1] == '/') path++; @@ -2888,11 +2890,20 @@ static inline int __security_genfs_sid(struct selinux_policy *policy, if (!genfs || cmp) return -ENOENT; + wildcard = ebitmap_get_bit(&policy->policydb.policycaps, + POLICYDB_CAP_GENFS_SECLABEL_WILDCARD); for (c = genfs->head; c; c = c->next) { - size_t len = strlen(c->u.name); - if ((!c->v.sclass || sclass == c->v.sclass) && - (strncmp(c->u.name, path, len) == 0)) - break; + if (!c->v.sclass || sclass == c->v.sclass) { + if (wildcard) { + if (match_wildcard(c->u.name, path)) + break; + } else { + size_t len = strlen(c->u.name); + + if ((strncmp(c->u.name, path, len)) == 0) + break; + } + } } if (!c) |