static DEFINE_RWLOCK(policy_rwlock);
-static DEFINE_MUTEX(load_mutex);
-#define LOAD_LOCK mutex_lock(&load_mutex)
-#define LOAD_UNLOCK mutex_unlock(&load_mutex)
-
static struct sidtab sidtab;
struct policydb policydb;
int ss_initialized;
goto inval_class;
if (unlikely(tclass > policydb.p_classes.nprim))
if (tclass > kdefs->cts_len ||
- !kdefs->class_to_string[tclass - 1] ||
+ !kdefs->class_to_string[tclass] ||
!policydb.allow_unknown)
goto inval_class;
return 0;
inval_class:
- printk(KERN_ERR "SELinux: %s: unrecognized class %d\n", __func__,
- tclass);
- return -EINVAL;
+ if (!tclass || tclass > kdefs->cts_len ||
+ !kdefs->class_to_string[tclass]) {
+ if (printk_ratelimit())
+ printk(KERN_ERR "SELinux: %s: unrecognized class %d\n",
+ __func__, tclass);
+ return -EINVAL;
+ }
+
+ /*
+ * Known to the kernel, but not to the policy.
+ * Handle as a denial (allowed is 0).
+ */
+ return 0;
}
/*
const struct selinux_class_perm *kdefs = &selinux_class_perm;
const char *def_class, *def_perm, *pol_class;
struct symtab *perms;
+ bool print_unknown_handle = 0;
if (p->allow_unknown) {
u32 num_classes = kdefs->cts_len;
return -EINVAL;
if (p->allow_unknown)
p->undefined_perms[i-1] = ~0U;
+ print_unknown_handle = 1;
continue;
}
pol_class = p->p_class_val_to_name[i-1];
return -EINVAL;
if (p->allow_unknown)
p->undefined_perms[class_val-1] |= perm_val;
+ print_unknown_handle = 1;
continue;
}
perdatum = hashtab_search(perms->table, def_perm);
return -EINVAL;
if (p->allow_unknown)
p->undefined_perms[class_val-1] |= (1 << j);
+ print_unknown_handle = 1;
continue;
}
perdatum = hashtab_search(perms->table, def_perm);
}
}
}
+ if (print_unknown_handle)
+ printk(KERN_INFO "SELinux: the above unknown classes and permissions will be %s\n",
+ (security_get_allow_unknown() ? "allowed" : "denied"));
return 0;
}
int rc = 0;
struct policy_file file = { data, len }, *fp = &file;
- LOAD_LOCK;
-
if (!ss_initialized) {
avtab_cache_init();
if (policydb_read(&policydb, fp)) {
- LOAD_UNLOCK;
avtab_cache_destroy();
return -EINVAL;
}
if (policydb_load_isids(&policydb, &sidtab)) {
- LOAD_UNLOCK;
policydb_destroy(&policydb);
avtab_cache_destroy();
return -EINVAL;
if (validate_classes(&policydb)) {
printk(KERN_ERR
"SELinux: the definition of a class is incorrect\n");
- LOAD_UNLOCK;
sidtab_destroy(&sidtab);
policydb_destroy(&policydb);
avtab_cache_destroy();
policydb_loaded_version = policydb.policyvers;
ss_initialized = 1;
seqno = ++latest_granting;
- LOAD_UNLOCK;
selinux_complete_init();
avc_ss_reset(seqno);
selnl_notify_policyload(seqno);
sidtab_hash_eval(&sidtab, "sids");
#endif
- if (policydb_read(&newpolicydb, fp)) {
- LOAD_UNLOCK;
+ if (policydb_read(&newpolicydb, fp))
return -EINVAL;
- }
if (sidtab_init(&newsidtab)) {
- LOAD_UNLOCK;
policydb_destroy(&newpolicydb);
return -ENOMEM;
}
seqno = ++latest_granting;
policydb_loaded_version = policydb.policyvers;
write_unlock_irq(&policy_rwlock);
- LOAD_UNLOCK;
/* Free the old policydb and SID table. */
policydb_destroy(&oldpolicydb);
return 0;
err:
- LOAD_UNLOCK;
sidtab_destroy(&newsidtab);
policydb_destroy(&newpolicydb);
return rc;
int security_fs_use(
const char *fstype,
unsigned int *behavior,
- u32 *sid)
+ u32 *sid,
+ bool can_xattr)
{
int rc = 0;
struct ocontext *c;
c = c->next;
}
+ /* look for labeling behavior defined in policy */
if (c) {
*behavior = c->v.behavior;
if (!c->sid[0]) {
goto out;
}
*sid = c->sid[0];
+ goto out;
+ }
+
+ /* labeling behavior not in policy, use xattrs if possible */
+ if (can_xattr) {
+ *behavior = SECURITY_FS_USE_XATTR;
+ *sid = SECINITSID_FS;
+ goto out;
+ }
+
+ /* no behavior in policy and can't use xattrs, try GENFS */
+ rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid);
+ if (rc) {
+ *behavior = SECURITY_FS_USE_NONE;
+ rc = 0;
} else {
- rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid);
- if (rc) {
- *behavior = SECURITY_FS_USE_NONE;
- rc = 0;
- } else {
- *behavior = SECURITY_FS_USE_GENFS;
- }
+ *behavior = SECURITY_FS_USE_GENFS;
}
out: