Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 250801
b: refs/heads/master
c: 2463c26
h: refs/heads/master
i:
  250799: 3c47e9e
v: v3
  • Loading branch information
Eric Paris committed Apr 28, 2011
1 parent b56ac20 commit f86b8df
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 62 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: 3f058ef7787e1b48720622346de9a5317aeb749a
refs/heads/master: 2463c26d50adc282d19317013ba0ff473823ca47
167 changes: 119 additions & 48 deletions trunk/security/selinux/ss/policydb.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,43 @@ static int roles_init(struct policydb *p)
return rc;
}

static u32 filenametr_hash(struct hashtab *h, const void *k)
{
const struct filename_trans *ft = k;
unsigned long hash;
unsigned int byte_num;
unsigned char focus;

hash = ft->stype ^ ft->ttype ^ ft->tclass;

byte_num = 0;
while ((focus = ft->name[byte_num++]))
hash = partial_name_hash(focus, hash);
return hash & (h->size - 1);
}

static int filenametr_cmp(struct hashtab *h, const void *k1, const void *k2)
{
const struct filename_trans *ft1 = k1;
const struct filename_trans *ft2 = k2;
int v;

v = ft1->stype - ft2->stype;
if (v)
return v;

v = ft1->ttype - ft2->ttype;
if (v)
return v;

v = ft1->tclass - ft2->tclass;
if (v)
return v;

return strcmp(ft1->name, ft2->name);

}

static u32 rangetr_hash(struct hashtab *h, const void *k)
{
const struct range_trans *key = k;
Expand Down Expand Up @@ -236,6 +273,10 @@ static int policydb_init(struct policydb *p)
if (rc)
goto out;

p->filename_trans = hashtab_create(filenametr_hash, filenametr_cmp, (1 << 10));
if (!p->filename_trans)
goto out;

p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256);
if (!p->range_tr)
goto out;
Expand All @@ -246,6 +287,8 @@ static int policydb_init(struct policydb *p)

return 0;
out:
hashtab_destroy(p->filename_trans);
hashtab_destroy(p->range_tr);
for (i = 0; i < SYM_NUM; i++)
hashtab_destroy(p->symtab[i].table);
return rc;
Expand Down Expand Up @@ -675,6 +718,16 @@ static int (*destroy_f[SYM_NUM]) (void *key, void *datum, void *datap) =
cat_destroy,
};

static int filenametr_destroy(void *key, void *datum, void *p)
{
struct filename_trans *ft = key;
kfree(ft->name);
kfree(key);
kfree(datum);
cond_resched();
return 0;
}

static int range_tr_destroy(void *key, void *datum, void *p)
{
struct mls_range *rt = datum;
Expand Down Expand Up @@ -709,7 +762,6 @@ void policydb_destroy(struct policydb *p)
int i;
struct role_allow *ra, *lra = NULL;
struct role_trans *tr, *ltr = NULL;
struct filename_trans *ft, *nft;

for (i = 0; i < SYM_NUM; i++) {
cond_resched();
Expand Down Expand Up @@ -773,6 +825,9 @@ void policydb_destroy(struct policydb *p)
}
kfree(lra);

hashtab_map(p->filename_trans, filenametr_destroy, NULL);
hashtab_destroy(p->filename_trans);

hashtab_map(p->range_tr, range_tr_destroy, NULL);
hashtab_destroy(p->range_tr);

Expand All @@ -788,14 +843,6 @@ void policydb_destroy(struct policydb *p)
flex_array_free(p->type_attr_map_array);
}

ft = p->filename_trans;
while (ft) {
nft = ft->next;
kfree(ft->name);
kfree(ft);
ft = nft;
}

ebitmap_destroy(&p->filename_trans_ttypes);
ebitmap_destroy(&p->policycaps);
ebitmap_destroy(&p->permissive_map);
Expand Down Expand Up @@ -1806,9 +1853,10 @@ static int range_read(struct policydb *p, void *fp)

static int filename_trans_read(struct policydb *p, void *fp)
{
struct filename_trans *ft, *last;
u32 nel, len;
struct filename_trans *ft;
struct filename_trans_datum *otype;
char *name;
u32 nel, len;
__le32 buf[4];
int rc, i;

Expand All @@ -1817,25 +1865,23 @@ static int filename_trans_read(struct policydb *p, void *fp)

rc = next_entry(buf, fp, sizeof(u32));
if (rc)
goto out;
return rc;
nel = le32_to_cpu(buf[0]);

last = p->filename_trans;
while (last && last->next)
last = last->next;

for (i = 0; i < nel; i++) {
ft = NULL;
otype = NULL;
name = NULL;

rc = -ENOMEM;
ft = kzalloc(sizeof(*ft), GFP_KERNEL);
if (!ft)
goto out;

/* add it to the tail of the list */
if (!last)
p->filename_trans = ft;
else
last->next = ft;
last = ft;
rc = -ENOMEM;
otype = kmalloc(sizeof(*otype), GFP_KERNEL);
if (!otype)
goto out;

/* length of the path component string */
rc = next_entry(buf, fp, sizeof(u32));
Expand Down Expand Up @@ -1863,14 +1909,22 @@ static int filename_trans_read(struct policydb *p, void *fp)
ft->stype = le32_to_cpu(buf[0]);
ft->ttype = le32_to_cpu(buf[1]);
ft->tclass = le32_to_cpu(buf[2]);
ft->otype = le32_to_cpu(buf[3]);

otype->otype = le32_to_cpu(buf[3]);

rc = ebitmap_set_bit(&p->filename_trans_ttypes, ft->ttype, 1);
if (rc)
goto out;

hashtab_insert(p->filename_trans, ft, otype);
}
rc = 0;
hash_eval(p->filename_trans, "filenametr");
return 0;
out:
kfree(ft);
kfree(name);
kfree(otype);

return rc;
}

Expand Down Expand Up @@ -3131,43 +3185,60 @@ static int range_write(struct policydb *p, void *fp)
return 0;
}

static int filename_trans_write(struct policydb *p, void *fp)
static int filename_write_helper(void *key, void *data, void *ptr)
{
struct filename_trans *ft;
u32 len, nel = 0;
__le32 buf[4];
struct filename_trans *ft = key;
struct filename_trans_datum *otype = data;
void *fp = ptr;
int rc;
u32 len;

for (ft = p->filename_trans; ft; ft = ft->next)
nel++;

buf[0] = cpu_to_le32(nel);
len = strlen(ft->name);
buf[0] = cpu_to_le32(len);
rc = put_entry(buf, sizeof(u32), 1, fp);
if (rc)
return rc;

for (ft = p->filename_trans; ft; ft = ft->next) {
len = strlen(ft->name);
buf[0] = cpu_to_le32(len);
rc = put_entry(buf, sizeof(u32), 1, fp);
if (rc)
return rc;
rc = put_entry(ft->name, sizeof(char), len, fp);
if (rc)
return rc;

rc = put_entry(ft->name, sizeof(char), len, fp);
if (rc)
return rc;
buf[0] = ft->stype;
buf[1] = ft->ttype;
buf[2] = ft->tclass;
buf[3] = otype->otype;

buf[0] = ft->stype;
buf[1] = ft->ttype;
buf[2] = ft->tclass;
buf[3] = ft->otype;
rc = put_entry(buf, sizeof(u32), 4, fp);
if (rc)
return rc;

rc = put_entry(buf, sizeof(u32), 4, fp);
if (rc)
return rc;
}
return 0;
}

static int filename_trans_write(struct policydb *p, void *fp)
{
u32 nel;
__le32 buf[1];
int rc;

nel = 0;
rc = hashtab_map(p->filename_trans, hashtab_cnt, &nel);
if (rc)
return rc;

buf[0] = cpu_to_le32(nel);
rc = put_entry(buf, sizeof(u32), 1, fp);
if (rc)
return rc;

rc = hashtab_map(p->filename_trans, filename_write_helper, fp);
if (rc)
return rc;

return 0;
}

/*
* Write the configuration data in a policy database
* structure to a policy database binary representation
Expand Down
9 changes: 6 additions & 3 deletions trunk/security/selinux/ss/policydb.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,13 @@ struct role_trans {
};

struct filename_trans {
struct filename_trans *next;
u32 stype; /* current process */
u32 ttype; /* parent dir context */
u16 tclass; /* class of new object */
const char *name; /* last path component */
};

struct filename_trans_datum {
u32 otype; /* expected of new object */
};

Expand Down Expand Up @@ -227,10 +229,11 @@ struct policydb {
/* role transitions */
struct role_trans *role_tr;

/* file transitions with the last path component */
/* quickly exclude lookups when parent ttype has no rules */
struct ebitmap filename_trans_ttypes;
/* file transitions with the last path component */
struct filename_trans *filename_trans;
/* actual set of filename_trans rules */
struct hashtab *filename_trans;

/* bools indexed by (value - 1) */
struct cond_bool_datum **bool_val_to_struct;
Expand Down
20 changes: 10 additions & 10 deletions trunk/security/selinux/ss/services.c
Original file line number Diff line number Diff line change
Expand Up @@ -1362,7 +1362,8 @@ static void filename_compute_type(struct policydb *p, struct context *newcontext
u32 stype, u32 ttype, u16 tclass,
const char *objname)
{
struct filename_trans *ft;
struct filename_trans ft;
struct filename_trans_datum *otype;

/*
* Most filename trans rules are going to live in specific directories
Expand All @@ -1372,15 +1373,14 @@ static void filename_compute_type(struct policydb *p, struct context *newcontext
if (!ebitmap_get_bit(&p->filename_trans_ttypes, ttype))
return;

for (ft = p->filename_trans; ft; ft = ft->next) {
if (ft->stype == stype &&
ft->ttype == ttype &&
ft->tclass == tclass &&
!strcmp(ft->name, objname)) {
newcontext->type = ft->otype;
return;
}
}
ft.stype = stype;
ft.ttype = ttype;
ft.tclass = tclass;
ft.name = objname;

otype = hashtab_search(p->filename_trans, &ft);
if (otype)
newcontext->type = otype->otype;
}

static int security_compute_sid(u32 ssid,
Expand Down

0 comments on commit f86b8df

Please sign in to comment.