summaryrefslogtreecommitdiff
path: root/security/selinux/ss/services.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss/services.c')
-rw-r--r--security/selinux/ss/services.c58
1 files changed, 47 insertions, 11 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index e431772c6168..713130bd43c4 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1153,6 +1153,14 @@ void security_compute_av(u32 ssid,
if (ebitmap_get_bit(&policydb->permissive_map, scontext->type))
avd->flags |= AVD_FLAGS_PERMISSIVE;
+ /* neveraudit domain? */
+ if (ebitmap_get_bit(&policydb->neveraudit_map, scontext->type))
+ avd->flags |= AVD_FLAGS_NEVERAUDIT;
+
+ /* both permissive and neveraudit => allow */
+ if (avd->flags == (AVD_FLAGS_PERMISSIVE|AVD_FLAGS_NEVERAUDIT))
+ goto allow;
+
tcontext = sidtab_search(sidtab, tsid);
if (!tcontext) {
pr_err("SELinux: %s: unrecognized SID %d\n",
@@ -1172,6 +1180,8 @@ void security_compute_av(u32 ssid,
policydb->allow_unknown);
out:
rcu_read_unlock();
+ if (avd->flags & AVD_FLAGS_NEVERAUDIT)
+ avd->auditallow = avd->auditdeny = 0;
return;
allow:
avd->allowed = 0xffffffff;
@@ -1208,6 +1218,14 @@ void security_compute_av_user(u32 ssid,
if (ebitmap_get_bit(&policydb->permissive_map, scontext->type))
avd->flags |= AVD_FLAGS_PERMISSIVE;
+ /* neveraudit domain? */
+ if (ebitmap_get_bit(&policydb->neveraudit_map, scontext->type))
+ avd->flags |= AVD_FLAGS_NEVERAUDIT;
+
+ /* both permissive and neveraudit => allow */
+ if (avd->flags == (AVD_FLAGS_PERMISSIVE|AVD_FLAGS_NEVERAUDIT))
+ goto allow;
+
tcontext = sidtab_search(sidtab, tsid);
if (!tcontext) {
pr_err("SELinux: %s: unrecognized SID %d\n",
@@ -1225,6 +1243,8 @@ void security_compute_av_user(u32 ssid,
NULL);
out:
rcu_read_unlock();
+ if (avd->flags & AVD_FLAGS_NEVERAUDIT)
+ avd->auditallow = avd->auditdeny = 0;
return;
allow:
avd->allowed = 0xffffffff;
@@ -1909,11 +1929,17 @@ retry:
goto out_unlock;
}
/* Obtain the sid for the context. */
- rc = sidtab_context_to_sid(sidtab, &newcontext, out_sid);
- if (rc == -ESTALE) {
- rcu_read_unlock();
- context_destroy(&newcontext);
- goto retry;
+ if (context_equal(scontext, &newcontext))
+ *out_sid = ssid;
+ else if (context_equal(tcontext, &newcontext))
+ *out_sid = tsid;
+ else {
+ rc = sidtab_context_to_sid(sidtab, &newcontext, out_sid);
+ if (rc == -ESTALE) {
+ rcu_read_unlock();
+ context_destroy(&newcontext);
+ goto retry;
+ }
}
out_unlock:
rcu_read_unlock();
@@ -2643,7 +2669,7 @@ static bool match_ipv6_addrmask(const u32 input[4], const u32 addr[4], const u32
* @out_sid: security identifier
*/
int security_node_sid(u16 domain,
- void *addrp,
+ const void *addrp,
u32 addrlen,
u32 *out_sid)
{
@@ -2672,7 +2698,7 @@ retry:
if (addrlen != sizeof(u32))
goto out;
- addr = *((u32 *)addrp);
+ addr = *((const u32 *)addrp);
c = policydb->ocontexts[OCON_NODE];
while (c) {
@@ -2872,6 +2898,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 +2915,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)