Merge git://git.infradead.org/users/eparis/selinux
Conflicts: security/selinux/hooks.c Pull Eric's existing SELinux tree as there are a number of patches in there that are not yet upstream. There was some minor fixup needed to resolve a conflict in security/selinux/hooks.c:selinux_set_mnt_opts() between the labeled NFS patches and Eric's security_fs_use() simplification patch.
This commit is contained in:
@@ -213,7 +213,12 @@ netlbl_import_failure:
|
||||
}
|
||||
#endif /* CONFIG_NETLABEL */
|
||||
|
||||
int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2)
|
||||
/*
|
||||
* Check to see if all the bits set in e2 are also set in e1. Optionally,
|
||||
* if last_e2bit is non-zero, the highest set bit in e2 cannot exceed
|
||||
* last_e2bit.
|
||||
*/
|
||||
int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2, u32 last_e2bit)
|
||||
{
|
||||
struct ebitmap_node *n1, *n2;
|
||||
int i;
|
||||
@@ -223,14 +228,25 @@ int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2)
|
||||
|
||||
n1 = e1->node;
|
||||
n2 = e2->node;
|
||||
|
||||
while (n1 && n2 && (n1->startbit <= n2->startbit)) {
|
||||
if (n1->startbit < n2->startbit) {
|
||||
n1 = n1->next;
|
||||
continue;
|
||||
}
|
||||
for (i = 0; i < EBITMAP_UNIT_NUMS; i++) {
|
||||
for (i = EBITMAP_UNIT_NUMS - 1; (i >= 0) && !n2->maps[i]; )
|
||||
i--; /* Skip trailing NULL map entries */
|
||||
if (last_e2bit && (i >= 0)) {
|
||||
u32 lastsetbit = n2->startbit + i * EBITMAP_UNIT_SIZE +
|
||||
__fls(n2->maps[i]);
|
||||
if (lastsetbit > last_e2bit)
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (i >= 0) {
|
||||
if ((n1->maps[i] & n2->maps[i]) != n2->maps[i])
|
||||
return 0;
|
||||
i--;
|
||||
}
|
||||
|
||||
n1 = n1->next;
|
||||
|
@@ -16,7 +16,13 @@
|
||||
|
||||
#include <net/netlabel.h>
|
||||
|
||||
#define EBITMAP_UNIT_NUMS ((32 - sizeof(void *) - sizeof(u32)) \
|
||||
#ifdef CONFIG_64BIT
|
||||
#define EBITMAP_NODE_SIZE 64
|
||||
#else
|
||||
#define EBITMAP_NODE_SIZE 32
|
||||
#endif
|
||||
|
||||
#define EBITMAP_UNIT_NUMS ((EBITMAP_NODE_SIZE-sizeof(void *)-sizeof(u32))\
|
||||
/ sizeof(unsigned long))
|
||||
#define EBITMAP_UNIT_SIZE BITS_PER_LONG
|
||||
#define EBITMAP_SIZE (EBITMAP_UNIT_NUMS * EBITMAP_UNIT_SIZE)
|
||||
@@ -117,7 +123,7 @@ static inline void ebitmap_node_clr_bit(struct ebitmap_node *n,
|
||||
|
||||
int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2);
|
||||
int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src);
|
||||
int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2);
|
||||
int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2, u32 last_e2bit);
|
||||
int ebitmap_get_bit(struct ebitmap *e, unsigned long bit);
|
||||
int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value);
|
||||
void ebitmap_destroy(struct ebitmap *e);
|
||||
|
@@ -160,8 +160,6 @@ void mls_sid_to_context(struct context *context,
|
||||
int mls_level_isvalid(struct policydb *p, struct mls_level *l)
|
||||
{
|
||||
struct level_datum *levdatum;
|
||||
struct ebitmap_node *node;
|
||||
int i;
|
||||
|
||||
if (!l->sens || l->sens > p->p_levels.nprim)
|
||||
return 0;
|
||||
@@ -170,19 +168,13 @@ int mls_level_isvalid(struct policydb *p, struct mls_level *l)
|
||||
if (!levdatum)
|
||||
return 0;
|
||||
|
||||
ebitmap_for_each_positive_bit(&l->cat, node, i) {
|
||||
if (i > p->p_cats.nprim)
|
||||
return 0;
|
||||
if (!ebitmap_get_bit(&levdatum->level->cat, i)) {
|
||||
/*
|
||||
* Category may not be associated with
|
||||
* sensitivity.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
/*
|
||||
* Return 1 iff all the bits set in l->cat are also be set in
|
||||
* levdatum->level->cat and no bit in l->cat is larger than
|
||||
* p->p_cats.nprim.
|
||||
*/
|
||||
return ebitmap_contains(&levdatum->level->cat, &l->cat,
|
||||
p->p_cats.nprim);
|
||||
}
|
||||
|
||||
int mls_range_isvalid(struct policydb *p, struct mls_range *r)
|
||||
|
@@ -35,7 +35,7 @@ static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2)
|
||||
static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2)
|
||||
{
|
||||
return ((l1->sens >= l2->sens) &&
|
||||
ebitmap_contains(&l1->cat, &l2->cat));
|
||||
ebitmap_contains(&l1->cat, &l2->cat, 0));
|
||||
}
|
||||
|
||||
#define mls_level_incomp(l1, l2) \
|
||||
|
@@ -3203,9 +3203,8 @@ static int range_write_helper(void *key, void *data, void *ptr)
|
||||
|
||||
static int range_write(struct policydb *p, void *fp)
|
||||
{
|
||||
size_t nel;
|
||||
__le32 buf[1];
|
||||
int rc;
|
||||
int rc, nel;
|
||||
struct policy_data pd;
|
||||
|
||||
pd.p = p;
|
||||
|
@@ -72,6 +72,7 @@
|
||||
|
||||
int selinux_policycap_netpeer;
|
||||
int selinux_policycap_openperm;
|
||||
int selinux_policycap_alwaysnetwork;
|
||||
|
||||
static DEFINE_RWLOCK(policy_rwlock);
|
||||
|
||||
@@ -1812,6 +1813,8 @@ static void security_load_policycaps(void)
|
||||
POLICYDB_CAPABILITY_NETPEER);
|
||||
selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps,
|
||||
POLICYDB_CAPABILITY_OPENPERM);
|
||||
selinux_policycap_alwaysnetwork = ebitmap_get_bit(&policydb.policycaps,
|
||||
POLICYDB_CAPABILITY_ALWAYSNETWORK);
|
||||
}
|
||||
|
||||
static int security_preserve_bools(struct policydb *p);
|
||||
@@ -2323,43 +2326,74 @@ out:
|
||||
|
||||
/**
|
||||
* security_fs_use - Determine how to handle labeling for a filesystem.
|
||||
* @fstype: filesystem type
|
||||
* @behavior: labeling behavior
|
||||
* @sid: SID for filesystem (superblock)
|
||||
* @sb: superblock in question
|
||||
*/
|
||||
int security_fs_use(
|
||||
const char *fstype,
|
||||
unsigned int *behavior,
|
||||
u32 *sid)
|
||||
int security_fs_use(struct super_block *sb)
|
||||
{
|
||||
int rc = 0;
|
||||
struct ocontext *c;
|
||||
struct superblock_security_struct *sbsec = sb->s_security;
|
||||
const char *fstype = sb->s_type->name;
|
||||
const char *subtype = (sb->s_subtype && sb->s_subtype[0]) ? sb->s_subtype : NULL;
|
||||
struct ocontext *base = NULL;
|
||||
|
||||
read_lock(&policy_rwlock);
|
||||
|
||||
c = policydb.ocontexts[OCON_FSUSE];
|
||||
while (c) {
|
||||
if (strcmp(fstype, c->u.name) == 0)
|
||||
for (c = policydb.ocontexts[OCON_FSUSE]; c; c = c->next) {
|
||||
char *sub;
|
||||
int baselen;
|
||||
|
||||
baselen = strlen(fstype);
|
||||
|
||||
/* if base does not match, this is not the one */
|
||||
if (strncmp(fstype, c->u.name, baselen))
|
||||
continue;
|
||||
|
||||
/* if there is no subtype, this is the one! */
|
||||
if (!subtype)
|
||||
break;
|
||||
|
||||
/* skip past the base in this entry */
|
||||
sub = c->u.name + baselen;
|
||||
|
||||
/* entry is only a base. save it. keep looking for subtype */
|
||||
if (sub[0] == '\0') {
|
||||
base = c;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* entry is not followed by a subtype, so it is not a match */
|
||||
if (sub[0] != '.')
|
||||
continue;
|
||||
|
||||
/* whew, we found a subtype of this fstype */
|
||||
sub++; /* move past '.' */
|
||||
|
||||
/* exact match of fstype AND subtype */
|
||||
if (!strcmp(subtype, sub))
|
||||
break;
|
||||
c = c->next;
|
||||
}
|
||||
|
||||
/* in case we had found an fstype match but no subtype match */
|
||||
if (!c)
|
||||
c = base;
|
||||
|
||||
if (c) {
|
||||
*behavior = c->v.behavior;
|
||||
sbsec->behavior = c->v.behavior;
|
||||
if (!c->sid[0]) {
|
||||
rc = sidtab_context_to_sid(&sidtab, &c->context[0],
|
||||
&c->sid[0]);
|
||||
if (rc)
|
||||
goto out;
|
||||
}
|
||||
*sid = c->sid[0];
|
||||
sbsec->sid = c->sid[0];
|
||||
} else {
|
||||
rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid);
|
||||
rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, &sbsec->sid);
|
||||
if (rc) {
|
||||
*behavior = SECURITY_FS_USE_NONE;
|
||||
sbsec->behavior = SECURITY_FS_USE_NONE;
|
||||
rc = 0;
|
||||
} else {
|
||||
*behavior = SECURITY_FS_USE_GENFS;
|
||||
sbsec->behavior = SECURITY_FS_USE_GENFS;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user