📄 policydb.c
字号:
context_destroy(&c->context[1]); if ( i == OCON_ISID ) xfree(c->u.name); xfree(c);}/* * Free any memory allocated by a policy database structure. */void policydb_destroy(struct policydb *p){ struct ocontext *c, *ctmp; int i; struct role_allow *ra, *lra = NULL; struct role_trans *tr, *ltr = NULL; struct range_trans *rt, *lrt = NULL; for ( i = 0; i < SYM_NUM; i++ ) { hashtab_map(p->symtab[i].table, destroy_f[i], NULL); hashtab_destroy(p->symtab[i].table); } for ( i = 0; i < SYM_NUM; i++ ) xfree(p->sym_val_to_name[i]); xfree(p->class_val_to_struct); xfree(p->role_val_to_struct); xfree(p->user_val_to_struct); avtab_destroy(&p->te_avtab); for ( i = 0; i < OCON_NUM; i++ ) { c = p->ocontexts[i]; while ( c ) { ctmp = c; c = c->next; ocontext_destroy(ctmp,i); } } cond_policydb_destroy(p); for ( tr = p->role_tr; tr; tr = tr->next ) { if ( ltr ) xfree(ltr); ltr = tr; } if ( ltr ) xfree(ltr); for ( ra = p->role_allow; ra; ra = ra -> next ) { if ( lra ) xfree(lra); lra = ra; } if ( lra ) xfree(lra); for ( rt = p->range_tr; rt; rt = rt -> next ) { if ( lrt ) xfree(lrt); lrt = rt; } if ( lrt ) xfree(lrt); for ( i = 0; i < p->p_types.nprim; i++ ) ebitmap_destroy(&p->type_attr_map[i]); xfree(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 = xmalloc(struct perm_datum); if ( !perdatum ) { rc = -ENOMEM; goto out; } memset(perdatum, 0, sizeof(*perdatum)); 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 = xmalloc_array(char, len + 1); 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 = xmalloc(struct common_datum); if ( !comdatum ) { rc = -ENOMEM; goto out; } memset(comdatum, 0, sizeof(*comdatum)); 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 = xmalloc_array(char, len + 1); 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 = xmalloc(struct constraint_node); if ( !c ) return -ENOMEM; memset(c, 0, sizeof(*c)); 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 = xmalloc(struct constraint_expr); if ( !e ) return -ENOMEM; memset(e, 0, sizeof(*e)); 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 = xmalloc(struct class_datum); if ( !cladatum ) { rc = -ENOMEM; goto out; } memset(cladatum, 0, sizeof(*cladatum)); 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 = xmalloc_array(char, len + 1); if ( !key ) { rc = -ENOMEM; goto bad; } rc = next_entry(key, fp, len); if ( rc < 0 ) goto bad; key[len] = 0; if ( len2 ) { cladatum->comkey = xmalloc_array(char, len2 + 1); 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 = xmalloc(struct role_datum); if ( !role ) { rc = -ENOMEM; goto out; } memset(role, 0, sizeof(*role)); 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 = xmalloc_array(char, len + 1); 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 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -