};
#endif
-int policydb_loaded_version;
-
static unsigned int symtab_sizes[SYM_NUM] = {
2,
32,
struct policydb *p,
void *fp)
{
- u32 *buf;
- int rc = 0;
+ u32 buf[3];
+ int rc;
- buf = next_entry(fp, sizeof(u32)*3);
- if (!buf) {
+ rc = next_entry(buf, fp, sizeof buf);
+ if (rc < 0) {
printk(KERN_ERR "security: context truncated\n");
- rc = -EINVAL;
goto out;
}
c->user = le32_to_cpu(buf[0]);
char *key = NULL;
struct perm_datum *perdatum;
int rc;
- u32 *buf, len;
+ u32 buf[2], len;
perdatum = kmalloc(sizeof(*perdatum), GFP_KERNEL);
if (!perdatum) {
}
memset(perdatum, 0, sizeof(*perdatum));
- buf = next_entry(fp, sizeof(u32)*2);
- if (!buf) {
- rc = -EINVAL;
+ rc = next_entry(buf, fp, sizeof buf);
+ if (rc < 0)
goto bad;
- }
len = le32_to_cpu(buf[0]);
perdatum->value = le32_to_cpu(buf[1]);
if (rc)
goto bad;
- buf = next_entry(fp, len);
- if (!buf) {
- rc = -EINVAL;
- goto bad;
- }
key = kmalloc(len + 1,GFP_KERNEL);
if (!key) {
rc = -ENOMEM;
goto bad;
}
- memcpy(key, buf, len);
+ rc = next_entry(key, fp, len);
+ if (rc < 0)
+ goto bad;
key[len] = 0;
rc = hashtab_insert(h, key, perdatum);
{
char *key = NULL;
struct common_datum *comdatum;
- u32 *buf, len, nel;
+ u32 buf[4], len, nel;
int i, rc;
comdatum = kmalloc(sizeof(*comdatum), GFP_KERNEL);
}
memset(comdatum, 0, sizeof(*comdatum));
- buf = next_entry(fp, sizeof(u32)*4);
- if (!buf) {
- rc = -EINVAL;
+ rc = next_entry(buf, fp, sizeof buf);
+ if (rc < 0)
goto bad;
- }
len = le32_to_cpu(buf[0]);
comdatum->value = le32_to_cpu(buf[1]);
comdatum->permissions.nprim = le32_to_cpu(buf[2]);
nel = le32_to_cpu(buf[3]);
- buf = next_entry(fp, len);
- if (!buf) {
- rc = -EINVAL;
- goto bad;
- }
key = kmalloc(len + 1,GFP_KERNEL);
if (!key) {
rc = -ENOMEM;
goto bad;
}
- memcpy(key, buf, len);
+ rc = next_entry(key, fp, len);
+ if (rc < 0)
+ goto bad;
key[len] = 0;
for (i = 0; i < nel; i++) {
struct class_datum *cladatum;
struct constraint_node *c, *lc;
struct constraint_expr *e, *le;
- u32 *buf, len, len2, ncons, nexpr, nel;
+ u32 buf[6], len, len2, ncons, nexpr, nel;
int i, j, depth, rc;
cladatum = kmalloc(sizeof(*cladatum), GFP_KERNEL);
if (!cladatum) {
rc = -ENOMEM;
- goto bad;
+ goto out;
}
memset(cladatum, 0, sizeof(*cladatum));
- buf = next_entry(fp, sizeof(u32)*6);
- if (!buf) {
- rc = -EINVAL;
+ rc = next_entry(buf, fp, sizeof(u32)*6);
+ if (rc < 0)
goto bad;
- }
len = le32_to_cpu(buf[0]);
len2 = le32_to_cpu(buf[1]);
ncons = le32_to_cpu(buf[5]);
- buf = next_entry(fp, len);
- if (!buf) {
- rc = -EINVAL;
- goto bad;
- }
key = kmalloc(len + 1,GFP_KERNEL);
if (!key) {
rc = -ENOMEM;
goto bad;
}
- memcpy(key, buf, len);
+ rc = next_entry(key, fp, len);
+ if (rc < 0)
+ goto bad;
key[len] = 0;
if (len2) {
rc = -ENOMEM;
goto bad;
}
- buf = next_entry(fp, len2);
- if (!buf) {
- rc = -EINVAL;
+ rc = next_entry(cladatum->comkey, fp, len2);
+ if (rc < 0)
goto bad;
- }
- memcpy(cladatum->comkey, buf, len2);
cladatum->comkey[len2] = 0;
cladatum->comdatum = hashtab_search(p->p_commons.table,
}
lc = NULL;
- rc = -EINVAL;
for (i = 0; i < ncons; i++) {
c = kmalloc(sizeof(*c), GFP_KERNEL);
if (!c) {
cladatum->constraints = c;
}
- buf = next_entry(fp, sizeof(u32)*2);
- if (!buf)
+ rc = next_entry(buf, fp, sizeof(u32)*2);
+ if (rc < 0)
goto bad;
c->permissions = le32_to_cpu(buf[0]);
nexpr = le32_to_cpu(buf[1]);
c->expr = e;
}
- buf = next_entry(fp, sizeof(u32)*3);
- if (!buf)
+ rc = next_entry(buf, fp, sizeof(u32)*3);
+ if (rc < 0)
goto bad;
e->expr_type = le32_to_cpu(buf[0]);
e->attr = le32_to_cpu(buf[1]);
e->op = le32_to_cpu(buf[2]);
+ rc = -EINVAL;
switch (e->expr_type) {
case CEXPR_NOT:
if (depth < 0)
rc = hashtab_insert(h, key, cladatum);
if (rc)
goto bad;
+
+ rc = 0;
out:
return rc;
bad:
char *key = NULL;
struct role_datum *role;
int rc;
- u32 *buf, len;
+ u32 buf[2], len;
role = kmalloc(sizeof(*role), GFP_KERNEL);
if (!role) {
}
memset(role, 0, sizeof(*role));
- buf = next_entry(fp, sizeof(u32)*2);
- if (!buf) {
- rc = -EINVAL;
+ rc = next_entry(buf, fp, sizeof buf);
+ if (rc < 0)
goto bad;
- }
len = le32_to_cpu(buf[0]);
role->value = le32_to_cpu(buf[1]);
- buf = next_entry(fp, len);
- if (!buf) {
- rc = -EINVAL;
- goto bad;
- }
key = kmalloc(len + 1,GFP_KERNEL);
if (!key) {
rc = -ENOMEM;
goto bad;
}
- memcpy(key, buf, len);
+ rc = next_entry(key, fp, len);
+ if (rc < 0)
+ goto bad;
key[len] = 0;
rc = ebitmap_read(&role->dominates, fp);
char *key = NULL;
struct type_datum *typdatum;
int rc;
- u32 *buf, len;
+ u32 buf[3], len;
typdatum = kmalloc(sizeof(*typdatum),GFP_KERNEL);
if (!typdatum) {
}
memset(typdatum, 0, sizeof(*typdatum));
- buf = next_entry(fp, sizeof(u32)*3);
- if (!buf) {
- rc = -EINVAL;
+ rc = next_entry(buf, fp, sizeof buf);
+ if (rc < 0)
goto bad;
- }
len = le32_to_cpu(buf[0]);
typdatum->value = le32_to_cpu(buf[1]);
typdatum->primary = le32_to_cpu(buf[2]);
- buf = next_entry(fp, len);
- if (!buf) {
- rc = -EINVAL;
- goto bad;
- }
key = kmalloc(len + 1,GFP_KERNEL);
if (!key) {
rc = -ENOMEM;
goto bad;
}
- memcpy(key, buf, len);
+ rc = next_entry(key, fp, len);
+ if (rc < 0)
+ goto bad;
key[len] = 0;
rc = hashtab_insert(h, key, typdatum);
char *key = NULL;
struct user_datum *usrdatum;
int rc;
- u32 *buf, len;
+ u32 buf[2], len;
usrdatum = kmalloc(sizeof(*usrdatum), GFP_KERNEL);
}
memset(usrdatum, 0, sizeof(*usrdatum));
- buf = next_entry(fp, sizeof(u32)*2);
- if (!buf) {
- rc = -EINVAL;
+ rc = next_entry(buf, fp, sizeof buf);
+ if (rc < 0)
goto bad;
- }
len = le32_to_cpu(buf[0]);
usrdatum->value = le32_to_cpu(buf[1]);
- buf = next_entry(fp, len);
- if (!buf) {
- rc = -EINVAL;
- goto bad;
- }
key = kmalloc(len + 1,GFP_KERNEL);
if (!key) {
rc = -ENOMEM;
goto bad;
}
- memcpy(key, buf, len);
+ rc = next_entry(key, fp, len);
+ if (rc < 0)
+ goto bad;
key[len] = 0;
rc = ebitmap_read(&usrdatum->roles, fp);
struct role_trans *tr, *ltr;
struct ocontext *l, *c, *newc;
struct genfs *genfs_p, *genfs, *newgenfs;
- int i, j, rc, r_policyvers = 0;
- u32 *buf, len, len2, config, nprim, nel, nel2;
+ int i, j, rc;
+ u32 buf[8], len, len2, config, nprim, nel, nel2;
char *policydb_str;
struct policydb_compat_info *info;
if (rc)
goto out;
- rc = -EINVAL;
/* Read the magic number and string length. */
- buf = next_entry(fp, sizeof(u32)* 2);
- if (!buf)
+ rc = next_entry(buf, fp, sizeof(u32)* 2);
+ if (rc < 0)
goto bad;
for (i = 0; i < 2; i++)
len, strlen(POLICYDB_STRING));
goto bad;
}
- buf = next_entry(fp, len);
- if (!buf) {
- printk(KERN_ERR "security: truncated policydb string identifier\n");
- goto bad;
- }
policydb_str = kmalloc(len + 1,GFP_KERNEL);
if (!policydb_str) {
printk(KERN_ERR "security: unable to allocate memory for policydb "
rc = -ENOMEM;
goto bad;
}
- memcpy(policydb_str, buf, len);
+ rc = next_entry(policydb_str, fp, len);
+ if (rc < 0) {
+ printk(KERN_ERR "security: truncated policydb string identifier\n");
+ kfree(policydb_str);
+ goto bad;
+ }
policydb_str[len] = 0;
if (strcmp(policydb_str, POLICYDB_STRING)) {
printk(KERN_ERR "security: policydb string %s does not match "
policydb_str = NULL;
/* Read the version, config, and table sizes. */
- buf = next_entry(fp, sizeof(u32)*4);
- if (!buf)
+ rc = next_entry(buf, fp, sizeof(u32)*4);
+ if (rc < 0)
goto bad;
for (i = 0; i < 4; i++)
buf[i] = le32_to_cpu(buf[i]);
- r_policyvers = buf[0];
- if (r_policyvers < POLICYDB_VERSION_MIN ||
- r_policyvers > POLICYDB_VERSION_MAX) {
+ p->policyvers = buf[0];
+ if (p->policyvers < POLICYDB_VERSION_MIN ||
+ p->policyvers > POLICYDB_VERSION_MAX) {
printk(KERN_ERR "security: policydb version %d does not match "
"my version range %d-%d\n",
buf[0], POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
}
- info = policydb_lookup_compat(r_policyvers);
+ info = policydb_lookup_compat(p->policyvers);
if (!info) {
printk(KERN_ERR "security: unable to find policy compat info "
- "for version %d\n", r_policyvers);
+ "for version %d\n", p->policyvers);
goto bad;
}
goto bad;
for (i = 0; i < info->sym_num; i++) {
- buf = next_entry(fp, sizeof(u32)*2);
- if (!buf) {
- rc = -EINVAL;
+ rc = next_entry(buf, fp, sizeof(u32)*2);
+ if (rc < 0)
goto bad;
- }
nprim = le32_to_cpu(buf[0]);
nel = le32_to_cpu(buf[1]);
for (j = 0; j < nel; j++) {
if (rc)
goto bad;
- if (r_policyvers >= POLICYDB_VERSION_BOOL) {
+ if (p->policyvers >= POLICYDB_VERSION_BOOL) {
rc = cond_read_list(p, fp);
if (rc)
goto bad;
}
- buf = next_entry(fp, sizeof(u32));
- if (!buf) {
- rc = -EINVAL;
+ rc = next_entry(buf, fp, sizeof(u32));
+ if (rc < 0)
goto bad;
- }
nel = le32_to_cpu(buf[0]);
ltr = NULL;
for (i = 0; i < nel; i++) {
} else {
p->role_tr = tr;
}
- buf = next_entry(fp, sizeof(u32)*3);
- if (!buf) {
- rc = -EINVAL;
+ rc = next_entry(buf, fp, sizeof(u32)*3);
+ if (rc < 0)
goto bad;
- }
tr->role = le32_to_cpu(buf[0]);
tr->type = le32_to_cpu(buf[1]);
tr->new_role = le32_to_cpu(buf[2]);
ltr = tr;
}
- buf = next_entry(fp, sizeof(u32));
- if (!buf) {
- rc = -EINVAL;
+ rc = next_entry(buf, fp, sizeof(u32));
+ if (rc < 0)
goto bad;
- }
nel = le32_to_cpu(buf[0]);
lra = NULL;
for (i = 0; i < nel; i++) {
} else {
p->role_allow = ra;
}
- buf = next_entry(fp, sizeof(u32)*2);
- if (!buf) {
- rc = -EINVAL;
+ rc = next_entry(buf, fp, sizeof(u32)*2);
+ if (rc < 0)
goto bad;
- }
ra->role = le32_to_cpu(buf[0]);
ra->new_role = le32_to_cpu(buf[1]);
lra = ra;
goto bad;
for (i = 0; i < info->ocon_num; i++) {
- buf = next_entry(fp, sizeof(u32));
- if (!buf) {
- rc = -EINVAL;
+ rc = next_entry(buf, fp, sizeof(u32));
+ if (rc < 0)
goto bad;
- }
nel = le32_to_cpu(buf[0]);
l = NULL;
for (j = 0; j < nel; j++) {
rc = -EINVAL;
switch (i) {
case OCON_ISID:
- buf = next_entry(fp, sizeof(u32));
- if (!buf)
+ rc = next_entry(buf, fp, sizeof(u32));
+ if (rc < 0)
goto bad;
c->sid[0] = le32_to_cpu(buf[0]);
rc = context_read_and_validate(&c->context[0], p, fp);
break;
case OCON_FS:
case OCON_NETIF:
- buf = next_entry(fp, sizeof(u32));
- if (!buf)
+ rc = next_entry(buf, fp, sizeof(u32));
+ if (rc < 0)
goto bad;
len = le32_to_cpu(buf[0]);
- buf = next_entry(fp, len);
- if (!buf)
- goto bad;
c->u.name = kmalloc(len + 1,GFP_KERNEL);
if (!c->u.name) {
rc = -ENOMEM;
goto bad;
}
- memcpy(c->u.name, buf, len);
+ rc = next_entry(c->u.name, fp, len);
+ if (rc < 0)
+ goto bad;
c->u.name[len] = 0;
rc = context_read_and_validate(&c->context[0], p, fp);
if (rc)
goto bad;
break;
case OCON_PORT:
- buf = next_entry(fp, sizeof(u32)*3);
- if (!buf)
+ rc = next_entry(buf, fp, sizeof(u32)*3);
+ if (rc < 0)
goto bad;
c->u.port.protocol = le32_to_cpu(buf[0]);
c->u.port.low_port = le32_to_cpu(buf[1]);
goto bad;
break;
case OCON_NODE:
- buf = next_entry(fp, sizeof(u32)* 2);
- if (!buf)
+ rc = next_entry(buf, fp, sizeof(u32)* 2);
+ if (rc < 0)
goto bad;
c->u.node.addr = le32_to_cpu(buf[0]);
c->u.node.mask = le32_to_cpu(buf[1]);
goto bad;
break;
case OCON_FSUSE:
- buf = next_entry(fp, sizeof(u32)*2);
- if (!buf)
+ rc = next_entry(buf, fp, sizeof(u32)*2);
+ if (rc < 0)
goto bad;
c->v.behavior = le32_to_cpu(buf[0]);
if (c->v.behavior > SECURITY_FS_USE_NONE)
goto bad;
len = le32_to_cpu(buf[1]);
- buf = next_entry(fp, len);
- if (!buf)
- goto bad;
c->u.name = kmalloc(len + 1,GFP_KERNEL);
if (!c->u.name) {
rc = -ENOMEM;
goto bad;
}
- memcpy(c->u.name, buf, len);
+ rc = next_entry(c->u.name, fp, len);
+ if (rc < 0)
+ goto bad;
c->u.name[len] = 0;
rc = context_read_and_validate(&c->context[0], p, fp);
if (rc)
case OCON_NODE6: {
int k;
- buf = next_entry(fp, sizeof(u32) * 8);
- if (!buf)
+ rc = next_entry(buf, fp, sizeof(u32) * 8);
+ if (rc < 0)
goto bad;
for (k = 0; k < 4; k++)
c->u.node6.addr[k] = le32_to_cpu(buf[k]);
}
}
- buf = next_entry(fp, sizeof(u32));
- if (!buf) {
- rc = -EINVAL;
+ rc = next_entry(buf, fp, sizeof(u32));
+ if (rc < 0)
goto bad;
- }
nel = le32_to_cpu(buf[0]);
genfs_p = NULL;
rc = -EINVAL;
for (i = 0; i < nel; i++) {
- buf = next_entry(fp, sizeof(u32));
- if (!buf)
+ rc = next_entry(buf, fp, sizeof(u32));
+ if (rc < 0)
goto bad;
len = le32_to_cpu(buf[0]);
- buf = next_entry(fp, len);
- if (!buf)
- goto bad;
newgenfs = kmalloc(sizeof(*newgenfs), GFP_KERNEL);
if (!newgenfs) {
rc = -ENOMEM;
kfree(newgenfs);
goto bad;
}
- memcpy(newgenfs->fstype, buf, len);
+ rc = next_entry(newgenfs->fstype, fp, len);
+ if (rc < 0) {
+ kfree(newgenfs->fstype);
+ kfree(newgenfs);
+ goto bad;
+ }
newgenfs->fstype[len] = 0;
for (genfs_p = NULL, genfs = p->genfs; genfs;
genfs_p = genfs, genfs = genfs->next) {
genfs_p->next = newgenfs;
else
p->genfs = newgenfs;
- buf = next_entry(fp, sizeof(u32));
- if (!buf)
+ rc = next_entry(buf, fp, sizeof(u32));
+ if (rc < 0)
goto bad;
nel2 = le32_to_cpu(buf[0]);
for (j = 0; j < nel2; j++) {
- buf = next_entry(fp, sizeof(u32));
- if (!buf)
+ rc = next_entry(buf, fp, sizeof(u32));
+ if (rc < 0)
goto bad;
len = le32_to_cpu(buf[0]);
- buf = next_entry(fp, len);
- if (!buf)
- goto bad;
newc = kmalloc(sizeof(*newc), GFP_KERNEL);
if (!newc) {
rc = -ENOMEM;
goto bad_newc;
}
- memcpy(newc->u.name, buf, len);
+ rc = next_entry(newc->u.name, fp, len);
+ if (rc < 0)
+ goto bad_newc;
newc->u.name[len] = 0;
- buf = next_entry(fp, sizeof(u32));
- if (!buf)
+ rc = next_entry(buf, fp, sizeof(u32));
+ if (rc < 0)
goto bad_newc;
newc->v.sclass = le32_to_cpu(buf[0]);
if (context_read_and_validate(&newc->context[0], p, fp))
rc = mls_read_trusted(p, fp);
if (rc)
goto bad;
+
+ rc = 0;
out:
- policydb_loaded_version = r_policyvers;
return rc;
bad_newc:
ocontext_destroy(newc,OCON_FSUSE);
bad:
+ if (!rc)
+ rc = -EINVAL;
policydb_destroy(p);
goto out;
}