📄 policydb.c
字号:
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 = xmalloc(struct type_datum); if ( !typdatum ) { rc = -ENOMEM; return rc; } memset(typdatum, 0, sizeof(*typdatum)); 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 = 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, 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; __le32 buf[2]; u32 len; usrdatum = xmalloc(struct user_datum); if ( !usrdatum ) { rc = -ENOMEM; goto out; } memset(usrdatum, 0, sizeof(*usrdatum)); 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]); 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(&usrdatum->roles, fp); if ( rc ) goto bad; if ( p->policyvers >= POLICYDB_VERSION_MLS ) { rc = mls_read_range_helper(&usrdatum->range, fp); if ( rc ) goto bad; rc = mls_read_level(&usrdatum->dfltlevel, 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 sens_read(struct policydb *p, struct hashtab *h, void *fp){ char *key = NULL; struct level_datum *levdatum; int rc; __le32 buf[2]; u32 len; levdatum = xmalloc(struct level_datum); if ( !levdatum ) { rc = -ENOMEM; goto out; } memset(levdatum, 0, sizeof(*levdatum)); rc = next_entry(buf, fp, sizeof buf); if ( rc < 0 ) goto bad; len = le32_to_cpu(buf[0]); levdatum->isalias = 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; levdatum->level = xmalloc(struct mls_level); if ( !levdatum->level ) { rc = -ENOMEM; goto bad; } if ( mls_read_level(levdatum->level, fp) ) { rc = -EINVAL; goto bad; } rc = hashtab_insert(h, key, levdatum); if ( rc ) goto bad;out: return rc;bad: sens_destroy(key, levdatum, NULL); goto out;}static int cat_read(struct policydb *p, struct hashtab *h, void *fp){ char *key = NULL; struct cat_datum *catdatum; int rc; __le32 buf[3]; u32 len; catdatum = xmalloc(struct cat_datum); if ( !catdatum ) { rc = -ENOMEM; goto out; } memset(catdatum, 0, sizeof(*catdatum)); rc = next_entry(buf, fp, sizeof buf); if ( rc < 0 ) goto bad; len = le32_to_cpu(buf[0]); catdatum->value = le32_to_cpu(buf[1]); catdatum->isalias = le32_to_cpu(buf[2]); 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, catdatum); if ( rc ) goto bad;out: return rc;bad: cat_destroy(key, catdatum, 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, cond_read_bool, sens_read, cat_read,};extern int ss_initialized;/* * 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*/; int i, j, rc; __le32 buf[8]; u32 len, /*len2,*/ config, nprim, nel /*, nel2*/; char *policydb_str; struct policydb_compat_info *info; struct range_trans *rt, *lrt; config = 0; rc = policydb_init(p); if ( rc ) goto out; /* Read the magic number and string length. */ rc = next_entry(buf, fp, sizeof(u32)* 2); if ( rc < 0 ) goto bad; if ( le32_to_cpu(buf[0]) != POLICYDB_MAGIC ) { printk(KERN_ERR "security: policydb magic number 0x%x does " "not match expected magic number 0x%x\n", le32_to_cpu(buf[0]), POLICYDB_MAGIC); goto bad; } len = le32_to_cpu(buf[1]); if ( len != strlen(POLICYDB_STRING) ) { printk(KERN_ERR "security: policydb string length %d does not " "match expected length %Zu\n", len, (u32) strlen(POLICYDB_STRING)); goto bad; } policydb_str = xmalloc_array(char, len + 1); if ( !policydb_str ) { printk(KERN_ERR "security: unable to allocate memory for policydb " "string of length %d\n", len); rc = -ENOMEM; goto bad; } rc = next_entry(policydb_str, fp, len); if ( rc < 0 ) { printk(KERN_ERR "security: truncated policydb string identifier\n"); xfree(policydb_str); goto bad; } 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); xfree(policydb_str); goto bad; } /* Done with policydb_str. */ xfree(policydb_str); policydb_str = NULL; /* Read the version, config, and table sizes. */ rc = next_entry(buf, fp, sizeof(u32)*4); if ( rc < 0 ) goto bad; p->policyvers = le32_to_cpu(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", le32_to_cpu(buf[0]), POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX); goto bad; } if ( (le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS) ) { if ( ss_initialized && !flask_mls_enabled ) { printk(KERN_ERR "Cannot switch between non-MLS and MLS " "policies\n"); goto bad; } flask_mls_enabled = 1; config |= POLICYDB_CONFIG_MLS; if ( p->policyvers < POLICYDB_VERSION_MLS ) { printk(KERN_ERR "security policydb version %d (MLS) " "not backwards compatible\n", p->policyvers); goto bad; } } else { if ( ss_initialized && flask_mls_enabled ) { printk(KERN_ERR "Cannot switch between MLS and non-MLS " "policies\n"); goto bad; } } info = policydb_lookup_compat(p->policyvers); if ( !info ) { printk(KERN_ERR "security: unable to find policy compat info " "for version %d\n", p->policyvers); goto bad; } if ( le32_to_cpu(buf[2]) != info->sym_num || le32_to_cpu(buf[3]) != info->ocon_num ) { printk(KERN_ERR "security: policydb table sizes (%d,%d) do " "not match mine (%d,%d)\n", le32_to_cpu(buf[2]), le32_to_cpu(buf[3]), info->sym_num, info->ocon_num); goto bad; } for ( i = 0; i < info->sym_num; i++ ) { 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++ ) { 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, p->policyvers); if ( rc ) goto bad; if ( p->policyvers >= POLICYDB_VERSION_BOOL ) { rc = cond_read_list(p, fp); if ( rc ) goto bad; } 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++ ) { tr = xmalloc(struct role_trans); if ( !tr ) { rc = -ENOMEM; goto bad; } memset(tr, 0, sizeof(*tr)); if ( ltr ) ltr->next = tr; else p->role_tr = tr; 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; } 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++ ) { ra = xmalloc(struct role_allow); if ( !ra ) { rc = -ENOMEM; goto bad; } memset(ra, 0, sizeof(*ra)); if ( lra ) lra->next = ra; else p->role_allow = ra; 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; } 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++ ) { 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++ ) { c = xmalloc(struct ocontext); 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: 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); if ( rc ) goto bad; break; } } } rc = next_entry(buf, fp, sizeof(u32)); if ( rc < 0 ) goto bad; nel = le32_to_cpu(buf[0]); if ( p->policyvers >= POLICYDB_VERSION_MLS ) { rc = next_entry(buf, fp, sizeof(u32)); if ( rc < 0 ) goto bad; nel = le32_to_cpu(buf[0]); lrt = NULL; for ( i = 0; i < nel; i++ ) { rt = xmalloc(struct range_trans); if ( !rt ) { rc = -ENOMEM; goto bad; } memset(rt, 0, sizeof(*rt)); if ( lrt ) lrt->next = rt; else p->range_tr = rt; rc = next_entry(buf, fp, (sizeof(u32) * 2)); if ( rc < 0 ) goto bad; rt->dom = le32_to_cpu(buf[0]); rt->type = le32_to_cpu(buf[1]); rc = mls_read_range_helper(&rt->range, fp); if ( rc ) goto bad; lrt = rt; } } p->type_attr_map = xmalloc_array(struct ebitmap, p->p_types.nprim); if ( !p->type_attr_map ) goto bad; for ( i = 0; i < p->p_types.nprim; i++ ) { ebitmap_init(&p->type_attr_map[i]); if ( p->policyvers >= POLICYDB_VERSION_AVTAB ) { if ( ebitmap_read(&p->type_attr_map[i], fp) ) goto bad; } /* add the type itself as the degenerate case */ if ( ebitmap_set_bit(&p->type_attr_map[i], i, 1) ) goto bad; } rc = 0;out: return rc;bad: if ( !rc ) rc = -EINVAL; policydb_destroy(p); goto out;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -