Commit 9398c7f7 authored by Eric Paris's avatar Eric Paris

SELinux: standardize return code handling in policydb.c

policydb.c has lots of different standards on how to handle return paths on
error.  For the most part transition to

	rc=errno
	if (failure)
		goto out;
[...]
out:
	cleanup()
	return rc;

Instead of doing cleanup mid function, or having multiple returns or other
options.  This doesn't do that for every function, but most of the complex
functions which have cleanup routines on error.
Signed-off-by: default avatarEric Paris <eparis@redhat.com>
parent e8a7e48b
...@@ -148,32 +148,30 @@ static int roles_init(struct policydb *p) ...@@ -148,32 +148,30 @@ static int roles_init(struct policydb *p)
int rc; int rc;
struct role_datum *role; struct role_datum *role;
rc = -ENOMEM;
role = kzalloc(sizeof(*role), GFP_KERNEL); role = kzalloc(sizeof(*role), GFP_KERNEL);
if (!role) { if (!role)
rc = -ENOMEM;
goto out; goto out;
}
rc = -EINVAL;
role->value = ++p->p_roles.nprim; role->value = ++p->p_roles.nprim;
if (role->value != OBJECT_R_VAL) { if (role->value != OBJECT_R_VAL)
rc = -EINVAL; goto out;
goto out_free_role;
} rc = -ENOMEM;
key = kstrdup(OBJECT_R, GFP_KERNEL); key = kstrdup(OBJECT_R, GFP_KERNEL);
if (!key) { if (!key)
rc = -ENOMEM; goto out;
goto out_free_role;
}
rc = hashtab_insert(p->p_roles.table, key, role); rc = hashtab_insert(p->p_roles.table, key, role);
if (rc) if (rc)
goto out_free_key; goto out;
out:
return rc;
out_free_key: return 0;
out:
kfree(key); kfree(key);
out_free_role:
kfree(role); kfree(role);
goto out; return rc;
} }
static u32 rangetr_hash(struct hashtab *h, const void *k) static u32 rangetr_hash(struct hashtab *h, const void *k)
...@@ -213,35 +211,33 @@ static int policydb_init(struct policydb *p) ...@@ -213,35 +211,33 @@ static int policydb_init(struct policydb *p)
for (i = 0; i < SYM_NUM; i++) { for (i = 0; i < SYM_NUM; i++) {
rc = symtab_init(&p->symtab[i], symtab_sizes[i]); rc = symtab_init(&p->symtab[i], symtab_sizes[i]);
if (rc) if (rc)
goto out_free_symtab; goto out;
} }
rc = avtab_init(&p->te_avtab); rc = avtab_init(&p->te_avtab);
if (rc) if (rc)
goto out_free_symtab; goto out;
rc = roles_init(p); rc = roles_init(p);
if (rc) if (rc)
goto out_free_symtab; goto out;
rc = cond_policydb_init(p); rc = cond_policydb_init(p);
if (rc) if (rc)
goto out_free_symtab; goto out;
p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256); p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256);
if (!p->range_tr) if (!p->range_tr)
goto out_free_symtab; goto out;
ebitmap_init(&p->policycaps); ebitmap_init(&p->policycaps);
ebitmap_init(&p->permissive_map); ebitmap_init(&p->permissive_map);
return 0;
out: out:
return rc;
out_free_symtab:
for (i = 0; i < SYM_NUM; i++) for (i = 0; i < SYM_NUM; i++)
hashtab_destroy(p->symtab[i].table); hashtab_destroy(p->symtab[i].table);
goto out; return rc;
} }
/* /*
...@@ -391,30 +387,27 @@ static int policydb_index_classes(struct policydb *p) ...@@ -391,30 +387,27 @@ static int policydb_index_classes(struct policydb *p)
{ {
int rc; int rc;
rc = -ENOMEM;
p->p_common_val_to_name = p->p_common_val_to_name =
kmalloc(p->p_commons.nprim * sizeof(char *), GFP_KERNEL); kmalloc(p->p_commons.nprim * sizeof(char *), GFP_KERNEL);
if (!p->p_common_val_to_name) { if (!p->p_common_val_to_name)
rc = -ENOMEM;
goto out; goto out;
}
rc = hashtab_map(p->p_commons.table, common_index, p); rc = hashtab_map(p->p_commons.table, common_index, p);
if (rc) if (rc)
goto out; goto out;
rc = -ENOMEM;
p->class_val_to_struct = p->class_val_to_struct =
kmalloc(p->p_classes.nprim * sizeof(*(p->class_val_to_struct)), GFP_KERNEL); kmalloc(p->p_classes.nprim * sizeof(*(p->class_val_to_struct)), GFP_KERNEL);
if (!p->class_val_to_struct) { if (!p->class_val_to_struct)
rc = -ENOMEM;
goto out; goto out;
}
rc = -ENOMEM;
p->p_class_val_to_name = p->p_class_val_to_name =
kmalloc(p->p_classes.nprim * sizeof(char *), GFP_KERNEL); kmalloc(p->p_classes.nprim * sizeof(char *), GFP_KERNEL);
if (!p->p_class_val_to_name) { if (!p->p_class_val_to_name)
rc = -ENOMEM;
goto out; goto out;
}
rc = hashtab_map(p->p_classes.table, class_index, p); rc = hashtab_map(p->p_classes.table, class_index, p);
out: out:
...@@ -460,7 +453,7 @@ static inline void rangetr_hash_eval(struct hashtab *h) ...@@ -460,7 +453,7 @@ static inline void rangetr_hash_eval(struct hashtab *h)
*/ */
static int policydb_index_others(struct policydb *p) static int policydb_index_others(struct policydb *p)
{ {
int i, rc = 0; int i, rc;
printk(KERN_DEBUG "SELinux: %d users, %d roles, %d types, %d bools", printk(KERN_DEBUG "SELinux: %d users, %d roles, %d types, %d bools",
p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim); p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);
...@@ -477,47 +470,42 @@ static int policydb_index_others(struct policydb *p) ...@@ -477,47 +470,42 @@ static int policydb_index_others(struct policydb *p)
symtab_hash_eval(p->symtab); symtab_hash_eval(p->symtab);
#endif #endif
rc = -ENOMEM;
p->role_val_to_struct = p->role_val_to_struct =
kmalloc(p->p_roles.nprim * sizeof(*(p->role_val_to_struct)), kmalloc(p->p_roles.nprim * sizeof(*(p->role_val_to_struct)),
GFP_KERNEL); GFP_KERNEL);
if (!p->role_val_to_struct) { if (!p->role_val_to_struct)
rc = -ENOMEM;
goto out; goto out;
}
rc = -ENOMEM;
p->user_val_to_struct = p->user_val_to_struct =
kmalloc(p->p_users.nprim * sizeof(*(p->user_val_to_struct)), kmalloc(p->p_users.nprim * sizeof(*(p->user_val_to_struct)),
GFP_KERNEL); GFP_KERNEL);
if (!p->user_val_to_struct) { if (!p->user_val_to_struct)
rc = -ENOMEM;
goto out; goto out;
}
rc = -ENOMEM;
p->type_val_to_struct = p->type_val_to_struct =
kmalloc(p->p_types.nprim * sizeof(*(p->type_val_to_struct)), kmalloc(p->p_types.nprim * sizeof(*(p->type_val_to_struct)),
GFP_KERNEL); GFP_KERNEL);
if (!p->type_val_to_struct) { if (!p->type_val_to_struct)
rc = -ENOMEM;
goto out; goto out;
}
if (cond_init_bool_indexes(p)) { rc = -ENOMEM;
rc = -ENOMEM; if (cond_init_bool_indexes(p))
goto out; goto out;
}
for (i = SYM_ROLES; i < SYM_NUM; i++) { for (i = SYM_ROLES; i < SYM_NUM; i++) {
rc = -ENOMEM;
p->sym_val_to_name[i] = p->sym_val_to_name[i] =
kmalloc(p->symtab[i].nprim * sizeof(char *), GFP_KERNEL); kmalloc(p->symtab[i].nprim * sizeof(char *), GFP_KERNEL);
if (!p->sym_val_to_name[i]) { if (!p->sym_val_to_name[i])
rc = -ENOMEM;
goto out; goto out;
}
rc = hashtab_map(p->symtab[i].table, index_f[i], p); rc = hashtab_map(p->symtab[i].table, index_f[i], p);
if (rc) if (rc)
goto out; goto out;
} }
rc = 0;
out: out:
return rc; return rc;
} }
...@@ -540,9 +528,11 @@ static int common_destroy(void *key, void *datum, void *p) ...@@ -540,9 +528,11 @@ static int common_destroy(void *key, void *datum, void *p)
struct common_datum *comdatum; struct common_datum *comdatum;
kfree(key); kfree(key);
comdatum = datum; if (datum) {
hashtab_map(comdatum->permissions.table, perm_destroy, NULL); comdatum = datum;
hashtab_destroy(comdatum->permissions.table); hashtab_map(comdatum->permissions.table, perm_destroy, NULL);
hashtab_destroy(comdatum->permissions.table);
}
kfree(datum); kfree(datum);
return 0; return 0;
} }
...@@ -554,38 +544,40 @@ static int cls_destroy(void *key, void *datum, void *p) ...@@ -554,38 +544,40 @@ static int cls_destroy(void *key, void *datum, void *p)
struct constraint_expr *e, *etmp; struct constraint_expr *e, *etmp;
kfree(key); kfree(key);
cladatum = datum; if (datum) {
hashtab_map(cladatum->permissions.table, perm_destroy, NULL); cladatum = datum;
hashtab_destroy(cladatum->permissions.table); hashtab_map(cladatum->permissions.table, perm_destroy, NULL);
constraint = cladatum->constraints; hashtab_destroy(cladatum->permissions.table);
while (constraint) { constraint = cladatum->constraints;
e = constraint->expr; while (constraint) {
while (e) { e = constraint->expr;
ebitmap_destroy(&e->names); while (e) {
etmp = e; ebitmap_destroy(&e->names);
e = e->next; etmp = e;
kfree(etmp); e = e->next;
kfree(etmp);
}
ctemp = constraint;
constraint = constraint->next;
kfree(ctemp);
} }
ctemp = constraint;
constraint = constraint->next; constraint = cladatum->validatetrans;
kfree(ctemp); while (constraint) {
} e = constraint->expr;
while (e) {
constraint = cladatum->validatetrans; ebitmap_destroy(&e->names);
while (constraint) { etmp = e;
e = constraint->expr; e = e->next;
while (e) { kfree(etmp);
ebitmap_destroy(&e->names); }
etmp = e; ctemp = constraint;
e = e->next; constraint = constraint->next;
kfree(etmp); kfree(ctemp);
} }
ctemp = constraint;
constraint = constraint->next;
kfree(ctemp);
}
kfree(cladatum->comkey); kfree(cladatum->comkey);
}
kfree(datum); kfree(datum);
return 0; return 0;
} }
...@@ -595,9 +587,11 @@ static int role_destroy(void *key, void *datum, void *p) ...@@ -595,9 +587,11 @@ static int role_destroy(void *key, void *datum, void *p)
struct role_datum *role; struct role_datum *role;
kfree(key); kfree(key);
role = datum; if (datum) {
ebitmap_destroy(&role->dominates); role = datum;
ebitmap_destroy(&role->types); ebitmap_destroy(&role->dominates);
ebitmap_destroy(&role->types);
}
kfree(datum); kfree(datum);
return 0; return 0;
} }
...@@ -614,11 +608,13 @@ static int user_destroy(void *key, void *datum, void *p) ...@@ -614,11 +608,13 @@ static int user_destroy(void *key, void *datum, void *p)
struct user_datum *usrdatum; struct user_datum *usrdatum;
kfree(key); kfree(key);
usrdatum = datum; if (datum) {
ebitmap_destroy(&usrdatum->roles); usrdatum = datum;
ebitmap_destroy(&usrdatum->range.level[0].cat); ebitmap_destroy(&usrdatum->roles);
ebitmap_destroy(&usrdatum->range.level[1].cat); ebitmap_destroy(&usrdatum->range.level[0].cat);
ebitmap_destroy(&usrdatum->dfltlevel.cat); ebitmap_destroy(&usrdatum->range.level[1].cat);
ebitmap_destroy(&usrdatum->dfltlevel.cat);
}
kfree(datum); kfree(datum);
return 0; return 0;
} }
...@@ -628,9 +624,11 @@ static int sens_destroy(void *key, void *datum, void *p) ...@@ -628,9 +624,11 @@ static int sens_destroy(void *key, void *datum, void *p)
struct level_datum *levdatum; struct level_datum *levdatum;
kfree(key); kfree(key);
levdatum = datum; if (datum) {
ebitmap_destroy(&levdatum->level->cat); levdatum = datum;
kfree(levdatum->level); ebitmap_destroy(&levdatum->level->cat);
kfree(levdatum->level);
}
kfree(datum); kfree(datum);
return 0; return 0;
} }
...@@ -785,19 +783,21 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s) ...@@ -785,19 +783,21 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s)
head = p->ocontexts[OCON_ISID]; head = p->ocontexts[OCON_ISID];
for (c = head; c; c = c->next) { for (c = head; c; c = c->next) {
rc = -EINVAL;
if (!c->context[0].user) { if (!c->context[0].user) {
printk(KERN_ERR "SELinux: SID %s was never " printk(KERN_ERR "SELinux: SID %s was never defined.\n",
"defined.\n", c->u.name); c->u.name);
rc = -EINVAL;
goto out; goto out;
} }
if (sidtab_insert(s, c->sid[0], &c->context[0])) {
printk(KERN_ERR "SELinux: unable to load initial " rc = sidtab_insert(s, c->sid[0], &c->context[0]);
"SID %s.\n", c->u.name); if (rc) {
rc = -EINVAL; printk(KERN_ERR "SELinux: unable to load initial SID %s.\n",
c->u.name);
goto out; goto out;
} }
} }
rc = 0;
out: out:
return rc; return rc;
} }
...@@ -846,8 +846,7 @@ int policydb_context_isvalid(struct policydb *p, struct context *c) ...@@ -846,8 +846,7 @@ int policydb_context_isvalid(struct policydb *p, struct context *c)
* Role must be authorized for the type. * Role must be authorized for the type.
*/ */
role = p->role_val_to_struct[c->role - 1]; role = p->role_val_to_struct[c->role - 1];
if (!ebitmap_get_bit(&role->types, if (!ebitmap_get_bit(&role->types, c->type - 1))
c->type - 1))
/* role may not be associated with type */ /* role may not be associated with type */
return 0; return 0;
...@@ -858,8 +857,7 @@ int policydb_context_isvalid(struct policydb *p, struct context *c) ...@@ -858,8 +857,7 @@ int policydb_context_isvalid(struct policydb *p, struct context *c)
if (!usrdatum) if (!usrdatum)
return 0; return 0;
if (!ebitmap_get_bit(&usrdatum->roles, if (!ebitmap_get_bit(&usrdatum->roles, c->role - 1))
c->role - 1))
/* user may not be associated with role */ /* user may not be associated with role */
return 0; return 0;
} }
...@@ -881,20 +879,22 @@ static int mls_read_range_helper(struct mls_range *r, void *fp) ...@@ -881,20 +879,22 @@ static int mls_read_range_helper(struct mls_range *r, void *fp)
int rc; int rc;
rc = next_entry(buf, fp, sizeof(u32)); rc = next_entry(buf, fp, sizeof(u32));
if (rc < 0) if (rc)
goto out; goto out;
rc = -EINVAL;
items = le32_to_cpu(buf[0]); items = le32_to_cpu(buf[0]);
if (items > ARRAY_SIZE(buf)) { if (items > ARRAY_SIZE(buf)) {
printk(KERN_ERR "SELinux: mls: range overflow\n"); printk(KERN_ERR "SELinux: mls: range overflow\n");
rc = -EINVAL;
goto out; goto out;
} }
rc = next_entry(buf, fp, sizeof(u32) * items); rc = next_entry(buf, fp, sizeof(u32) * items);
if (rc < 0) { if (rc) {
printk(KERN_ERR "SELinux: mls: truncated range\n"); printk(KERN_ERR "SELinux: mls: truncated range\n");
goto out; goto out;
} }
r->level[0].sens = le32_to_cpu(buf[0]); r->level[0].sens = le32_to_cpu(buf[0]);
if (items > 1) if (items > 1)
r->level[1].sens = le32_to_cpu(buf[1]); r->level[1].sens = le32_to_cpu(buf[1]);
...@@ -903,15 +903,13 @@ static int mls_read_range_helper(struct mls_range *r, void *fp) ...@@ -903,15 +903,13 @@ static int mls_read_range_helper(struct mls_range *r, void *fp)
rc = ebitmap_read(&r->level[0].cat, fp); rc = ebitmap_read(&r->level[0].cat, fp);
if (rc) { if (rc) {
printk(KERN_ERR "SELinux: mls: error reading low " printk(KERN_ERR "SELinux: mls: error reading low categories\n");
"categories\n");
goto out; goto out;
} }
if (items > 1) { if (items > 1) {
rc = ebitmap_read(&r->level[1].cat, fp); rc = ebitmap_read(&r->level[1].cat, fp);
if (rc) { if (rc) {
printk(KERN_ERR "SELinux: mls: error reading high " printk(KERN_ERR "SELinux: mls: error reading high categories\n");
"categories\n");
goto bad_high; goto bad_high;
} }
} else { } else {
...@@ -922,12 +920,11 @@ static int mls_read_range_helper(struct mls_range *r, void *fp) ...@@ -922,12 +920,11 @@ static int mls_read_range_helper(struct mls_range *r, void *fp)
} }
} }
rc = 0; return 0;
out:
return rc;
bad_high: bad_high:
ebitmap_destroy(&r->level[0].cat); ebitmap_destroy(&r->level[0].cat);
goto out; out:
return rc;
} }
/* /*
...@@ -942,7 +939,7 @@ static int context_read_and_validate(struct context *c, ...@@ -942,7 +939,7 @@ static int context_read_and_validate(struct context *c,
int rc; int rc;
rc = next_entry(buf, fp, sizeof buf); rc = next_entry(buf, fp, sizeof buf);
if (rc < 0) { if (rc) {
printk(KERN_ERR "SELinux: context truncated\n"); printk(KERN_ERR "SELinux: context truncated\n");
goto out; goto out;
} }
...@@ -950,19 +947,20 @@ static int context_read_and_validate(struct context *c, ...@@ -950,19 +947,20 @@ static int context_read_and_validate(struct context *c,
c->role = le32_to_cpu(buf[1]); c->role = le32_to_cpu(buf[1]);
c->type = le32_to_cpu(buf[2]); c->type = le32_to_cpu(buf[2]);
if (p->policyvers >= POLICYDB_VERSION_MLS) { if (p->policyvers >= POLICYDB_VERSION_MLS) {
if (mls_read_range_helper(&c->range, fp)) { rc = mls_read_range_helper(&c->range, fp);
printk(KERN_ERR "SELinux: error reading MLS range of " if (rc) {
"context\n"); printk(KERN_ERR "SELinux: error reading MLS range of context\n");
rc = -EINVAL;
goto out; goto out;
} }
} }
rc = -EINVAL;
if (!policydb_context_isvalid(p, c)) { if (!policydb_context_isvalid(p, c)) {
printk(KERN_ERR "SELinux: invalid security context\n"); printk(KERN_ERR "SELinux: invalid security context\n");
context_destroy(c); context_destroy(c);
rc = -EINVAL; goto out;
} }
rc = 0;
out: out:
return rc; return rc;
} }
...@@ -981,37 +979,36 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -981,37 +979,36 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[2]; __le32 buf[2];
u32 len; u32 len;
rc = -ENOMEM;
perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL); perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL);
if (!perdatum) { if (!perdatum)
rc = -ENOMEM; goto bad;
goto out;
}
rc = next_entry(buf, fp, sizeof buf); rc = next_entry(buf, fp, sizeof buf);
if (rc < 0) if (rc)
goto bad; goto bad;
len = le32_to_cpu(buf[0]); len = le32_to_cpu(buf[0]);
perdatum->value = le32_to_cpu(buf[1]); perdatum->value = le32_to_cpu(buf[1]);
rc = -ENOMEM;
key = kmalloc(len + 1, GFP_KERNEL); key = kmalloc(len + 1, GFP_KERNEL);
if (!key) { if (!key)
rc = -ENOMEM;
goto bad; goto bad;
}
rc = next_entry(key, fp, len); rc = next_entry(key, fp, len);
if (rc < 0) if (rc)
goto bad; goto bad;
key[len] = '\0'; key[len] = '\0';
rc = hashtab_insert(h, key, perdatum); rc = hashtab_insert(h, key, perdatum);
if (rc) if (rc)
goto bad; goto bad;
out:
return rc; return 0;
bad: bad:
perm_destroy(key, perdatum, NULL); perm_destroy(key, perdatum, NULL);
goto out; return rc;
} }
static int common_read(struct policydb *p, struct hashtab *h, void *fp) static int common_read(struct policydb *p, struct hashtab *h, void *fp)
...@@ -1022,14 +1019,13 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1022,14 +1019,13 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
u32 len, nel; u32 len, nel;
int i, rc; int i, rc;
rc = -ENOMEM;
comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL); comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL);
if (!comdatum) { if (!comdatum)
rc = -ENOMEM; goto bad;
goto out;
}
rc = next_entry(buf, fp, sizeof buf); rc = next_entry(buf, fp, sizeof buf);
if (rc < 0) if (rc)
goto bad; goto bad;
len = le32_to_cpu(buf[0]); len = le32_to_cpu(buf[0]);
...@@ -1041,13 +1037,13 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1041,13 +1037,13 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
comdatum->permissions.nprim = le32_to_cpu(buf[2]); comdatum->permissions.nprim = le32_to_cpu(buf[2]);
nel = le32_to_cpu(buf[3]); nel = le32_to_cpu(buf[3]);
rc = -ENOMEM;
key = kmalloc(len + 1, GFP_KERNEL); key = kmalloc(len + 1, GFP_KERNEL);
if (!key) { if (!key)
rc = -ENOMEM;
goto bad; goto bad;
}
rc = next_entry(key, fp, len); rc = next_entry(key, fp, len);
if (rc < 0) if (rc)
goto bad; goto bad;
key[len] = '\0'; key[len] = '\0';
...@@ -1060,11 +1056,10 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1060,11 +1056,10 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
rc = hashtab_insert(h, key, comdatum); rc = hashtab_insert(h, key, comdatum);
if (rc) if (rc)
goto bad; goto bad;
out: return 0;
return rc;
bad: bad:
common_destroy(key, comdatum, NULL); common_destroy(key, comdatum, NULL);
goto out; return rc;
} }
static int read_cons_helper(struct constraint_node **nodep, int ncons, static int read_cons_helper(struct constraint_node **nodep, int ncons,
...@@ -1088,7 +1083,7 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons, ...@@ -1088,7 +1083,7 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
*nodep = c; *nodep = c;
rc = next_entry(buf, fp, (sizeof(u32) * 2)); rc = next_entry(buf, fp, (sizeof(u32) * 2));
if (rc < 0) if (rc)
return rc; return rc;
c->permissions = le32_to_cpu(buf[0]); c->permissions = le32_to_cpu(buf[0]);
nexpr = le32_to_cpu(buf[1]); nexpr = le32_to_cpu(buf[1]);
...@@ -1105,7 +1100,7 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons, ...@@ -1105,7 +1100,7 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
c->expr = e; c->expr = e;
rc = next_entry(buf, fp, (sizeof(u32) * 3)); rc = next_entry(buf, fp, (sizeof(u32) * 3));
if (rc < 0) if (rc)
return rc; return rc;
e->expr_type = le32_to_cpu(buf[0]); e->expr_type = le32_to_cpu(buf[0]);
e->attr = le32_to_cpu(buf[1]); e->attr = le32_to_cpu(buf[1]);
...@@ -1133,8 +1128,9 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons, ...@@ -1133,8 +1128,9 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
if (depth == (CEXPR_MAXDEPTH - 1)) if (depth == (CEXPR_MAXDEPTH - 1))
return -EINVAL; return -EINVAL;
depth++; depth++;
if (ebitmap_read(&e->names, fp)) rc = ebitmap_read(&e->names, fp);
return -EINVAL; if (rc)
return rc;
break; break;
default: default:
return -EINVAL; return -EINVAL;
...@@ -1157,14 +1153,13 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1157,14 +1153,13 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
u32 len, len2, ncons, nel; u32 len, len2, ncons, nel;
int i, rc; int i, rc;
rc = -ENOMEM;
cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL); cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL);
if (!cladatum) { if (!cladatum)
rc = -ENOMEM; goto bad;
goto out;
}
rc = next_entry(buf, fp, sizeof(u32)*6); rc = next_entry(buf, fp, sizeof(u32)*6);
if (rc < 0) if (rc)
goto bad; goto bad;
len = le32_to_cpu(buf[0]); len = le32_to_cpu(buf[0]);
...@@ -1179,33 +1174,30 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1179,33 +1174,30 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
ncons = le32_to_cpu(buf[5]); ncons = le32_to_cpu(buf[5]);
rc = -ENOMEM;
key = kmalloc(len + 1, GFP_KERNEL); key = kmalloc(len + 1, GFP_KERNEL);
if (!key) { if (!key)
rc = -ENOMEM;
goto bad; goto bad;
}
rc = next_entry(key, fp, len); rc = next_entry(key, fp, len);
if (rc < 0) if (rc)
goto bad; goto bad;
key[len] = '\0'; key[len] = '\0';
if (len2) { if (len2) {
rc = -ENOMEM;
cladatum->comkey = kmalloc(len2 + 1, GFP_KERNEL); cladatum->comkey = kmalloc(len2 + 1, GFP_KERNEL);
if (!cladatum->comkey) { if (!cladatum->comkey)
rc = -ENOMEM;
goto bad; goto bad;
}
rc = next_entry(cladatum->comkey, fp, len2); rc = next_entry(cladatum->comkey, fp, len2);
if (rc < 0) if (rc)
goto bad; goto bad;
cladatum->comkey[len2] = '\0'; cladatum->comkey[len2] = '\0';
cladatum->comdatum = hashtab_search(p->p_commons.table, rc = -EINVAL;
cladatum->comkey); cladatum->comdatum = hashtab_search(p->p_commons.table, cladatum->comkey);
if (!cladatum->comdatum) { if (!cladatum->comdatum) {
printk(KERN_ERR "SELinux: unknown common %s\n", printk(KERN_ERR "SELinux: unknown common %s\n", cladatum->comkey);
cladatum->comkey);
rc = -EINVAL;
goto bad; goto bad;
} }
} }
...@@ -1222,7 +1214,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1222,7 +1214,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
if (p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) { if (p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) {
/* grab the validatetrans rules */ /* grab the validatetrans rules */
rc = next_entry(buf, fp, sizeof(u32)); rc = next_entry(buf, fp, sizeof(u32));
if (rc < 0) if (rc)
goto bad; goto bad;
ncons = le32_to_cpu(buf[0]); ncons = le32_to_cpu(buf[0]);
rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, fp); rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, fp);
...@@ -1234,12 +1226,10 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1234,12 +1226,10 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
if (rc) if (rc)
goto bad; goto bad;
rc = 0; return 0;
out:
return rc;
bad: bad:
cls_destroy(key, cladatum, NULL); cls_destroy(key, cladatum, NULL);
goto out; return rc;
} }
static int role_read(struct policydb *p, struct hashtab *h, void *fp) static int role_read(struct policydb *p, struct hashtab *h, void *fp)
...@@ -1250,17 +1240,16 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1250,17 +1240,16 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[3]; __le32 buf[3];
u32 len; u32 len;
rc = -ENOMEM;
role = kzalloc(sizeof(*role), GFP_KERNEL); role = kzalloc(sizeof(*role), GFP_KERNEL);
if (!role) { if (!role)
rc = -ENOMEM; goto bad;
goto out;
}
if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
to_read = 3; to_read = 3;
rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); rc = next_entry(buf, fp, sizeof(buf[0]) * to_read);
if (rc < 0) if (rc)
goto bad; goto bad;
len = le32_to_cpu(buf[0]); len = le32_to_cpu(buf[0]);
...@@ -1268,13 +1257,13 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1268,13 +1257,13 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
role->bounds = le32_to_cpu(buf[2]); role->bounds = le32_to_cpu(buf[2]);
rc = -ENOMEM;
key = kmalloc(len + 1, GFP_KERNEL); key = kmalloc(len + 1, GFP_KERNEL);
if (!key) { if (!key)
rc = -ENOMEM;
goto bad; goto bad;
}
rc = next_entry(key, fp, len); rc = next_entry(key, fp, len);
if (rc < 0) if (rc)
goto bad; goto bad;
key[len] = '\0'; key[len] = '\0';
...@@ -1287,10 +1276,10 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1287,10 +1276,10 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
goto bad; goto bad;
if (strcmp(key, OBJECT_R) == 0) { if (strcmp(key, OBJECT_R) == 0) {
rc = -EINVAL;
if (role->value != OBJECT_R_VAL) { if (role->value != OBJECT_R_VAL) {
printk(KERN_ERR "SELinux: Role %s has wrong value %d\n", printk(KERN_ERR "SELinux: Role %s has wrong value %d\n",
OBJECT_R, role->value); OBJECT_R, role->value);
rc = -EINVAL;
goto bad; goto bad;
} }
rc = 0; rc = 0;
...@@ -1300,11 +1289,10 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1300,11 +1289,10 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
rc = hashtab_insert(h, key, role); rc = hashtab_insert(h, key, role);
if (rc) if (rc)
goto bad; goto bad;
out: return 0;
return rc;
bad: bad:
role_destroy(key, role, NULL); role_destroy(key, role, NULL);
goto out; return rc;
} }
static int type_read(struct policydb *p, struct hashtab *h, void *fp) static int type_read(struct policydb *p, struct hashtab *h, void *fp)
...@@ -1315,17 +1303,16 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1315,17 +1303,16 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[4]; __le32 buf[4];
u32 len; u32 len;
rc = -ENOMEM;
typdatum = kzalloc(sizeof(*typdatum), GFP_KERNEL); typdatum = kzalloc(sizeof(*typdatum), GFP_KERNEL);
if (!typdatum) { if (!typdatum)
rc = -ENOMEM; goto bad;
return rc;
}
if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
to_read = 4; to_read = 4;
rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); rc = next_entry(buf, fp, sizeof(buf[0]) * to_read);
if (rc < 0) if (rc)
goto bad; goto bad;
len = le32_to_cpu(buf[0]); len = le32_to_cpu(buf[0]);
...@@ -1343,24 +1330,22 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1343,24 +1330,22 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
typdatum->primary = le32_to_cpu(buf[2]); typdatum->primary = le32_to_cpu(buf[2]);
} }
rc = -ENOMEM;
key = kmalloc(len + 1, GFP_KERNEL); key = kmalloc(len + 1, GFP_KERNEL);
if (!key) { if (!key)
rc = -ENOMEM;
goto bad; goto bad;
}
rc = next_entry(key, fp, len); rc = next_entry(key, fp, len);
if (rc < 0) if (rc)
goto bad; goto bad;
key[len] = '\0'; key[len] = '\0';
rc = hashtab_insert(h, key, typdatum); rc = hashtab_insert(h, key, typdatum);
if (rc) if (rc)
goto bad; goto bad;
out: return 0;
return rc;
bad: bad:
type_destroy(key, typdatum, NULL); type_destroy(key, typdatum, NULL);
goto out; return rc;
} }
...@@ -1376,22 +1361,18 @@ static int mls_read_level(struct mls_level *lp, void *fp) ...@@ -1376,22 +1361,18 @@ static int mls_read_level(struct mls_level *lp, void *fp)
memset(lp, 0, sizeof(*lp)); memset(lp, 0, sizeof(*lp));
rc = next_entry(buf, fp, sizeof buf); rc = next_entry(buf, fp, sizeof buf);
if (rc < 0) { if (rc) {
printk(KERN_ERR "SELinux: mls: truncated level\n"); printk(KERN_ERR "SELinux: mls: truncated level\n");
goto bad; return rc;
} }
lp->sens = le32_to_cpu(buf[0]); lp->sens = le32_to_cpu(buf[0]);
if (ebitmap_read(&lp->cat, fp)) { rc = ebitmap_read(&lp->cat, fp);
printk(KERN_ERR "SELinux: mls: error reading level " if (rc) {
"categories\n"); printk(KERN_ERR "SELinux: mls: error reading level categories\n");
goto bad; return rc;
} }
return 0; return 0;
bad:
return -EINVAL;
} }
static int user_read(struct policydb *p, struct hashtab *h, void *fp) static int user_read(struct policydb *p, struct hashtab *h, void *fp)
...@@ -1402,17 +1383,16 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1402,17 +1383,16 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[3]; __le32 buf[3];
u32 len; u32 len;
rc = -ENOMEM;
usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL); usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL);
if (!usrdatum) { if (!usrdatum)
rc = -ENOMEM; goto bad;
goto out;
}
if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
to_read = 3; to_read = 3;
rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); rc = next_entry(buf, fp, sizeof(buf[0]) * to_read);
if (rc < 0) if (rc)
goto bad; goto bad;
len = le32_to_cpu(buf[0]); len = le32_to_cpu(buf[0]);
...@@ -1420,13 +1400,12 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1420,13 +1400,12 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
usrdatum->bounds = le32_to_cpu(buf[2]); usrdatum->bounds = le32_to_cpu(buf[2]);
rc = -ENOMEM;
key = kmalloc(len + 1, GFP_KERNEL); key = kmalloc(len + 1, GFP_KERNEL);
if (!key) { if (!key)
rc = -ENOMEM;
goto bad; goto bad;
}
rc = next_entry(key, fp, len); rc = next_entry(key, fp, len);
if (rc < 0) if (rc)
goto bad; goto bad;
key[len] = '\0'; key[len] = '\0';
...@@ -1446,11 +1425,10 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1446,11 +1425,10 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
rc = hashtab_insert(h, key, usrdatum); rc = hashtab_insert(h, key, usrdatum);
if (rc) if (rc)
goto bad; goto bad;
out: return 0;
return rc;
bad: bad:
user_destroy(key, usrdatum, NULL); user_destroy(key, usrdatum, NULL);
goto out; return rc;
} }
static int sens_read(struct policydb *p, struct hashtab *h, void *fp) static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
...@@ -1461,47 +1439,43 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1461,47 +1439,43 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[2]; __le32 buf[2];
u32 len; u32 len;
rc = -ENOMEM;
levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC); levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC);
if (!levdatum) { if (!levdatum)
rc = -ENOMEM; goto bad;
goto out;
}
rc = next_entry(buf, fp, sizeof buf); rc = next_entry(buf, fp, sizeof buf);
if (rc < 0) if (rc)
goto bad; goto bad;
len = le32_to_cpu(buf[0]); len = le32_to_cpu(buf[0]);
levdatum->isalias = le32_to_cpu(buf[1]); levdatum->isalias = le32_to_cpu(buf[1]);
rc = -ENOMEM;
key = kmalloc(len + 1, GFP_ATOMIC); key = kmalloc(len + 1, GFP_ATOMIC);
if (!key) { if (!key)
rc = -ENOMEM;
goto bad; goto bad;
}
rc = next_entry(key, fp, len); rc = next_entry(key, fp, len);
if (rc < 0) if (rc)
goto bad; goto bad;
key[len] = '\0'; key[len] = '\0';
rc = -ENOMEM;
levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC); levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC);
if (!levdatum->level) { if (!levdatum->level)
rc = -ENOMEM;
goto bad; goto bad;
}
if (mls_read_level(levdatum->level, fp)) { rc = mls_read_level(levdatum->level, fp);
rc = -EINVAL; if (rc)
goto bad; goto bad;
}
rc = hashtab_insert(h, key, levdatum); rc = hashtab_insert(h, key, levdatum);
if (rc) if (rc)
goto bad; goto bad;
out: return 0;
return rc;
bad: bad:
sens_destroy(key, levdatum, NULL); sens_destroy(key, levdatum, NULL);
goto out; return rc;
} }
static int cat_read(struct policydb *p, struct hashtab *h, void *fp) static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
...@@ -1512,39 +1486,35 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1512,39 +1486,35 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
__le32 buf[3]; __le32 buf[3];
u32 len; u32 len;
rc = -ENOMEM;
catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC); catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC);
if (!catdatum) { if (!catdatum)
rc = -ENOMEM; goto bad;
goto out;
}
rc = next_entry(buf, fp, sizeof buf); rc = next_entry(buf, fp, sizeof buf);
if (rc < 0) if (rc)
goto bad; goto bad;
len = le32_to_cpu(buf[0]); len = le32_to_cpu(buf[0]);
catdatum->value = le32_to_cpu(buf[1]); catdatum->value = le32_to_cpu(buf[1]);
catdatum->isalias = le32_to_cpu(buf[2]); catdatum->isalias = le32_to_cpu(buf[2]);
rc = -ENOMEM;
key = kmalloc(len + 1, GFP_ATOMIC); key = kmalloc(len + 1, GFP_ATOMIC);
if (!key) { if (!key)
rc = -ENOMEM;
goto bad; goto bad;
}
rc = next_entry(key, fp, len); rc = next_entry(key, fp, len);
if (rc < 0) if (rc)
goto bad; goto bad;
key[len] = '\0'; key[len] = '\0';
rc = hashtab_insert(h, key, catdatum); rc = hashtab_insert(h, key, catdatum);
if (rc) if (rc)
goto bad; goto bad;
out: return 0;
return rc;
bad: bad:
cat_destroy(key, catdatum, NULL); cat_destroy(key, catdatum, NULL);
goto out; return rc;
} }
static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp) = static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp) =
...@@ -2066,13 +2036,14 @@ int policydb_read(struct policydb *p, void *fp) ...@@ -2066,13 +2036,14 @@ int policydb_read(struct policydb *p, void *fp)
rc = policydb_init(p); rc = policydb_init(p);
if (rc) if (rc)
goto out; return rc;
/* Read the magic number and string length. */ /* Read the magic number and string length. */
rc = next_entry(buf, fp, sizeof(u32) * 2); rc = next_entry(buf, fp, sizeof(u32) * 2);
if (rc < 0) if (rc)
goto bad; goto bad;
rc = -EINVAL;
if (le32_to_cpu(buf[0]) != POLICYDB_MAGIC) { if (le32_to_cpu(buf[0]) != POLICYDB_MAGIC) {
printk(KERN_ERR "SELinux: policydb magic number 0x%x does " printk(KERN_ERR "SELinux: policydb magic number 0x%x does "
"not match expected magic number 0x%x\n", "not match expected magic number 0x%x\n",
...@@ -2080,6 +2051,7 @@ int policydb_read(struct policydb *p, void *fp) ...@@ -2080,6 +2051,7 @@ int policydb_read(struct policydb *p, void *fp)
goto bad; goto bad;
} }
rc = -EINVAL;
len = le32_to_cpu(buf[1]); len = le32_to_cpu(buf[1]);
if (len != strlen(POLICYDB_STRING)) { if (len != strlen(POLICYDB_STRING)) {
printk(KERN_ERR "SELinux: policydb string length %d does not " printk(KERN_ERR "SELinux: policydb string length %d does not "
...@@ -2087,19 +2059,23 @@ int policydb_read(struct policydb *p, void *fp) ...@@ -2087,19 +2059,23 @@ int policydb_read(struct policydb *p, void *fp)
len, strlen(POLICYDB_STRING)); len, strlen(POLICYDB_STRING));
goto bad; goto bad;
} }
rc = -ENOMEM;
policydb_str = kmalloc(len + 1, GFP_KERNEL); policydb_str = kmalloc(len + 1, GFP_KERNEL);
if (!policydb_str) { if (!policydb_str) {
printk(KERN_ERR "SELinux: unable to allocate memory for policydb " printk(KERN_ERR "SELinux: unable to allocate memory for policydb "
"string of length %d\n", len); "string of length %d\n", len);
rc = -ENOMEM;
goto bad; goto bad;
} }
rc = next_entry(policydb_str, fp, len); rc = next_entry(policydb_str, fp, len);
if (rc < 0) { if (rc) {
printk(KERN_ERR "SELinux: truncated policydb string identifier\n"); printk(KERN_ERR "SELinux: truncated policydb string identifier\n");
kfree(policydb_str); kfree(policydb_str);
goto bad; goto bad;
} }
rc = -EINVAL;
policydb_str[len] = '\0'; policydb_str[len] = '\0';
if (strcmp(policydb_str, POLICYDB_STRING)) { if (strcmp(policydb_str, POLICYDB_STRING)) {
printk(KERN_ERR "SELinux: policydb string %s does not match " printk(KERN_ERR "SELinux: policydb string %s does not match "
...@@ -2113,9 +2089,10 @@ int policydb_read(struct policydb *p, void *fp) ...@@ -2113,9 +2089,10 @@ int policydb_read(struct policydb *p, void *fp)
/* Read the version and table sizes. */ /* Read the version and table sizes. */
rc = next_entry(buf, fp, sizeof(u32)*4); rc = next_entry(buf, fp, sizeof(u32)*4);
if (rc < 0) if (rc)
goto bad; goto bad;
rc = -EINVAL;
p->policyvers = le32_to_cpu(buf[0]); p->policyvers = le32_to_cpu(buf[0]);
if (p->policyvers < POLICYDB_VERSION_MIN || if (p->policyvers < POLICYDB_VERSION_MIN ||
p->policyvers > POLICYDB_VERSION_MAX) { p->policyvers > POLICYDB_VERSION_MAX) {
...@@ -2128,6 +2105,7 @@ int policydb_read(struct policydb *p, void *fp) ...@@ -2128,6 +2105,7 @@ int policydb_read(struct policydb *p, void *fp)
if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) { if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
p->mls_enabled = 1; p->mls_enabled = 1;
rc = -EINVAL;
if (p->policyvers < POLICYDB_VERSION_MLS) { if (p->policyvers < POLICYDB_VERSION_MLS) {
printk(KERN_ERR "SELinux: security policydb version %d " printk(KERN_ERR "SELinux: security policydb version %d "
"(MLS) not backwards compatible\n", "(MLS) not backwards compatible\n",
...@@ -2138,14 +2116,19 @@ int policydb_read(struct policydb *p, void *fp) ...@@ -2138,14 +2116,19 @@ int policydb_read(struct policydb *p, void *fp)
p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN); p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN); p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
if (p->policyvers >= POLICYDB_VERSION_POLCAP && if (p->policyvers >= POLICYDB_VERSION_POLCAP) {
ebitmap_read(&p->policycaps, fp) != 0) rc = ebitmap_read(&p->policycaps, fp);
goto bad; if (rc)
goto bad;
}
if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE && if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE) {
ebitmap_read(&p->permissive_map, fp) != 0) rc = ebitmap_read(&p->permissive_map, fp);
goto bad; if (rc)
goto bad;
}
rc = -EINVAL;
info = policydb_lookup_compat(p->policyvers); info = policydb_lookup_compat(p->policyvers);
if (!info) { if (!info) {
printk(KERN_ERR "SELinux: unable to find policy compat info " printk(KERN_ERR "SELinux: unable to find policy compat info "
...@@ -2153,6 +2136,7 @@ int policydb_read(struct policydb *p, void *fp) ...@@ -2153,6 +2136,7 @@ int policydb_read(struct policydb *p, void *fp)
goto bad; goto bad;
} }
rc = -EINVAL;
if (le32_to_cpu(buf[2]) != info->sym_num || if (le32_to_cpu(buf[2]) != info->sym_num ||
le32_to_cpu(buf[3]) != info->ocon_num) { le32_to_cpu(buf[3]) != info->ocon_num) {
printk(KERN_ERR "SELinux: policydb table sizes (%d,%d) do " printk(KERN_ERR "SELinux: policydb table sizes (%d,%d) do "
...@@ -2164,7 +2148,7 @@ int policydb_read(struct policydb *p, void *fp) ...@@ -2164,7 +2148,7 @@ int policydb_read(struct policydb *p, void *fp)
for (i = 0; i < info->sym_num; i++) { for (i = 0; i < info->sym_num; i++) {
rc = next_entry(buf, fp, sizeof(u32)*2); rc = next_entry(buf, fp, sizeof(u32)*2);
if (rc < 0) if (rc)
goto bad; goto bad;
nprim = le32_to_cpu(buf[0]); nprim = le32_to_cpu(buf[0]);
nel = le32_to_cpu(buf[1]); nel = le32_to_cpu(buf[1]);
...@@ -2188,60 +2172,58 @@ int policydb_read(struct policydb *p, void *fp) ...@@ -2188,60 +2172,58 @@ int policydb_read(struct policydb *p, void *fp)
} }
rc = next_entry(buf, fp, sizeof(u32)); rc = next_entry(buf, fp, sizeof(u32));
if (rc < 0) if (rc)
goto bad; goto bad;
nel = le32_to_cpu(buf[0]); nel = le32_to_cpu(buf[0]);
ltr = NULL; ltr = NULL;
for (i = 0; i < nel; i++) { for (i = 0; i < nel; i++) {
rc = -ENOMEM;
tr = kzalloc(sizeof(*tr), GFP_KERNEL); tr = kzalloc(sizeof(*tr), GFP_KERNEL);
if (!tr) { if (!tr)
rc = -ENOMEM;
goto bad; goto bad;
}
if (ltr) if (ltr)
ltr->next = tr; ltr->next = tr;
else else
p->role_tr = tr; p->role_tr = tr;
rc = next_entry(buf, fp, sizeof(u32)*3); rc = next_entry(buf, fp, sizeof(u32)*3);
if (rc < 0) if (rc)
goto bad; goto bad;
rc = -EINVAL;
tr->role = le32_to_cpu(buf[0]); tr->role = le32_to_cpu(buf[0]);
tr->type = le32_to_cpu(buf[1]); tr->type = le32_to_cpu(buf[1]);
tr->new_role = le32_to_cpu(buf[2]); tr->new_role = le32_to_cpu(buf[2]);
if (!policydb_role_isvalid(p, tr->role) || if (!policydb_role_isvalid(p, tr->role) ||
!policydb_type_isvalid(p, tr->type) || !policydb_type_isvalid(p, tr->type) ||
!policydb_role_isvalid(p, tr->new_role)) { !policydb_role_isvalid(p, tr->new_role))
rc = -EINVAL;
goto bad; goto bad;
}
ltr = tr; ltr = tr;
} }
rc = next_entry(buf, fp, sizeof(u32)); rc = next_entry(buf, fp, sizeof(u32));
if (rc < 0) if (rc)
goto bad; goto bad;
nel = le32_to_cpu(buf[0]); nel = le32_to_cpu(buf[0]);
lra = NULL; lra = NULL;
for (i = 0; i < nel; i++) { for (i = 0; i < nel; i++) {
rc = -ENOMEM;
ra = kzalloc(sizeof(*ra), GFP_KERNEL); ra = kzalloc(sizeof(*ra), GFP_KERNEL);
if (!ra) { if (!ra)
rc = -ENOMEM;
goto bad; goto bad;
}
if (lra) if (lra)
lra->next = ra; lra->next = ra;
else else
p->role_allow = ra; p->role_allow = ra;
rc = next_entry(buf, fp, sizeof(u32)*2); rc = next_entry(buf, fp, sizeof(u32)*2);
if (rc < 0) if (rc)
goto bad; goto bad;
rc = -EINVAL;
ra->role = le32_to_cpu(buf[0]); ra->role = le32_to_cpu(buf[0]);
ra->new_role = le32_to_cpu(buf[1]); ra->new_role = le32_to_cpu(buf[1]);
if (!policydb_role_isvalid(p, ra->role) || if (!policydb_role_isvalid(p, ra->role) ||
!policydb_role_isvalid(p, ra->new_role)) { !policydb_role_isvalid(p, ra->new_role))
rc = -EINVAL;
goto bad; goto bad;
}
lra = ra; lra = ra;
} }
...@@ -2253,13 +2235,14 @@ int policydb_read(struct policydb *p, void *fp) ...@@ -2253,13 +2235,14 @@ int policydb_read(struct policydb *p, void *fp)
if (rc) if (rc)
goto bad; goto bad;
rc = -EINVAL;
p->process_class = string_to_security_class(p, "process"); p->process_class = string_to_security_class(p, "process");
if (!p->process_class) if (!p->process_class)
goto bad; goto bad;
p->process_trans_perms = string_to_av_perm(p, p->process_class,
"transition"); rc = -EINVAL;
p->process_trans_perms |= string_to_av_perm(p, p->process_class, p->process_trans_perms = string_to_av_perm(p, p->process_class, "transition");
"dyntransition"); p->process_trans_perms |= string_to_av_perm(p, p->process_class, "dyntransition");
if (!p->process_trans_perms) if (!p->process_trans_perms)
goto bad; goto bad;
...@@ -2312,8 +2295,6 @@ int policydb_read(struct policydb *p, void *fp) ...@@ -2312,8 +2295,6 @@ int policydb_read(struct policydb *p, void *fp)
out: out:
return rc; return rc;
bad: bad:
if (!rc)
rc = -EINVAL;
policydb_destroy(p); policydb_destroy(p);
goto out; goto out;
} }
...@@ -3076,7 +3057,7 @@ int policydb_write(struct policydb *p, void *fp) ...@@ -3076,7 +3057,7 @@ int policydb_write(struct policydb *p, void *fp)
if (!info) { if (!info) {
printk(KERN_ERR "SELinux: compatibility lookup failed for policy " printk(KERN_ERR "SELinux: compatibility lookup failed for policy "
"version %d", p->policyvers); "version %d", p->policyvers);
return rc; return -EINVAL;
} }
buf[0] = cpu_to_le32(p->policyvers); buf[0] = cpu_to_le32(p->policyvers);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment