📄 policydb.c
字号:
rc = hashtab_insert(h, key, typdatum); if (rc) goto bad;out: return rc;bad: type_destroy(key, typdatum, NULL); goto out;}static int user_read(struct policydb *p, struct hashtab *h, void *fp){ char *key = NULL; struct user_datum *usrdatum; int rc; u32 *buf, len; usrdatum = kmalloc(sizeof(*usrdatum), GFP_KERNEL); if (!usrdatum) { rc = -ENOMEM; goto out; } memset(usrdatum, 0, sizeof(*usrdatum)); buf = next_entry(fp, sizeof(u32)*2); if (!buf) { rc = -EINVAL; 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); key[len] = 0; rc = ebitmap_read(&usrdatum->roles, fp); if (rc) goto bad; rc = mls_read_user(usrdatum, fp); if (rc) goto bad; rc = hashtab_insert(h, key, usrdatum); if (rc) goto bad;out: return rc;bad: user_destroy(key, usrdatum, NULL); goto out;}static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp) ={ common_read, class_read, role_read, type_read, user_read, mls_read_f cond_read_bool};#define mls_config(x) \ ((x) & POLICYDB_CONFIG_MLS) ? "mls" : "no_mls"/* * Read the configuration data from a policy database binary * representation file into a policy database structure. */int policydb_read(struct policydb *p, void *fp){ struct role_allow *ra, *lra; 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; char *policydb_str; struct policydb_compat_info *info; config = 0; mls_set_config(config); rc = policydb_init(p); if (rc) goto out; rc = -EINVAL; /* Read the magic number and string length. */ buf = next_entry(fp, sizeof(u32)* 2); if (!buf) goto bad; for (i = 0; i < 2; i++) buf[i] = le32_to_cpu(buf[i]); if (buf[0] != POLICYDB_MAGIC) { printk(KERN_ERR "security: policydb magic number 0x%x does " "not match expected magic number 0x%x\n", buf[0], POLICYDB_MAGIC); goto bad; } len = buf[1]; if (len != strlen(POLICYDB_STRING)) { printk(KERN_ERR "security: policydb string length %d does not " "match expected length %Zu\n", 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 " "string of length %d\n", len); rc = -ENOMEM; goto bad; } memcpy(policydb_str, buf, len); policydb_str[len] = 0; if (strcmp(policydb_str, POLICYDB_STRING)) { printk(KERN_ERR "security: policydb string %s does not match " "my string %s\n", policydb_str, POLICYDB_STRING); kfree(policydb_str); goto bad; } /* Done with policydb_str. */ kfree(policydb_str); policydb_str = NULL; /* Read the version, config, and table sizes. */ buf = next_entry(fp, sizeof(u32)*4); if (!buf) 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) { printk(KERN_ERR "security: policydb version %d does not match " "my version range %d-%d\n", buf[0], POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX); goto bad; } if (buf[1] != config) { printk(KERN_ERR "security: policydb configuration (%s) does " "not match my configuration (%s)\n", mls_config(buf[1]), mls_config(config)); goto bad; } info = policydb_lookup_compat(r_policyvers); if (!info) { printk(KERN_ERR "security: unable to find policy compat info " "for version %d\n", r_policyvers); goto bad; } if (buf[2] != info->sym_num || buf[3] != info->ocon_num) { printk(KERN_ERR "security: policydb table sizes (%d,%d) do " "not match mine (%d,%d)\n", buf[2], buf[3], info->sym_num, info->ocon_num); goto bad; } rc = mls_read_nlevels(p, fp); if (rc) goto bad; for (i = 0; i < info->sym_num; i++) { buf = next_entry(fp, sizeof(u32)*2); if (!buf) { rc = -EINVAL; goto bad; } nprim = le32_to_cpu(buf[0]); nel = le32_to_cpu(buf[1]); for (j = 0; j < nel; j++) { rc = read_f[i](p, p->symtab[i].table, fp); if (rc) goto bad; } p->symtab[i].nprim = nprim; } rc = avtab_read(&p->te_avtab, fp, config); if (rc) goto bad; if (r_policyvers >= POLICYDB_VERSION_BOOL) { rc = cond_read_list(p, fp); if (rc) goto bad; } buf = next_entry(fp, sizeof(u32)); if (!buf) { rc = -EINVAL; goto bad; } nel = le32_to_cpu(buf[0]); ltr = NULL; for (i = 0; i < nel; i++) { tr = kmalloc(sizeof(*tr), GFP_KERNEL); if (!tr) { rc = -ENOMEM; goto bad; } memset(tr, 0, sizeof(*tr)); if (ltr) { ltr->next = tr; } else { p->role_tr = tr; } buf = next_entry(fp, sizeof(u32)*3); if (!buf) { rc = -EINVAL; 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; goto bad; } nel = le32_to_cpu(buf[0]); lra = NULL; for (i = 0; i < nel; i++) { ra = kmalloc(sizeof(*ra), GFP_KERNEL); if (!ra) { rc = -ENOMEM; goto bad; } memset(ra, 0, sizeof(*ra)); if (lra) { lra->next = ra; } else { p->role_allow = ra; } buf = next_entry(fp, sizeof(u32)*2); if (!buf) { rc = -EINVAL; goto bad; } ra->role = le32_to_cpu(buf[0]); ra->new_role = le32_to_cpu(buf[1]); lra = ra; } rc = policydb_index_classes(p); if (rc) goto bad; rc = policydb_index_others(p); if (rc) goto bad; for (i = 0; i < info->ocon_num; i++) { buf = next_entry(fp, sizeof(u32)); if (!buf) { rc = -EINVAL; goto bad; } nel = le32_to_cpu(buf[0]); l = NULL; for (j = 0; j < nel; j++) { c = kmalloc(sizeof(*c), GFP_KERNEL); if (!c) { rc = -ENOMEM; goto bad; } memset(c, 0, sizeof(*c)); if (l) { l->next = c; } else { p->ocontexts[i] = c; } l = c; rc = -EINVAL; switch (i) { case OCON_ISID: buf = next_entry(fp, sizeof(u32)); if (!buf) 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: buf = next_entry(fp, sizeof(u32)); if (!buf) 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); 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: buf = next_entry(fp, sizeof(u32)*3); if (!buf) 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: buf = next_entry(fp, sizeof(u32)* 2); if (!buf) goto bad; c->u.node.addr = le32_to_cpu(buf[0]); c->u.node.mask = le32_to_cpu(buf[1]); rc = context_read_and_validate(&c->context[0], p, fp); if (rc) goto bad; break; case OCON_FSUSE: buf = next_entry(fp, sizeof(u32)*2); if (!buf) 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); 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; buf = next_entry(fp, sizeof(u32) * 8); if (!buf) goto bad; for (k = 0; k < 4; k++) c->u.node6.addr[k] = le32_to_cpu(buf[k]); for (k = 0; k < 4; k++) c->u.node6.mask[k] = le32_to_cpu(buf[k+4]); if (context_read_and_validate(&c->context[0], p, fp)) goto bad; break; } } } } buf = next_entry(fp, sizeof(u32)); if (!buf) { rc = -EINVAL; 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) 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; goto bad; } memset(newgenfs, 0, sizeof(*newgenfs)); newgenfs->fstype = kmalloc(len + 1,GFP_KERNEL); if (!newgenfs->fstype) { rc = -ENOMEM; kfree(newgenfs); goto bad; } memcpy(newgenfs->fstype, buf, len); 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 "security: 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; buf = next_entry(fp, sizeof(u32)); if (!buf) goto bad; nel2 = le32_to_cpu(buf[0]); for (j = 0; j < nel2; j++) { buf = next_entry(fp, sizeof(u32)); if (!buf) 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; } memset(newc, 0, sizeof(*newc)); newc->u.name = kmalloc(len + 1,GFP_KERNEL); if (!newc->u.name) { rc = -ENOMEM; goto bad_newc; } memcpy(newc->u.name, buf, len); newc->u.name[len] = 0; buf = next_entry(fp, sizeof(u32)); if (!buf) 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 "security: 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 = mls_read_trusted(p, fp); if (rc) goto bad;out: policydb_loaded_version = r_policyvers; return rc;bad_newc: ocontext_destroy(newc,OCON_FSUSE);bad: policydb_destroy(p); goto out;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -