Commit d1b43547 authored by Eric Paris's avatar Eric Paris Committed by James Morris

SELinux: move genfs read to a separate function

move genfs read functionality out of policydb_read() and into a new
function called genfs_read()
Signed-off-by: default avatarEric Paris <eparis@redhat.com>
Acked-by: default avatarStephen D. Smalley <sds@tycho.nsa.gov>
Signed-off-by: default avatarJames Morris <jmorris@namei.org>
parent 9a798279
...@@ -655,6 +655,9 @@ static int range_tr_destroy(void *key, void *datum, void *p) ...@@ -655,6 +655,9 @@ static int range_tr_destroy(void *key, void *datum, void *p)
static void ocontext_destroy(struct ocontext *c, int i) static void ocontext_destroy(struct ocontext *c, int i)
{ {
if (!c)
return;
context_destroy(&c->context[0]); context_destroy(&c->context[0]);
context_destroy(&c->context[1]); context_destroy(&c->context[1]);
if (i == OCON_ISID || i == OCON_FS || if (i == OCON_ISID || i == OCON_FS ||
...@@ -1773,6 +1776,131 @@ static int range_read(struct policydb *p, void *fp) ...@@ -1773,6 +1776,131 @@ static int range_read(struct policydb *p, void *fp)
return rc; return rc;
} }
static int genfs_read(struct policydb *p, void *fp)
{
int i, j, rc;
u32 nel, nel2, len, len2;
__le32 buf[1];
struct ocontext *l, *c;
struct ocontext *newc = NULL;
struct genfs *genfs_p, *genfs;
struct genfs *newgenfs = NULL;
rc = next_entry(buf, fp, sizeof(u32));
if (rc)
goto out;
nel = le32_to_cpu(buf[0]);
for (i = 0; i < nel; i++) {
rc = next_entry(buf, fp, sizeof(u32));
if (rc)
goto out;
len = le32_to_cpu(buf[0]);
rc = -ENOMEM;
newgenfs = kzalloc(sizeof(*newgenfs), GFP_KERNEL);
if (!newgenfs)
goto out;
rc = -ENOMEM;
newgenfs->fstype = kmalloc(len + 1, GFP_KERNEL);
if (!newgenfs->fstype)
goto out;
rc = next_entry(newgenfs->fstype, fp, len);
if (rc)
goto out;
newgenfs->fstype[len] = 0;
for (genfs_p = NULL, genfs = p->genfs; genfs;
genfs_p = genfs, genfs = genfs->next) {
rc = -EINVAL;
if (strcmp(newgenfs->fstype, genfs->fstype) == 0) {
printk(KERN_ERR "SELinux: dup genfs fstype %s\n",
newgenfs->fstype);
goto out;
}
if (strcmp(newgenfs->fstype, genfs->fstype) < 0)
break;
}
newgenfs->next = genfs;
if (genfs_p)
genfs_p->next = newgenfs;
else
p->genfs = newgenfs;
genfs = newgenfs;
newgenfs = NULL;
rc = next_entry(buf, fp, sizeof(u32));
if (rc)
goto out;
nel2 = le32_to_cpu(buf[0]);
for (j = 0; j < nel2; j++) {
rc = next_entry(buf, fp, sizeof(u32));
if (rc)
goto out;
len = le32_to_cpu(buf[0]);
rc = -ENOMEM;
newc = kzalloc(sizeof(*newc), GFP_KERNEL);
if (!newc)
goto out;
rc = -ENOMEM;
newc->u.name = kmalloc(len + 1, GFP_KERNEL);
if (!newc->u.name)
goto out;
rc = next_entry(newc->u.name, fp, len);
if (rc)
goto out;
newc->u.name[len] = 0;
rc = next_entry(buf, fp, sizeof(u32));
if (rc)
goto out;
newc->v.sclass = le32_to_cpu(buf[0]);
rc = context_read_and_validate(&newc->context[0], p, fp);
if (rc)
goto out;
for (l = NULL, c = genfs->head; c;
l = c, c = c->next) {
rc = -EINVAL;
if (!strcmp(newc->u.name, c->u.name) &&
(!c->v.sclass || !newc->v.sclass ||
newc->v.sclass == c->v.sclass)) {
printk(KERN_ERR "SELinux: dup genfs entry (%s,%s)\n",
genfs->fstype, c->u.name);
goto out;
}
len = strlen(newc->u.name);
len2 = strlen(c->u.name);
if (len > len2)
break;
}
newc->next = c;
if (l)
l->next = newc;
else
genfs->head = newc;
newc = NULL;
}
}
rc = 0;
out:
if (newgenfs)
kfree(newgenfs->fstype);
kfree(newgenfs);
ocontext_destroy(newc, OCON_FSUSE);
return rc;
}
/* /*
* Read the configuration data from a policy database binary * Read the configuration data from a policy database binary
* representation file into a policy database structure. * representation file into a policy database structure.
...@@ -1781,12 +1909,12 @@ int policydb_read(struct policydb *p, void *fp) ...@@ -1781,12 +1909,12 @@ int policydb_read(struct policydb *p, void *fp)
{ {
struct role_allow *ra, *lra; struct role_allow *ra, *lra;
struct role_trans *tr, *ltr; struct role_trans *tr, *ltr;
struct ocontext *l, *c, *newc; struct ocontext *l, *c;
struct genfs *genfs_p, *genfs, *newgenfs;
int i, j, rc; int i, j, rc;
__le32 buf[4]; __le32 buf[4];
u32 nodebuf[8]; u32 nodebuf[8];
u32 len, len2, nprim, nel, nel2; u32 len, nprim, nel;
char *policydb_str; char *policydb_str;
struct policydb_compat_info *info; struct policydb_compat_info *info;
...@@ -2099,107 +2227,9 @@ int policydb_read(struct policydb *p, void *fp) ...@@ -2099,107 +2227,9 @@ int policydb_read(struct policydb *p, void *fp)
} }
} }
rc = next_entry(buf, fp, sizeof(u32)); rc = genfs_read(p, fp);
if (rc < 0) if (rc)
goto bad; goto bad;
nel = le32_to_cpu(buf[0]);
genfs_p = NULL;
rc = -EINVAL;
for (i = 0; i < nel; i++) {
rc = next_entry(buf, fp, sizeof(u32));
if (rc < 0)
goto bad;
len = le32_to_cpu(buf[0]);
newgenfs = kzalloc(sizeof(*newgenfs), GFP_KERNEL);
if (!newgenfs) {
rc = -ENOMEM;
goto bad;
}
newgenfs->fstype = kmalloc(len + 1, GFP_KERNEL);
if (!newgenfs->fstype) {
rc = -ENOMEM;
kfree(newgenfs);
goto bad;
}
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) {
if (strcmp(newgenfs->fstype, genfs->fstype) == 0) {
printk(KERN_ERR "SELinux: dup genfs "
"fstype %s\n", newgenfs->fstype);
kfree(newgenfs->fstype);
kfree(newgenfs);
goto bad;
}
if (strcmp(newgenfs->fstype, genfs->fstype) < 0)
break;
}
newgenfs->next = genfs;
if (genfs_p)
genfs_p->next = newgenfs;
else
p->genfs = newgenfs;
rc = next_entry(buf, fp, sizeof(u32));
if (rc < 0)
goto bad;
nel2 = le32_to_cpu(buf[0]);
for (j = 0; j < nel2; j++) {
rc = next_entry(buf, fp, sizeof(u32));
if (rc < 0)
goto bad;
len = le32_to_cpu(buf[0]);
newc = kzalloc(sizeof(*newc), GFP_KERNEL);
if (!newc) {
rc = -ENOMEM;
goto bad;
}
newc->u.name = kmalloc(len + 1, GFP_KERNEL);
if (!newc->u.name) {
rc = -ENOMEM;
goto bad_newc;
}
rc = next_entry(newc->u.name, fp, len);
if (rc < 0)
goto bad_newc;
newc->u.name[len] = 0;
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))
goto bad_newc;
for (l = NULL, c = newgenfs->head; c;
l = c, c = c->next) {
if (!strcmp(newc->u.name, c->u.name) &&
(!c->v.sclass || !newc->v.sclass ||
newc->v.sclass == c->v.sclass)) {
printk(KERN_ERR "SELinux: dup genfs "
"entry (%s,%s)\n",
newgenfs->fstype, c->u.name);
goto bad_newc;
}
len = strlen(newc->u.name);
len2 = strlen(c->u.name);
if (len > len2)
break;
}
newc->next = c;
if (l)
l->next = newc;
else
newgenfs->head = newc;
}
}
rc = range_read(p, fp); rc = range_read(p, fp);
if (rc) if (rc)
...@@ -2227,8 +2257,6 @@ int policydb_read(struct policydb *p, void *fp) ...@@ -2227,8 +2257,6 @@ int policydb_read(struct policydb *p, void *fp)
rc = 0; rc = 0;
out: out:
return rc; return rc;
bad_newc:
ocontext_destroy(newc, OCON_FSUSE);
bad: bad:
if (!rc) if (!rc)
rc = -EINVAL; rc = -EINVAL;
......
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