📄 policydb.c
字号:
c = c->next; ocontext_destroy(ctmp,i); } } g = p->genfs; while (g) { kfree(g->fstype); c = g->head; while (c) { ctmp = c; c = c->next; ocontext_destroy(ctmp,OCON_FSUSE); } gtmp = g; g = g->next; kfree(gtmp); } cond_policydb_destroy(p); 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 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){ u32 *buf; int rc = 0; buf = next_entry(fp, sizeof(u32)*3); if (!buf) { printk(KERN_ERR "security: context truncated\n"); rc = -EINVAL; goto out; } c->user = le32_to_cpu(buf[0]); c->role = le32_to_cpu(buf[1]); c->type = le32_to_cpu(buf[2]); if (mls_read_range(c, 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; u32 *buf, len; perdatum = kmalloc(sizeof(*perdatum), GFP_KERNEL); if (!perdatum) { rc = -ENOMEM; goto out; } memset(perdatum, 0, sizeof(*perdatum)); buf = next_entry(fp, sizeof(u32)*2); if (!buf) { rc = -EINVAL; goto bad; } len = le32_to_cpu(buf[0]); perdatum->value = le32_to_cpu(buf[1]); rc = mls_read_perm(perdatum, 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); 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; u32 *buf, len, nel; int i, rc; comdatum = kmalloc(sizeof(*comdatum), GFP_KERNEL); if (!comdatum) { rc = -ENOMEM; goto out; } memset(comdatum, 0, sizeof(*comdatum)); buf = next_entry(fp, sizeof(u32)*4); if (!buf) { rc = -EINVAL; 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]); 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; 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 class_read(struct policydb *p, struct hashtab *h, void *fp){ char *key = NULL; struct class_datum *cladatum; struct constraint_node *c, *lc; struct constraint_expr *e, *le; u32 *buf, len, len2, ncons, nexpr, nel; int i, j, depth, rc; cladatum = kmalloc(sizeof(*cladatum), GFP_KERNEL); if (!cladatum) { rc = -ENOMEM; goto bad; } memset(cladatum, 0, sizeof(*cladatum)); buf = next_entry(fp, sizeof(u32)*6); if (!buf) { rc = -EINVAL; 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]); 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; if (len2) { cladatum->comkey = kmalloc(len2 + 1,GFP_KERNEL); if (!cladatum->comkey) { rc = -ENOMEM; goto bad; } buf = next_entry(fp, len2); if (!buf) { rc = -EINVAL; goto bad; } memcpy(cladatum->comkey, buf, len2); 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; } lc = NULL; rc = -EINVAL; for (i = 0; i < ncons; i++) { c = kmalloc(sizeof(*c), GFP_KERNEL); if (!c) { rc = -ENOMEM; goto bad; } memset(c, 0, sizeof(*c)); if (lc) { lc->next = c; } else { cladatum->constraints = c; } buf = next_entry(fp, sizeof(u32)*2); if (!buf) goto bad; c->permissions = le32_to_cpu(buf[0]); nexpr = le32_to_cpu(buf[1]); le = NULL; depth = -1; for (j = 0; j < nexpr; j++) { e = kmalloc(sizeof(*e), GFP_KERNEL); if (!e) { rc = -ENOMEM; goto bad; } memset(e, 0, sizeof(*e)); if (le) { le->next = e; } else { c->expr = e; } buf = next_entry(fp, sizeof(u32)*3); if (!buf) goto bad; 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) goto bad; break; case CEXPR_AND: case CEXPR_OR: if (depth < 1) goto bad; depth--; break; case CEXPR_ATTR: if (depth == (CEXPR_MAXDEPTH-1)) goto bad; depth++; break; case CEXPR_NAMES: if (depth == (CEXPR_MAXDEPTH-1)) goto bad; depth++; if (ebitmap_read(&e->names, fp)) goto bad; break; default: goto bad; } le = e; } if (depth != 0) goto bad; lc = c; } rc = mls_read_class(cladatum, fp); if (rc) goto bad; rc = hashtab_insert(h, key, cladatum); if (rc) goto bad;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; u32 *buf, len; role = kmalloc(sizeof(*role), GFP_KERNEL); if (!role) { rc = -ENOMEM; goto out; } memset(role, 0, sizeof(*role)); buf = next_entry(fp, sizeof(u32)*2); if (!buf) { rc = -EINVAL; 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); 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; u32 *buf, len; typdatum = kmalloc(sizeof(*typdatum),GFP_KERNEL); if (!typdatum) { rc = -ENOMEM; return rc; } memset(typdatum, 0, sizeof(*typdatum)); buf = next_entry(fp, sizeof(u32)*3); if (!buf) { rc = -EINVAL; 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); key[len] = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -