vserver 1.9.5.x5
[linux-2.6.git] / security / selinux / ss / policydb.c
index e10ed0e..46bc7b6 100644 (file)
@@ -38,8 +38,6 @@ static char *symtab_name[SYM_NUM] = {
 };
 #endif
 
-int policydb_loaded_version;
-
 static unsigned int symtab_sizes[SYM_NUM] = {
        2,
        32,
@@ -633,13 +631,12 @@ static int context_read_and_validate(struct context *c,
                                     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]);
@@ -672,7 +669,7 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
        char *key = NULL;
        struct perm_datum *perdatum;
        int rc;
-       u32 *buf, len;
+       u32 buf[2], len;
 
        perdatum = kmalloc(sizeof(*perdatum), GFP_KERNEL);
        if (!perdatum) {
@@ -681,11 +678,9 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
        }
        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]);
@@ -693,17 +688,14 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
        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);
@@ -720,7 +712,7 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
 {
        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);
@@ -730,11 +722,9 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
        }
        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]);
@@ -745,17 +735,14 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
        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++) {
@@ -780,21 +767,19 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
        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]);
@@ -808,17 +793,14 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
 
        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) {
@@ -827,12 +809,9 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
                        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,
@@ -851,7 +830,6 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
        }
 
        lc = NULL;
-       rc = -EINVAL;
        for (i = 0; i < ncons; i++) {
                c = kmalloc(sizeof(*c), GFP_KERNEL);
                if (!c) {
@@ -866,8 +844,8 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
                        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]);
@@ -887,13 +865,14 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
                                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)
@@ -934,6 +913,8 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
        rc = hashtab_insert(h, key, cladatum);
        if (rc)
                goto bad;
+
+       rc = 0;
 out:
        return rc;
 bad:
@@ -946,7 +927,7 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
        char *key = NULL;
        struct role_datum *role;
        int rc;
-       u32 *buf, len;
+       u32 buf[2], len;
 
        role = kmalloc(sizeof(*role), GFP_KERNEL);
        if (!role) {
@@ -955,26 +936,21 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
        }
        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);
@@ -1011,7 +987,7 @@ static int type_read(struct policydb *p, struct hashtab *h, void *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) {
@@ -1020,27 +996,22 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
        }
        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);
@@ -1058,7 +1029,7 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
        char *key = NULL;
        struct user_datum *usrdatum;
        int rc;
-       u32 *buf, len;
+       u32 buf[2], len;
 
 
        usrdatum = kmalloc(sizeof(*usrdatum), GFP_KERNEL);
@@ -1068,26 +1039,21 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
        }
        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);
@@ -1132,8 +1098,8 @@ int policydb_read(struct policydb *p, void *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;
 
@@ -1144,10 +1110,9 @@ int policydb_read(struct policydb *p, void *fp)
        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++)
@@ -1167,11 +1132,6 @@ int policydb_read(struct policydb *p, void *fp)
                       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 "
@@ -1179,7 +1139,12 @@ int policydb_read(struct policydb *p, void *fp)
                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 "
@@ -1192,15 +1157,15 @@ int policydb_read(struct policydb *p, void *fp)
        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);
@@ -1216,10 +1181,10 @@ int policydb_read(struct policydb *p, void *fp)
        }
 
 
-       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;
        }
 
@@ -1235,11 +1200,9 @@ int policydb_read(struct policydb *p, void *fp)
                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++) {
@@ -1255,17 +1218,15 @@ int policydb_read(struct policydb *p, void *fp)
        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++) {
@@ -1280,22 +1241,18 @@ int policydb_read(struct policydb *p, void *fp)
                } 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++) {
@@ -1310,11 +1267,9 @@ int policydb_read(struct policydb *p, void *fp)
                } 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;
@@ -1329,11 +1284,9 @@ int policydb_read(struct policydb *p, void *fp)
                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++) {
@@ -1352,8 +1305,8 @@ int policydb_read(struct policydb *p, void *fp)
                        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);
@@ -1362,19 +1315,18 @@ int policydb_read(struct policydb *p, void *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)
@@ -1384,8 +1336,8 @@ int policydb_read(struct policydb *p, void *fp)
                                        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]);
@@ -1395,8 +1347,8 @@ int policydb_read(struct policydb *p, void *fp)
                                        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]);
@@ -1405,22 +1357,21 @@ int policydb_read(struct policydb *p, void *fp)
                                        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)
@@ -1429,8 +1380,8 @@ int policydb_read(struct policydb *p, void *fp)
                        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]);
@@ -1444,22 +1395,17 @@ int policydb_read(struct policydb *p, void *fp)
                }
        }
 
-       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;
@@ -1473,7 +1419,12 @@ int policydb_read(struct policydb *p, void *fp)
                        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) {
@@ -1492,18 +1443,15 @@ int policydb_read(struct policydb *p, void *fp)
                        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) {
@@ -1517,10 +1465,12 @@ int policydb_read(struct policydb *p, void *fp)
                                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))
@@ -1552,12 +1502,15 @@ int policydb_read(struct policydb *p, void *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;
 }