📄 policydb.c
字号:
gtmp = g; g = g->next; kfree(gtmp); } cond_policydb_destroy(p); for (tr = p->role_tr; tr; tr = tr->next) { kfree(ltr); ltr = tr; } kfree(ltr); for (ra = p->role_allow; ra; ra = ra -> next) { kfree(lra); lra = ra; } kfree(lra); for (rt = p->range_tr; rt; rt = rt -> next) { kfree(lrt); lrt = rt; } kfree(lrt); if (p->type_attr_map) { for (i = 0; i < p->p_types.nprim; i++) ebitmap_destroy(&p->type_attr_map[i]); } kfree(p->type_attr_map); return;}/* * Load the initial SIDs specified in a policy database * structure into a SID table. */int policydb_load_isids(struct policydb *p, struct sidtab *s){ struct ocontext *head, *c; int rc; rc = sidtab_init(s); if (rc) { printk(KERN_ERR "security: out of memory on SID table init\n"); goto out; } head = p->ocontexts[OCON_ISID]; for (c = head; c; c = c->next) { if (!c->context[0].user) { printk(KERN_ERR "security: SID %s was never " "defined.\n", c->u.name); rc = -EINVAL; goto out; } if (sidtab_insert(s, c->sid[0], &c->context[0])) { printk(KERN_ERR "security: unable to load initial " "SID %s.\n", c->u.name); rc = -EINVAL; goto out; } }out: return rc;}/* * Return 1 if the fields in the security context * structure `c' are valid. Return 0 otherwise. */int policydb_context_isvalid(struct policydb *p, struct context *c){ struct role_datum *role; struct user_datum *usrdatum; if (!c->role || c->role > p->p_roles.nprim) return 0; if (!c->user || c->user > p->p_users.nprim) return 0; if (!c->type || c->type > p->p_types.nprim) return 0; if (c->role != OBJECT_R_VAL) { /* * Role must be authorized for the type. */ role = p->role_val_to_struct[c->role - 1]; if (!ebitmap_get_bit(&role->types, c->type - 1)) /* role may not be associated with type */ return 0; /* * User must be authorized for the role. */ usrdatum = p->user_val_to_struct[c->user - 1]; if (!usrdatum) return 0; if (!ebitmap_get_bit(&usrdatum->roles, c->role - 1)) /* user may not be associated with role */ return 0; } if (!mls_context_isvalid(p, c)) return 0; return 1;}/* * Read a MLS range structure from a policydb binary * representation file. */static int mls_read_range_helper(struct mls_range *r, void *fp){ __le32 buf[2]; u32 items; int rc; rc = next_entry(buf, fp, sizeof(u32)); if (rc < 0) goto out; items = le32_to_cpu(buf[0]); if (items > ARRAY_SIZE(buf)) { printk(KERN_ERR "security: mls: range overflow\n"); rc = -EINVAL; goto out; } rc = next_entry(buf, fp, sizeof(u32) * items); if (rc < 0) { printk(KERN_ERR "security: mls: truncated range\n"); goto out; } r->level[0].sens = le32_to_cpu(buf[0]); if (items > 1) r->level[1].sens = le32_to_cpu(buf[1]); else r->level[1].sens = r->level[0].sens; rc = ebitmap_read(&r->level[0].cat, fp); if (rc) { printk(KERN_ERR "security: mls: error reading low " "categories\n"); goto out; } if (items > 1) { rc = ebitmap_read(&r->level[1].cat, fp); if (rc) { printk(KERN_ERR "security: mls: error reading high " "categories\n"); goto bad_high; } } else { rc = ebitmap_cpy(&r->level[1].cat, &r->level[0].cat); if (rc) { printk(KERN_ERR "security: mls: out of memory\n"); goto bad_high; } } rc = 0;out: return rc;bad_high: ebitmap_destroy(&r->level[0].cat); goto out;}/* * Read and validate a security context structure * from a policydb binary representation file. */static int context_read_and_validate(struct context *c, struct policydb *p, void *fp){ __le32 buf[3]; int rc; rc = next_entry(buf, fp, sizeof buf); if (rc < 0) { printk(KERN_ERR "security: context truncated\n"); goto out; } c->user = le32_to_cpu(buf[0]); c->role = le32_to_cpu(buf[1]); c->type = le32_to_cpu(buf[2]); if (p->policyvers >= POLICYDB_VERSION_MLS) { if (mls_read_range_helper(&c->range, fp)) { printk(KERN_ERR "security: error reading MLS range of " "context\n"); rc = -EINVAL; goto out; } } if (!policydb_context_isvalid(p, c)) { printk(KERN_ERR "security: invalid security context\n"); context_destroy(c); rc = -EINVAL; }out: return rc;}/* * The following *_read functions are used to * read the symbol data from a policy database * binary representation file. */static int perm_read(struct policydb *p, struct hashtab *h, void *fp){ char *key = NULL; struct perm_datum *perdatum; int rc; __le32 buf[2]; u32 len; perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL); if (!perdatum) { rc = -ENOMEM; goto out; } 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]); key = kmalloc(len + 1,GFP_KERNEL); if (!key) { rc = -ENOMEM; goto bad; } rc = next_entry(key, fp, len); if (rc < 0) goto bad; key[len] = 0; rc = hashtab_insert(h, key, perdatum); if (rc) goto bad;out: return rc;bad: perm_destroy(key, perdatum, NULL); goto out;}static int common_read(struct policydb *p, struct hashtab *h, void *fp){ char *key = NULL; struct common_datum *comdatum; __le32 buf[4]; u32 len, nel; int i, rc; comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL); if (!comdatum) { rc = -ENOMEM; goto out; } 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]); rc = symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE); if (rc) goto bad; comdatum->permissions.nprim = le32_to_cpu(buf[2]); nel = le32_to_cpu(buf[3]); key = kmalloc(len + 1,GFP_KERNEL); if (!key) { rc = -ENOMEM; goto bad; } rc = next_entry(key, fp, len); if (rc < 0) goto bad; key[len] = 0; for (i = 0; i < nel; i++) { rc = perm_read(p, comdatum->permissions.table, fp); if (rc) goto bad; } rc = hashtab_insert(h, key, comdatum); if (rc) goto bad;out: return rc;bad: common_destroy(key, comdatum, NULL); goto out;}static int read_cons_helper(struct constraint_node **nodep, int ncons, int allowxtarget, void *fp){ struct constraint_node *c, *lc; struct constraint_expr *e, *le; __le32 buf[3]; u32 nexpr; int rc, i, j, depth; lc = NULL; for (i = 0; i < ncons; i++) { c = kzalloc(sizeof(*c), GFP_KERNEL); if (!c) return -ENOMEM; if (lc) { lc->next = c; } else { *nodep = c; } rc = next_entry(buf, fp, (sizeof(u32) * 2)); if (rc < 0) return rc; c->permissions = le32_to_cpu(buf[0]); nexpr = le32_to_cpu(buf[1]); le = NULL; depth = -1; for (j = 0; j < nexpr; j++) { e = kzalloc(sizeof(*e), GFP_KERNEL); if (!e) return -ENOMEM; if (le) { le->next = e; } else { c->expr = e; } rc = next_entry(buf, fp, (sizeof(u32) * 3)); if (rc < 0) return rc; e->expr_type = le32_to_cpu(buf[0]); e->attr = le32_to_cpu(buf[1]); e->op = le32_to_cpu(buf[2]); switch (e->expr_type) { case CEXPR_NOT: if (depth < 0) return -EINVAL; break; case CEXPR_AND: case CEXPR_OR: if (depth < 1) return -EINVAL; depth--; break; case CEXPR_ATTR: if (depth == (CEXPR_MAXDEPTH - 1)) return -EINVAL; depth++; break; case CEXPR_NAMES: if (!allowxtarget && (e->attr & CEXPR_XTARGET)) return -EINVAL; if (depth == (CEXPR_MAXDEPTH - 1)) return -EINVAL; depth++; if (ebitmap_read(&e->names, fp)) return -EINVAL; break; default: return -EINVAL; } le = e; } if (depth != 0) return -EINVAL; lc = c; } return 0;}static int class_read(struct policydb *p, struct hashtab *h, void *fp){ char *key = NULL; struct class_datum *cladatum; __le32 buf[6]; u32 len, len2, ncons, nel; int i, rc; cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL); if (!cladatum) { rc = -ENOMEM; goto out; } 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]); cladatum->value = le32_to_cpu(buf[2]); rc = symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE); if (rc) goto bad; cladatum->permissions.nprim = le32_to_cpu(buf[3]); nel = le32_to_cpu(buf[4]); ncons = le32_to_cpu(buf[5]); key = kmalloc(len + 1,GFP_KERNEL); if (!key) { rc = -ENOMEM; goto bad; } rc = next_entry(key, fp, len); if (rc < 0) goto bad; key[len] = 0; if (len2) { cladatum->comkey = kmalloc(len2 + 1,GFP_KERNEL); if (!cladatum->comkey) { rc = -ENOMEM; goto bad; } rc = next_entry(cladatum->comkey, fp, len2); if (rc < 0) goto bad; cladatum->comkey[len2] = 0; cladatum->comdatum = hashtab_search(p->p_commons.table, cladatum->comkey); if (!cladatum->comdatum) { printk(KERN_ERR "security: unknown common %s\n", cladatum->comkey); rc = -EINVAL; goto bad; } } for (i = 0; i < nel; i++) { rc = perm_read(p, cladatum->permissions.table, fp); if (rc) goto bad; } rc = read_cons_helper(&cladatum->constraints, ncons, 0, fp); if (rc) goto bad; if (p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) { /* grab the validatetrans rules */ rc = next_entry(buf, fp, sizeof(u32)); if (rc < 0) goto bad; ncons = le32_to_cpu(buf[0]); rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, fp); if (rc) goto bad; } rc = hashtab_insert(h, key, cladatum); if (rc) goto bad; rc = 0;out: return rc;bad: class_destroy(key, cladatum, NULL); goto out;}static int role_read(struct policydb *p, struct hashtab *h, void *fp){ char *key = NULL; struct role_datum *role; int rc; __le32 buf[2]; u32 len; role = kzalloc(sizeof(*role), GFP_KERNEL); if (!role) { rc = -ENOMEM; goto out; } 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]); key = kmalloc(len + 1,GFP_KERNEL); if (!key) { rc = -ENOMEM; goto bad; } rc = next_entry(key, fp, len); if (rc < 0) goto bad; key[len] = 0; rc = ebitmap_read(&role->dominates, fp); if (rc) goto bad; rc = ebitmap_read(&role->types, fp); if (rc) goto bad; if (strcmp(key, OBJECT_R) == 0) { if (role->value != OBJECT_R_VAL) { printk(KERN_ERR "Role %s has wrong value %d\n", OBJECT_R, role->value); rc = -EINVAL; goto bad; } rc = 0; goto bad; } rc = hashtab_insert(h, key, role); if (rc) goto bad;out: return rc;bad: role_destroy(key, role, NULL); goto out;}static int type_read(struct policydb *p, struct hashtab *h, void *fp){ char *key = NULL; struct type_datum *typdatum; int rc; __le32 buf[3]; u32 len; typdatum = kzalloc(sizeof(*typdatum),GFP_KERNEL); if (!typdatum) { rc = -ENOMEM; return rc; } 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]); key = kmalloc(len + 1,GFP_KERNEL); if (!key) { rc = -ENOMEM; goto bad; } rc = next_entry(key, fp, len); if (rc < 0) goto bad; key[len] = 0; rc = hashtab_insert(h, key, typdatum); if (rc) goto bad;out: return rc;bad: type_destroy(key, typdatum, NULL); goto out;}/* * Read a MLS level structure from a policydb binary * representation file. */static int mls_read_level(struct mls_level *lp, void *fp){ __le32 buf[1]; int rc; memset(lp, 0, sizeof(*lp)); rc = next_entry(buf, fp, sizeof buf); if (rc < 0) { printk(KERN_ERR "security: mls: truncated level\n"); goto bad; } lp->sens = le32_to_cpu(buf[0]); if (ebitmap_read(&lp->cat, fp)) { printk(KERN_ERR "security: mls: error reading level " "categories\n"); goto bad; } return 0;bad: return -EINVAL;}static int user_read(struct policydb *p, struct hashtab *h, void *fp){ char *key = NULL; struct user_datum *usrdatum; int rc;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -