Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 6888
b: refs/heads/master
c: 782ebb9
h: refs/heads/master
v: v3
  • Loading branch information
Stephen Smalley authored and Linus Torvalds committed Sep 5, 2005
1 parent d885bf6 commit e4c166f
Show file tree
Hide file tree
Showing 10 changed files with 401 additions and 236 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 720d6c29e146e96cca858057469951e91e0e6850
refs/heads/master: 782ebb992ec20b5afdd5786ee8c2f1b58b631f24
3 changes: 2 additions & 1 deletion trunk/security/selinux/include/security.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@
#define POLICYDB_VERSION_NLCLASS 18
#define POLICYDB_VERSION_VALIDATETRANS 19
#define POLICYDB_VERSION_MLS 19
#define POLICYDB_VERSION_AVTAB 20

/* Range of policy versions we understand*/
#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
#define POLICYDB_VERSION_MAX POLICYDB_VERSION_MLS
#define POLICYDB_VERSION_MAX POLICYDB_VERSION_AVTAB

#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM
extern int selinux_enabled;
Expand Down
192 changes: 123 additions & 69 deletions trunk/security/selinux/ss/avtab.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat
{
int hvalue;
struct avtab_node *prev, *cur, *newnode;
u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);

if (!h)
return -EINVAL;
Expand All @@ -69,7 +70,7 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat
if (key->source_type == cur->key.source_type &&
key->target_type == cur->key.target_type &&
key->target_class == cur->key.target_class &&
(datum->specified & cur->datum.specified))
(specified & cur->key.specified))
return -EEXIST;
if (key->source_type < cur->key.source_type)
break;
Expand Down Expand Up @@ -98,6 +99,7 @@ avtab_insert_nonunique(struct avtab * h, struct avtab_key * key, struct avtab_da
{
int hvalue;
struct avtab_node *prev, *cur, *newnode;
u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);

if (!h)
return NULL;
Expand All @@ -108,7 +110,7 @@ avtab_insert_nonunique(struct avtab * h, struct avtab_key * key, struct avtab_da
if (key->source_type == cur->key.source_type &&
key->target_type == cur->key.target_type &&
key->target_class == cur->key.target_class &&
(datum->specified & cur->datum.specified))
(specified & cur->key.specified))
break;
if (key->source_type < cur->key.source_type)
break;
Expand All @@ -125,10 +127,11 @@ avtab_insert_nonunique(struct avtab * h, struct avtab_key * key, struct avtab_da
return newnode;
}

struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key, int specified)
struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key)
{
int hvalue;
struct avtab_node *cur;
u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);

if (!h)
return NULL;
Expand All @@ -138,7 +141,7 @@ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key, int spe
if (key->source_type == cur->key.source_type &&
key->target_type == cur->key.target_type &&
key->target_class == cur->key.target_class &&
(specified & cur->datum.specified))
(specified & cur->key.specified))
return &cur->datum;

if (key->source_type < cur->key.source_type)
Expand All @@ -159,10 +162,11 @@ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key, int spe
* conjunction with avtab_search_next_node()
*/
struct avtab_node*
avtab_search_node(struct avtab *h, struct avtab_key *key, int specified)
avtab_search_node(struct avtab *h, struct avtab_key *key)
{
int hvalue;
struct avtab_node *cur;
u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);

if (!h)
return NULL;
Expand All @@ -172,7 +176,7 @@ avtab_search_node(struct avtab *h, struct avtab_key *key, int specified)
if (key->source_type == cur->key.source_type &&
key->target_type == cur->key.target_type &&
key->target_class == cur->key.target_class &&
(specified & cur->datum.specified))
(specified & cur->key.specified))
return cur;

if (key->source_type < cur->key.source_type)
Expand All @@ -196,11 +200,12 @@ avtab_search_node_next(struct avtab_node *node, int specified)
if (!node)
return NULL;

specified &= ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
for (cur = node->next; cur; cur = cur->next) {
if (node->key.source_type == cur->key.source_type &&
node->key.target_type == cur->key.target_type &&
node->key.target_class == cur->key.target_class &&
(specified & cur->datum.specified))
(specified & cur->key.specified))
return cur;

if (node->key.source_type < cur->key.source_type)
Expand Down Expand Up @@ -278,75 +283,126 @@ void avtab_hash_eval(struct avtab *h, char *tag)
max_chain_len);
}

int avtab_read_item(void *fp, struct avtab_datum *avdatum, struct avtab_key *avkey)
static uint16_t spec_order[] = {
AVTAB_ALLOWED,
AVTAB_AUDITDENY,
AVTAB_AUDITALLOW,
AVTAB_TRANSITION,
AVTAB_CHANGE,
AVTAB_MEMBER
};

int avtab_read_item(void *fp, u32 vers, struct avtab *a,
int (*insertf)(struct avtab *a, struct avtab_key *k,
struct avtab_datum *d, void *p),
void *p)
{
u32 buf[7];
u32 items, items2;
int rc;
u16 buf16[4], enabled;
u32 buf32[7], items, items2, val;
struct avtab_key key;
struct avtab_datum datum;
int i, rc;

memset(&key, 0, sizeof(struct avtab_key));
memset(&datum, 0, sizeof(struct avtab_datum));

if (vers < POLICYDB_VERSION_AVTAB) {
rc = next_entry(buf32, fp, sizeof(u32));
if (rc < 0) {
printk(KERN_ERR "security: avtab: truncated entry\n");
return -1;
}
items2 = le32_to_cpu(buf32[0]);
if (items2 > ARRAY_SIZE(buf32)) {
printk(KERN_ERR "security: avtab: entry overflow\n");
return -1;

memset(avkey, 0, sizeof(struct avtab_key));
memset(avdatum, 0, sizeof(struct avtab_datum));
}
rc = next_entry(buf32, fp, sizeof(u32)*items2);
if (rc < 0) {
printk(KERN_ERR "security: avtab: truncated entry\n");
return -1;
}
items = 0;

rc = next_entry(buf, fp, sizeof(u32));
if (rc < 0) {
printk(KERN_ERR "security: avtab: truncated entry\n");
goto bad;
}
items2 = le32_to_cpu(buf[0]);
if (items2 > ARRAY_SIZE(buf)) {
printk(KERN_ERR "security: avtab: entry overflow\n");
goto bad;
val = le32_to_cpu(buf32[items++]);
key.source_type = (u16)val;
if (key.source_type != val) {
printk("security: avtab: truncated source type\n");
return -1;
}
val = le32_to_cpu(buf32[items++]);
key.target_type = (u16)val;
if (key.target_type != val) {
printk("security: avtab: truncated target type\n");
return -1;
}
val = le32_to_cpu(buf32[items++]);
key.target_class = (u16)val;
if (key.target_class != val) {
printk("security: avtab: truncated target class\n");
return -1;
}

val = le32_to_cpu(buf32[items++]);
enabled = (val & AVTAB_ENABLED_OLD) ? AVTAB_ENABLED : 0;

if (!(val & (AVTAB_AV | AVTAB_TYPE))) {
printk("security: avtab: null entry\n");
return -1;
}
if ((val & AVTAB_AV) &&
(val & AVTAB_TYPE)) {
printk("security: avtab: entry has both access vectors and types\n");
return -1;
}

for (i = 0; i < sizeof(spec_order)/sizeof(u16); i++) {
if (val & spec_order[i]) {
key.specified = spec_order[i] | enabled;
datum.data = le32_to_cpu(buf32[items++]);
rc = insertf(a, &key, &datum, p);
if (rc) return rc;
}
}

if (items != items2) {
printk("security: avtab: entry only had %d items, expected %d\n", items2, items);
return -1;
}
return 0;
}
rc = next_entry(buf, fp, sizeof(u32)*items2);

rc = next_entry(buf16, fp, sizeof(u16)*4);
if (rc < 0) {
printk(KERN_ERR "security: avtab: truncated entry\n");
goto bad;
printk("security: avtab: truncated entry\n");
return -1;
}

items = 0;
avkey->source_type = le32_to_cpu(buf[items++]);
avkey->target_type = le32_to_cpu(buf[items++]);
avkey->target_class = le32_to_cpu(buf[items++]);
avdatum->specified = le32_to_cpu(buf[items++]);
if (!(avdatum->specified & (AVTAB_AV | AVTAB_TYPE))) {
printk(KERN_ERR "security: avtab: null entry\n");
goto bad;
}
if ((avdatum->specified & AVTAB_AV) &&
(avdatum->specified & AVTAB_TYPE)) {
printk(KERN_ERR "security: avtab: entry has both access vectors and types\n");
goto bad;
}
if (avdatum->specified & AVTAB_AV) {
if (avdatum->specified & AVTAB_ALLOWED)
avtab_allowed(avdatum) = le32_to_cpu(buf[items++]);
if (avdatum->specified & AVTAB_AUDITDENY)
avtab_auditdeny(avdatum) = le32_to_cpu(buf[items++]);
if (avdatum->specified & AVTAB_AUDITALLOW)
avtab_auditallow(avdatum) = le32_to_cpu(buf[items++]);
} else {
if (avdatum->specified & AVTAB_TRANSITION)
avtab_transition(avdatum) = le32_to_cpu(buf[items++]);
if (avdatum->specified & AVTAB_CHANGE)
avtab_change(avdatum) = le32_to_cpu(buf[items++]);
if (avdatum->specified & AVTAB_MEMBER)
avtab_member(avdatum) = le32_to_cpu(buf[items++]);
}
if (items != items2) {
printk(KERN_ERR "security: avtab: entry only had %d items, expected %d\n",
items2, items);
goto bad;
key.source_type = le16_to_cpu(buf16[items++]);
key.target_type = le16_to_cpu(buf16[items++]);
key.target_class = le16_to_cpu(buf16[items++]);
key.specified = le16_to_cpu(buf16[items++]);

rc = next_entry(buf32, fp, sizeof(u32));
if (rc < 0) {
printk("security: avtab: truncated entry\n");
return -1;
}
datum.data = le32_to_cpu(*buf32);
return insertf(a, &key, &datum, p);
}

return 0;
bad:
return -1;
static int avtab_insertf(struct avtab *a, struct avtab_key *k,
struct avtab_datum *d, void *p)
{
return avtab_insert(a, k, d);
}

int avtab_read(struct avtab *a, void *fp, u32 config)
int avtab_read(struct avtab *a, void *fp, u32 vers)
{
int rc;
struct avtab_key avkey;
struct avtab_datum avdatum;
u32 buf[1];
u32 nel, i;

Expand All @@ -363,16 +419,14 @@ int avtab_read(struct avtab *a, void *fp, u32 config)
goto bad;
}
for (i = 0; i < nel; i++) {
if (avtab_read_item(fp, &avdatum, &avkey)) {
rc = -EINVAL;
goto bad;
}
rc = avtab_insert(a, &avkey, &avdatum);
rc = avtab_read_item(fp,vers, a, avtab_insertf, NULL);
if (rc) {
if (rc == -ENOMEM)
printk(KERN_ERR "security: avtab: out of memory\n");
if (rc == -EEXIST)
else if (rc == -EEXIST)
printk(KERN_ERR "security: avtab: duplicate entry\n");
else
rc = -EINVAL;
goto bad;
}
}
Expand Down
37 changes: 18 additions & 19 deletions trunk/security/selinux/ss/avtab.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,9 @@
#define _SS_AVTAB_H_

struct avtab_key {
u32 source_type; /* source type */
u32 target_type; /* target type */
u32 target_class; /* target object class */
};

struct avtab_datum {
u16 source_type; /* source type */
u16 target_type; /* target type */
u16 target_class; /* target object class */
#define AVTAB_ALLOWED 1
#define AVTAB_AUDITALLOW 2
#define AVTAB_AUDITDENY 4
Expand All @@ -35,15 +32,13 @@ struct avtab_datum {
#define AVTAB_MEMBER 32
#define AVTAB_CHANGE 64
#define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE)
#define AVTAB_ENABLED 0x80000000 /* reserved for used in cond_avtab */
u32 specified; /* what fields are specified */
u32 data[3]; /* access vectors or types */
#define avtab_allowed(x) (x)->data[0]
#define avtab_auditdeny(x) (x)->data[1]
#define avtab_auditallow(x) (x)->data[2]
#define avtab_transition(x) (x)->data[0]
#define avtab_change(x) (x)->data[1]
#define avtab_member(x) (x)->data[2]
#define AVTAB_ENABLED_OLD 0x80000000 /* reserved for used in cond_avtab */
#define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */
u16 specified; /* what field is specified */
};

struct avtab_datum {
u32 data; /* access vector or type value */
};

struct avtab_node {
Expand All @@ -58,17 +53,21 @@ struct avtab {
};

int avtab_init(struct avtab *);
struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *k, int specified);
struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *k);
void avtab_destroy(struct avtab *h);
void avtab_hash_eval(struct avtab *h, char *tag);

int avtab_read_item(void *fp, struct avtab_datum *avdatum, struct avtab_key *avkey);
int avtab_read(struct avtab *a, void *fp, u32 config);
int avtab_read_item(void *fp, uint32_t vers, struct avtab *a,
int (*insert)(struct avtab *a, struct avtab_key *k,
struct avtab_datum *d, void *p),
void *p);

int avtab_read(struct avtab *a, void *fp, u32 vers);

struct avtab_node *avtab_insert_nonunique(struct avtab *h, struct avtab_key *key,
struct avtab_datum *datum);

struct avtab_node *avtab_search_node(struct avtab *h, struct avtab_key *key, int specified);
struct avtab_node *avtab_search_node(struct avtab *h, struct avtab_key *key);

struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified);

Expand Down
Loading

0 comments on commit e4c166f

Please sign in to comment.