SELinux: break ocontext reading into a separate function

Move the reading of ocontext type data out of policydb_read() in a separate
function ocontext_read()

Signed-off-by: Eric Paris <eparis@redhat.com>
Acked-by:  Stephen D. Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
This commit is contained in:
Eric Paris 2010-07-21 12:51:03 -04:00 committed by James Morris
parent d1b43547e5
commit 692a8a231b
1 changed files with 133 additions and 111 deletions

View File

@ -1901,6 +1901,136 @@ static int genfs_read(struct policydb *p, void *fp)
return rc;
}
static int ocontext_read(struct policydb *p, struct policydb_compat_info *info,
void *fp)
{
int i, j, rc;
u32 nel, len;
__le32 buf[3];
struct ocontext *l, *c;
u32 nodebuf[8];
for (i = 0; i < info->ocon_num; i++) {
rc = next_entry(buf, fp, sizeof(u32));
if (rc)
goto out;
nel = le32_to_cpu(buf[0]);
l = NULL;
for (j = 0; j < nel; j++) {
rc = -ENOMEM;
c = kzalloc(sizeof(*c), GFP_KERNEL);
if (!c)
goto out;
if (l)
l->next = c;
else
p->ocontexts[i] = c;
l = c;
switch (i) {
case OCON_ISID:
rc = next_entry(buf, fp, sizeof(u32));
if (rc)
goto out;
c->sid[0] = le32_to_cpu(buf[0]);
rc = context_read_and_validate(&c->context[0], p, fp);
if (rc)
goto out;
break;
case OCON_FS:
case OCON_NETIF:
rc = next_entry(buf, fp, sizeof(u32));
if (rc)
goto out;
len = le32_to_cpu(buf[0]);
rc = -ENOMEM;
c->u.name = kmalloc(len + 1, GFP_KERNEL);
if (!c->u.name)
goto out;
rc = next_entry(c->u.name, fp, len);
if (rc)
goto out;
c->u.name[len] = 0;
rc = context_read_and_validate(&c->context[0], p, fp);
if (rc)
goto out;
rc = context_read_and_validate(&c->context[1], p, fp);
if (rc)
goto out;
break;
case OCON_PORT:
rc = next_entry(buf, fp, sizeof(u32)*3);
if (rc)
goto out;
c->u.port.protocol = le32_to_cpu(buf[0]);
c->u.port.low_port = le32_to_cpu(buf[1]);
c->u.port.high_port = le32_to_cpu(buf[2]);
rc = context_read_and_validate(&c->context[0], p, fp);
if (rc)
goto out;
break;
case OCON_NODE:
rc = next_entry(nodebuf, fp, sizeof(u32) * 2);
if (rc)
goto out;
c->u.node.addr = nodebuf[0]; /* network order */
c->u.node.mask = nodebuf[1]; /* network order */
rc = context_read_and_validate(&c->context[0], p, fp);
if (rc)
goto out;
break;
case OCON_FSUSE:
rc = next_entry(buf, fp, sizeof(u32)*2);
if (rc)
goto out;
rc = -EINVAL;
c->v.behavior = le32_to_cpu(buf[0]);
if (c->v.behavior > SECURITY_FS_USE_NONE)
goto out;
rc = -ENOMEM;
len = le32_to_cpu(buf[1]);
c->u.name = kmalloc(len + 1, GFP_KERNEL);
if (!c->u.name)
goto out;
rc = next_entry(c->u.name, fp, len);
if (rc)
goto out;
c->u.name[len] = 0;
rc = context_read_and_validate(&c->context[0], p, fp);
if (rc)
goto out;
break;
case OCON_NODE6: {
int k;
rc = next_entry(nodebuf, fp, sizeof(u32) * 8);
if (rc)
goto out;
for (k = 0; k < 4; k++)
c->u.node6.addr[k] = nodebuf[k];
for (k = 0; k < 4; k++)
c->u.node6.mask[k] = nodebuf[k+4];
rc = context_read_and_validate(&c->context[0], p, fp);
if (rc)
goto out;
break;
}
}
}
}
rc = 0;
out:
return rc;
}
/*
* Read the configuration data from a policy database binary
* representation file into a policy database structure.
@ -1909,10 +2039,8 @@ int policydb_read(struct policydb *p, void *fp)
{
struct role_allow *ra, *lra;
struct role_trans *tr, *ltr;
struct ocontext *l, *c;
int i, j, rc;
__le32 buf[4];
u32 nodebuf[8];
u32 len, nprim, nel;
char *policydb_str;
@ -2117,115 +2245,9 @@ int policydb_read(struct policydb *p, void *fp)
if (!p->process_trans_perms)
goto bad;
for (i = 0; i < info->ocon_num; i++) {
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++) {
c = kzalloc(sizeof(*c), GFP_KERNEL);
if (!c) {
rc = -ENOMEM;
goto bad;
}
if (l)
l->next = c;
else
p->ocontexts[i] = c;
l = c;
rc = -EINVAL;
switch (i) {
case OCON_ISID:
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);
if (rc)
goto bad;
break;
case OCON_FS:
case OCON_NETIF:
rc = next_entry(buf, fp, sizeof(u32));
if (rc < 0)
goto bad;
len = le32_to_cpu(buf[0]);
c->u.name = kmalloc(len + 1, GFP_KERNEL);
if (!c->u.name) {
rc = -ENOMEM;
goto bad;
}
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;
rc = context_read_and_validate(&c->context[1], p, fp);
if (rc)
goto bad;
break;
case OCON_PORT:
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]);
c->u.port.high_port = le32_to_cpu(buf[2]);
rc = context_read_and_validate(&c->context[0], p, fp);
if (rc)
goto bad;
break;
case OCON_NODE:
rc = next_entry(nodebuf, fp, sizeof(u32) * 2);
if (rc < 0)
goto bad;
c->u.node.addr = nodebuf[0]; /* network order */
c->u.node.mask = nodebuf[1]; /* network order */
rc = context_read_and_validate(&c->context[0], p, fp);
if (rc)
goto bad;
break;
case OCON_FSUSE:
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]);
c->u.name = kmalloc(len + 1, GFP_KERNEL);
if (!c->u.name) {
rc = -ENOMEM;
goto bad;
}
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_NODE6: {
int k;
rc = next_entry(nodebuf, fp, sizeof(u32) * 8);
if (rc < 0)
goto bad;
for (k = 0; k < 4; k++)
c->u.node6.addr[k] = nodebuf[k];
for (k = 0; k < 4; k++)
c->u.node6.mask[k] = nodebuf[k+4];
if (context_read_and_validate(&c->context[0], p, fp))
goto bad;
break;
}
}
}
}
rc = ocontext_read(p, info, fp);
if (rc)
goto bad;
rc = genfs_read(p, fp);
if (rc)