/* Attempt to require a symbol within the current scope. If currently * within an optional (and not its else branch), add the symbol to the * required list. Return 0 on success, 1 if caller needs to free() * datum. If symbols may not be declared here return -1. For duplicate * declarations return -2. For all else, including out of memory, * return -3.. Note that dest_value and datum_value might not be * restricted pointers. */ int require_symbol(uint32_t symbol_type, hashtab_key_t key, hashtab_datum_t datum, uint32_t * dest_value, uint32_t * datum_value) { avrule_decl_t *decl = stack_top->decl; int retval; /* first check that symbols may be required here */ if (!is_require_allowed()) { return -1; } retval = symtab_insert(policydbp, symbol_type, key, datum, SCOPE_REQ, decl->decl_id, dest_value); if (retval == 1) { symtab_datum_t *s = (symtab_datum_t *) hashtab_search(policydbp->symtab[symbol_type].table, key); assert(s != NULL); if (symbol_type == SYM_LEVELS) { *dest_value = ((level_datum_t *) s)->level->sens; } else { *dest_value = s->value; } } else if (retval == -2) { /* ignore require statements if that symbol was * previously declared and is in current scope */ int prev_declaration_ok = 0; if (is_id_in_scope(symbol_type, key)) { if (symbol_type == SYM_TYPES) { /* check that previous symbol has same * type/attribute-ness */ unsigned char new_isattr = ((type_datum_t *) datum)->flavor; type_datum_t *old_datum = (type_datum_t *) hashtab_search(policydbp->symtab[SYM_TYPES].table, key); assert(old_datum != NULL); unsigned char old_isattr = old_datum->flavor; prev_declaration_ok = (old_isattr == new_isattr ? 1 : 0); } else { prev_declaration_ok = 1; } } if (prev_declaration_ok) { /* ignore this require statement because it * was already declared within my scope */ stack_top->require_given = 1; return 1; } else { /* previous declaration was not in scope or * had a mismatched type/attribute, so * generate an error */ return -2; } } else if (retval < 0) { return -3; } else { /* fall through possible if retval is 0 or 1 */ } if (datum_value != NULL) { if (ebitmap_set_bit(decl->required.scope + symbol_type, *datum_value - 1, 1)) { return -3; } } stack_top->require_given = 1; return retval; }
/* Check if a particular permission is present within the given class, * and that the class is enabled. Returns 1 if both conditions are * true, 0 if neither could be found or if the class id disabled. */ int is_perm_enabled(char *class_id, char *perm_id, policydb_t * p) { class_datum_t *cladatum; perm_datum_t *perm; if (!is_id_enabled(class_id, p, SYM_CLASSES)) { return 0; } cladatum = (class_datum_t *) hashtab_search(p->p_classes.table, class_id); if (cladatum == NULL) { return 0; } perm = hashtab_search(cladatum->permissions.table, perm_id); if (perm == NULL && cladatum->comdatum != 0) { /* permission was not in this class. before giving * up, check the class's parent */ perm = hashtab_search(cladatum->comdatum->permissions.table, perm_id); } if (perm == NULL) { return 0; } return 1; }
int add_rule(char *s, char *t, char *c, char *p, policydb_t *policy) { type_datum_t *src, *tgt; class_datum_t *cls; perm_datum_t *perm; avtab_datum_t *av; avtab_key_t key; src = hashtab_search(policy->p_types.table, s); if (src == NULL) { fprintf(stderr, "source type %s does not exist\n", s); return 2; } tgt = hashtab_search(policy->p_types.table, t); if (tgt == NULL) { fprintf(stderr, "target type %s does not exist\n", t); return 2; } cls = hashtab_search(policy->p_classes.table, c); if (cls == NULL) { fprintf(stderr, "class %s does not exist\n", c); return 2; } perm = hashtab_search(cls->permissions.table, p); if (perm == NULL) { if (cls->comdatum == NULL) { fprintf(stderr, "perm %s does not exist in class %s\n", p, c); return 2; } perm = hashtab_search(cls->comdatum->permissions.table, p); if (perm == NULL) { fprintf(stderr, "perm %s does not exist in class %s\n", p, c); return 2; } } // See if there is already a rule key.source_type = src->s.value; key.target_type = tgt->s.value; key.target_class = cls->s.value; key.specified = AVTAB_ALLOWED; av = avtab_search(&policy->te_avtab, &key); if (av == NULL) { int ret; av = cmalloc(sizeof av); av->data |= 1U << (perm->s.value - 1); ret = avtab_insert(&policy->te_avtab, &key, av); if (ret) { fprintf(stderr, "Error inserting into avtab\n"); return 1; } } av->data |= 1U << (perm->s.value - 1); return 0; }
int qpol_policy_get_user_by_name(const qpol_policy_t * policy, const char *name, const qpol_user_t ** datum) { hashtab_datum_t internal_datum; policydb_t *db; if (policy == NULL || name == NULL || datum == NULL) { if (datum != NULL) *datum = NULL; ERR(policy, "%s", strerror(EINVAL)); errno = EINVAL; return STATUS_ERR; } db = &policy->p->p; internal_datum = hashtab_search(db->p_users.table, (hashtab_key_t)name); if (internal_datum == NULL) { *datum = NULL; ERR(policy, "could not find datum for user %s", name); errno = ENOENT; return STATUS_ERR; } *datum = (qpol_user_t *) internal_datum; return STATUS_SUCCESS; }
/* Attempt to declare a symbol within the current declaration. If * currently within a non-conditional and in a non-else branch then * insert the symbol, return 0 on success if symbol was undeclared. * For roles and users, it is legal to have multiple declarations; as * such return 1 to indicate that caller must free() the datum because * it was not added. If symbols may not be declared here return -1. * For duplicate declarations return -2. For all else, including out * of memory, return -3. Note that dest_value and datum_value might * not be restricted pointers. */ int declare_symbol(uint32_t symbol_type, hashtab_key_t key, hashtab_datum_t datum, uint32_t * dest_value, uint32_t * datum_value) { avrule_decl_t *decl = stack_top->decl; int retval; /* first check that symbols may be declared here */ if (!is_declaration_allowed()) { return -1; } retval = symtab_insert(policydbp, symbol_type, key, datum, SCOPE_DECL, decl->decl_id, dest_value); if (retval == 1 && dest_value) { symtab_datum_t *s = (symtab_datum_t *) hashtab_search(policydbp->symtab[symbol_type].table, key); assert(s != NULL); if (symbol_type == SYM_LEVELS) { *dest_value = ((level_datum_t *) s)->level->sens; } else { *dest_value = s->value; } } else if (retval == -2) { return -2; } else if (retval < 0) { return -3; } else { /* fall through possible if retval is 0 */ } if (datum_value != NULL) { if (ebitmap_set_bit(decl->declared.scope + symbol_type, *datum_value - 1, 1)) { return -3; } } return retval; }
bool selinux_make_permissive(policydb_t *pdb, const std::string &type_str) { type_datum_t *type; type = (type_datum_t *) hashtab_search( pdb->p_types.table, (hashtab_key_t) type_str.c_str()); if (!type) { LOGV("Type %s not found in policy", type_str.c_str()); return false; } if (ebitmap_get_bit(&pdb->permissive_map, type->s.value)) { LOGV("Type %s is already permissive", type_str.c_str()); return true; } if (ebitmap_set_bit(&pdb->permissive_map, type->s.value, 1) < 0) { LOGE("Failed to set bit for type %s in the permissive map", type_str.c_str()); return false; } LOGD("Type %s is now permissive", type_str.c_str()); return true; }
static oskit_error_t recv(void *param, oskit_bufio_t *b, oskit_size_t pkt_size) { oskit_pd_t *pd = (oskit_pd_t *)param; oskit_netio_t *netio; oskit_s32_t fid; oskit_s32_t err; char *pkt; osenv_assert(param); osenv_assert(b); err = oskit_bufio_map(b, (void **)&pkt, 0, pkt_size); if (err) { return OSKIT_E_UNEXPECTED; } switch (pd->ft) { case OSKIT_PD_FILTER_DPF_INTERP: fid = oskit_dpf_iptr(pkt, pkt_size); break; default: return OSKIT_E_NOTIMPL; } if (fid != 0) { netio = (oskit_netio_t *)hashtab_search(pd->ht, (hashtab_key_t)fid); osenv_assert(netio); oskit_netio_push(netio, b, pkt_size); } else { oskit_netio_push(pd->default_netio, b, pkt_size); } return 0; }
/* * Return 1 if the MLS fields in the security context * structure `c' are valid. Return 0 otherwise. */ int mls_context_isvalid(struct policydb *p, struct context *c) { unsigned int relation; struct level_datum *levdatum; struct user_datum *usrdatum; struct mls_range_list *rnode; int i, l; /* * MLS range validity checks: high must dominate low, low level must * be valid (category set <-> sensitivity check), and high level must * be valid (category set <-> sensitivity check) */ relation = mls_level_relation(c->range.level[1], c->range.level[0]); if (!(relation & (MLS_RELATION_DOM | MLS_RELATION_EQ))) /* High does not dominate low. */ return 0; for (l = 0; l < 2; l++) { if (!c->range.level[l].sens || c->range.level[l].sens > p->p_levels.nprim) return 0; levdatum = hashtab_search(p->p_levels.table, p->p_sens_val_to_name[c->range.level[l].sens - 1]); if (!levdatum) return 0; for (i = 1; i <= ebitmap_length(&c->range.level[l].cat); i++) { if (ebitmap_get_bit(&c->range.level[l].cat, i - 1)) { if (i > p->p_cats.nprim) return 0; if (!ebitmap_get_bit(&levdatum->level->cat, i - 1)) /* * Category may not be associated with * sensitivity in low level. */ return 0; } } } if (c->role == OBJECT_R_VAL) return 1; /* * User must be authorized for the MLS range. */ if (!c->user || c->user > p->p_users.nprim) return 0; usrdatum = p->user_val_to_struct[c->user - 1]; for (rnode = usrdatum->ranges; rnode; rnode = rnode->next) { if (mls_range_contains(rnode->range, c->range)) break; } if (!rnode) /* user may not be associated with range */ return 0; return 1; }
static bool is_type_of_attribute_set(policydb_t *policydb, const char *type_name, ebitmap_t *attr_set) { struct type_datum *type = hashtab_search(policydb->p_types.table, (char *)type_name); if (!type) { fprintf(stderr, "Error: \"%s\" is not defined in this policy.\n", type_name); return false; } if (type->flavor != TYPE_TYPE) { fprintf(stderr, "Error: \"%s\" is not a type in this policy.\n", type_name); return false; } ebitmap_t dst; ebitmap_init(&dst); /* Take the intersection, if the set is empty, then its a failure */ int rc = ebitmap_and(&dst, attr_set, &policydb->type_attr_map[type->s.value - 1]); if (rc) { fprintf(stderr, "Error: Could not perform ebitmap_and: %d\n", rc); exit(1); } bool res = (bool)ebitmap_length(&dst); ebitmap_destroy(&dst); return res; }
static int user_implicit_bounds(hashtab_t users_tab, char *user_id, user_datum_t * user) { user_datum_t *bounds; char *bounds_id, *delim; delim = strrchr(user_id, '.'); if (!delim) return 0; /* no implicit boundary */ bounds_id = strdup(user_id); if (!bounds_id) { yyerror("out of memory"); return -1; } bounds_id[(size_t) (delim - user_id)] = '\0'; bounds = hashtab_search(users_tab, bounds_id); if (!bounds) { yyerror2("user %s doesn't exist, is implicit bounds of %s", bounds_id, user_id); return -1; } if (!user->bounds) user->bounds = bounds->s.value; else if (user->bounds != bounds->s.value) { yyerror2("user %s has inconsistent bounds %s/%s", user_id, bounds_id, policydbp->p_role_val_to_name[user->bounds - 1]); return -1; } free(bounds_id); return 0; }
/* * Verify that each permission that is defined under the * existing policy is still defined with the same value * in the new policy. */ static int validate_perm(void *key, void *datum, void *p) { struct hashtab *h; struct perm_datum *perdatum, *perdatum2; int rc = 0; h = p; perdatum = datum; perdatum2 = hashtab_search(h, key); if (!perdatum2) { printk(KERN_ERR "security: permission %s disappeared", (char *)key); rc = -ENOENT; goto out; } if (perdatum->value != perdatum2->value) { printk(KERN_ERR "security: the value of permission %s changed", (char *)key); rc = -EINVAL; } out: return rc; }
struct user *user_find(char *prefix) { struct user *user; char nick[512]; ircproto_parse_prefix(prefix, nick, sizeof(nick), NULL, 0, NULL, 0); user = hashtab_search(users, nick); return user; }
static OSKIT_COMDECL filesystem_getroot(oskit_filesystem_t *f, struct oskit_dir **out_dir) { struct gfilesystem *fs = (struct gfilesystem *) f; oskit_dir_t *d; struct proc *p; oskit_error_t ferror; struct vnode *vp; int error; if (!fs || !fs->count || !fs->mp) return OSKIT_E_INVALIDARG; ferror = getproc(&p); if (ferror) return ferror; error = VFS_ROOT(fs->mp, &vp); if (error) { prfree(p); return errno_to_oskit_error(error); } error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p); if (error) { vput(vp); prfree(p); return errno_to_oskit_error(error); } d = (oskit_dir_t *) hashtab_search(vptab, (hashtab_key_t) vp); if (d) { oskit_dir_addref(d); } else { d = (oskit_dir_t *) gfile_create(fs,vp); if (!d) { vput(vp); prfree(p); return OSKIT_ENOMEM; } } vput(vp); prfree(p); *out_dir = d; return 0; }
/* * Convert the MLS fields in the security context * structure `c' from the values specified in the * policy `oldp' to the values specified in the policy `newp'. */ int mls_convert_context(struct policydb *oldp, struct policydb *newp, struct context *c) { struct level_datum *levdatum; struct cat_datum *catdatum; struct ebitmap bitmap; int l, i; for (l = 0; l < 2; l++) { levdatum = hashtab_search(newp->p_levels.table, oldp->p_sens_val_to_name[c->range.level[l].sens - 1]); if (!levdatum) return -EINVAL; c->range.level[l].sens = levdatum->level->sens; ebitmap_init(&bitmap); for (i = 1; i <= ebitmap_length(&c->range.level[l].cat); i++) { if (ebitmap_get_bit(&c->range.level[l].cat, i - 1)) { int rc; catdatum = hashtab_search(newp->p_cats.table, oldp->p_cat_val_to_name[i - 1]); if (!catdatum) return -EINVAL; rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1); if (rc) return rc; } } ebitmap_destroy(&c->range.level[l].cat); c->range.level[l].cat = bitmap; } return 0; }
static int get_attr_bit(policydb_t *policydb, const char *attr_name) { struct type_datum *attr = hashtab_search(policydb->p_types.table, (char *)attr_name); if (!attr) { fprintf(stderr, "Error: \"%s\" is not defined in this policy.\n", attr_name); return -1; } if (attr->flavor != TYPE_ATTRIB) { fprintf(stderr, "Error: \"%s\" is not an attribute in this policy.\n", attr_name); return -1; } return attr->s.value - 1; }
avrule_decl_t *test_find_decl_by_sym(policydb_t * p, int symtab, char *sym) { scope_datum_t *scope = (scope_datum_t *) hashtab_search(p->scope[symtab].table, sym); if (scope == NULL) { return NULL; } if (scope->scope != SCOPE_DECL) { return NULL; } if (scope->decl_ids_len != 1) { return NULL; } return p->decl_val_to_struct[scope->decl_ids[0] - 1]; }
/* * Verify that each class that is defined under the * existing policy is still defined with the same * attributes in the new policy. */ static int validate_class(void *key, void *datum, void *p) { struct policydb *newp; struct class_datum *cladatum, *cladatum2; int rc; newp = p; cladatum = datum; cladatum2 = hashtab_search(newp->p_classes.table, key); if (!cladatum2) { printk(KERN_ERR "security: class %s disappeared\n", (char *)key); rc = -ENOENT; goto out; } if (cladatum->value != cladatum2->value) { printk(KERN_ERR "security: the value of class %s changed\n", (char *)key); rc = -EINVAL; goto out; } if ((cladatum->comdatum && !cladatum2->comdatum) || (!cladatum->comdatum && cladatum2->comdatum)) { printk(KERN_ERR "security: the inherits clause for the access " "vector definition for class %s changed\n", (char *)key); rc = -EINVAL; goto out; } if (cladatum->comdatum) { rc = hashtab_map(cladatum->comdatum->permissions.table, validate_perm, cladatum2->comdatum->permissions.table); if (rc) { printk(" in the access vector definition for class " "%s\n", (char *)key); goto out; } } rc = hashtab_map(cladatum->permissions.table, validate_perm, cladatum2->permissions.table); if (rc) printk(" in access vector definition for class %s\n", (char *)key); out: return rc; }
/* Look up an identifier in a policy's scoping table. If it is there, * marked as SCOPE_DECL, and any of its declaring block has been enabled, * then return 1. Otherwise return 0. Can only be called after the * decl_val_to_struct index has been created */ int is_id_enabled(char *id, policydb_t * p, int symbol_table) { scope_datum_t *scope = (scope_datum_t *) hashtab_search(p->scope[symbol_table].table, id); uint32_t i; if (scope == NULL) { return 0; } if (scope->scope != SCOPE_DECL) { return 0; } for (i = 0; i < scope->decl_ids_len; i++) { avrule_decl_t *decl = p->decl_val_to_struct[scope->decl_ids[i] - 1]; if (decl != NULL && decl->enabled) { return 1; } } return 0; }
/* Return a role_datum_t for the local avrule_decl with the given ID. * If it does not exist, create one with the same value as 'value'. * This function assumes that the ID is within scope. c.f., * is_id_in_scope(). * * NOTE: this function usurps ownership of id afterwards. The caller * shall not reference it nor free() it afterwards. */ role_datum_t *get_local_role(char *id, uint32_t value, unsigned char isattr) { role_datum_t *dest_roledatum; hashtab_t roles_tab; assert(stack_top->type == 1); if (stack_top->parent == NULL) { /* in global, so use global symbol table */ roles_tab = policydbp->p_roles.table; } else { roles_tab = stack_top->decl->p_roles.table; } dest_roledatum = hashtab_search(roles_tab, id); if (!dest_roledatum) { dest_roledatum = (role_datum_t *)malloc(sizeof(role_datum_t)); if (dest_roledatum == NULL) { free(id); return NULL; } role_datum_init(dest_roledatum); dest_roledatum->s.value = value; dest_roledatum->flavor = isattr ? ROLE_ATTRIB : ROLE_ROLE; if (hashtab_insert(roles_tab, id, dest_roledatum)) { free(id); role_datum_destroy(dest_roledatum); free(dest_roledatum); return NULL; } } else { free(id); if (dest_roledatum->flavor != isattr ? ROLE_ATTRIB : ROLE_ROLE) return NULL; } return dest_roledatum; }
static int bool_update(sepol_handle_t * handle, policydb_t * policydb, const sepol_bool_key_t * key, const sepol_bool_t * data) { const char *cname; char *name; int value; sepol_bool_key_unpack(key, &cname); name = strdup(cname); value = sepol_bool_get_value(data); if (!name) goto omem; cond_bool_datum_t *datum = hashtab_search(policydb->p_bools.table, name); if (!datum) { LOGD("boolean %s no longer in policy", name); goto err; } if (value != 0 && value != 1) { LOGD("illegal value %d for boolean %s", value, name); goto err; } free(name); datum->state = value; return STATUS_SUCCESS; omem: LOGD("out of memory"); err: free(name); LOGD("could not update boolean %s", cname); return STATUS_ERR; }
/* Return a type_datum_t for the local avrule_decl with the given ID. * If it does not exist, create one with the same value as 'value'. * This function assumes that the ID is within scope. c.f., * is_id_in_scope(). * * NOTE: this function usurps ownership of id afterwards. The caller * shall not reference it nor free() it afterwards. */ type_datum_t *get_local_type(char *id, uint32_t value, unsigned char isattr) { type_datum_t *dest_typdatum; hashtab_t types_tab; assert(stack_top->type == 1); if (stack_top->parent == NULL) { /* in global, so use global symbol table */ types_tab = policydbp->p_types.table; } else { types_tab = stack_top->decl->p_types.table; } dest_typdatum = hashtab_search(types_tab, id); if (!dest_typdatum) { dest_typdatum = (type_datum_t *) malloc(sizeof(type_datum_t)); if (dest_typdatum == NULL) { free(id); return NULL; } type_datum_init(dest_typdatum); dest_typdatum->s.value = value; dest_typdatum->flavor = isattr ? TYPE_ATTRIB : TYPE_TYPE; dest_typdatum->primary = 1; if (hashtab_insert(types_tab, id, dest_typdatum)) { free(id); type_datum_destroy(dest_typdatum); free(dest_typdatum); return NULL; } } else { free(id); if (dest_typdatum->flavor != isattr ? TYPE_ATTRIB : TYPE_TYPE) { return NULL; } } return dest_typdatum; }
/* TODO: Looks fishy */ int bpool_delete(struct bpool *pool, char *id, int write_back) { if(pool && id) { struct bpool_node *node; #ifdef BPOOL_ENABLE_LOCKS assert(0 == __bpool_lock(500, &pool->big_lock)); #endif node = hashtab_search(pool->table, id); if(node) { #ifdef BPOOL_ENABLE_LOCKS assert(0 == __bpool_lock(501, &node->page_lock)); #endif assert(!node->dirty); hashtab_delete(pool->table, id); /* TODO: add facility to reset blocks */ /*memset(node->id, 0, pool->PAGE_ID_SIZE); memset(node->buf, 0, pool->PAGE_SIZE);*/ node->refbit = 0; node->valid = 0; node->dirty = 0; #ifdef BPOOL_ENABLE_LOCKS assert(0 == __bpool_unlock(501, &node->page_lock)); #endif } #ifdef BPOOL_ENABLE_LOCKS assert(0 == __bpool_unlock(500, &pool->big_lock)); #endif } // if pool && id return -2; }
int main () { int i = 0; int res = 0; char *pres = NULL; hashtab_node * node = NULL; struct test_node *p = NULL; hashtab *h = NULL; #ifdef MEMORY_TEST setenv("MALLOC_TRACE","1.txt",1); mtrace(); #endif h = hashtab_create(5,hashtab_hvalue,hashtab_keycmp,hashtab_node_free); assert(h!= NULL); while(1) { p = (struct test_node*)malloc(sizeof(struct test_node)); assert(p != NULL); printf("\r\n 请输入key 和value,当可以等于\"quit\"时退出"); scanf("%s",p->key); scanf("%s",p->data); if(strcmp(p->key,"quit") == 0) { free(p); break; } res = hashtab_insert(h,p->key,p->data); if (res != 0) { free(p); printf("\r\n key[%s],data[%s] insert failed %d",p->key,p->data,res); } else { printf("\r\n key[%s],data[%s] insert success %d",p->key,p->data,res); } } hashtab_dump(h); while(1) { p = (struct test_node*)malloc(sizeof(struct test_node)); assert(p != NULL); printf("\r\n 请输入key 查询value的数值,当可以等于\"quit\"时退出"); scanf("%s",p->key); if(strcmp(p->key,"quit") == 0) { free(p); break; } pres = hashtab_search(h,p->key); if (pres == NULL) { printf("\r\n key[%s] search data failed",p->key); } else { printf("\r\n key[%s],search data[%s] success",p->key,pres); } free(p); } hashtab_dump(h); while(1) { p = (struct test_node*)malloc(sizeof(struct test_node)); assert(p != NULL); printf("\r\n 请输入key 删除节点的数值,当可以等于\"quit\"时退出"); scanf("%s",p->key); if(strcmp(p->key,"quit") == 0) { free(p); break; } node = hashtab_delete(h,p->key); if (node == NULL) { printf("\r\n key[%s] delete node failed ",p->key); } else { printf("\r\n key[%s],delete data[%s] success",node->key,node->data); h->hash_node_free(node); } free(p); hashtab_dump(h); } hashtab_destory(h); #ifdef MEMORY_TEST muntrace(); #endif return 0; }
/* Resume the deduping process that happens during the initial scanning. * We also use it as a building block in the run-time map creation * process as well, just by initializing the variables accordingly. * P2D tuple consists of iodedupID to indicate which dedup block does * this pblk map into. * * @param[in] buf * @param[in] len * @param[in] ioblkID * @param[in] initflag * @param[in] lastblk_flag */ int resumeDeduping(unsigned char *buf, __u16 len, __u32 ioblkID, int initflag, int lastblk_flag, int rw_flag) { //uint32_t ptime; /* To be noted when event occurs, is this needed? TODO int ret; __u32 iodedupID; unsigned long long stime=0, etime=0; //savemem unsigned char dig[HASHLEN + MAGIC_SIZE]; unsigned char *dig = malloc(HASHLEN + MAGIC_SIZE); unsigned char *key = NULL; d2pv_datum *dedupd2pv = NULL, *d2pv = NULL; D2P_tuple_t *d2p = NULL; #ifdef STRICT_NO_HASH_COLLISION unsigned char *oldbuf = NULL; //savemem unsigned char debugkey[HASHLEN + MAGIC_SIZE]; unsigned char* debugkey = malloc(HASHLEN + MAGIC_SIZE); #endif #if defined(DEDUPING_DEBUG_SSS) fprintf(stdout, "In %s\n", __FUNCTION__); #endif /* Buf will always have "len" == BLKSIZE. No leftovers. */ #ifdef DEBUG_SS assert(len == BLKSIZE || lastblk_flag == ZEROBLK_FLAG); assert(initflag == INIT_STAGE || initflag == NOINIT_STAGE); #endif if (len != 0) /* Not a zero blk */ { assert(buf != NULL); memset(dig, 0, HASHLEN); stime = gettime(); /* START IODEDUP map-update-get-hash time */ if (getHashKey(buf, len, dig)) RET_ERR("getHashKey() returned error\n"); etime = gettime(); /* END IODEDUP map-update-get-hash */ ACCESSTIME_PRINT("iodedmap-map-update-component-get-hash time: %llu\n", etime - stime); key = (unsigned char*)dig; #if defined(SIMREPLAY_DEBUG_SS_DONE) printf("Content metadata update: buf=%s\n", (char*)buf); printf("Content metadata update: md5="); puts((char*)dig); #endif if (cmaphit_flag && !disksimflag) { assert(REALDISK_SCANNING_NOCOLLECTFORMAT_VMBUNCHREPLAY);//assert(0); //no need to update metadata if this is read request with //metadata hit, and disk is real, not simulated! return 0; } else if (cmaphit_flag) /* read with metadata hit but disk simulated */ { //ideally, i.e. if traces are perfect, then //no need to update metadata here, just return, but.... d2pv_datum *curr_d2pv = NULL; //but if the traces dont have consistent read/write requests, //in some cases of metadata-hit followed by cccahe-miss, the //following assert fails! work-around below... curr_d2pv = (d2pv_datum*) hashtab_search(deduptab.table, key); #ifndef INCONSISTENT_TRACES assert(curr_d2pv != NULL); #endif //work-around: //since we have already updated the content-cache with //the "offending content", we have to update the existing //metadata of this ioblk with new dhashkey, and also add //that new d2pv entry into deduptab (or update existing //dedupd2pv for the new dhashkey, if that is the case) d2pv_datum *cmaphit_d2pv = NULL; //found during metadata hit d2pv_datum *trace_d2pv = NULL; //due to inconsistent trace, //if disk is being simulated #ifdef INCONSISTENT_TRACES D2P_tuple_t *trace_d2p = NULL; #endif cmaphit_d2pv = getDedupMap(cmaphit_iodedupID); assert(cmaphit_d2pv != NULL); trace_d2pv = (d2pv_datum*) hashtab_search(deduptab.table, key); if (cmaphit_d2pv == trace_d2pv) curr_d2pv = cmaphit_d2pv; //true if trace is consistent #ifndef INCONSISTENT_TRACES else RET_ERR("inconsistence why?\n"); #else else //begin: fix for inconsistent trace { //trace is inconsistent, so we have to do some //impromptu metadata updates:- if (trace_d2pv == NULL) { __u32 iodedupID; trace_d2pv = (d2pv_datum*) calloc(1, sizeof(d2pv_datum)); INIT_LIST_HEAD(&trace_d2pv->d2pmaps); iodedupID = getNextDedupNum(initflag); trace_d2p = calloc (1, sizeof(D2P_tuple_t)); /*************************************************************** if (ccache_already_had_flag) { note_dedup_attrs(trace_d2pv, key, iodedupID, ccache_already_had_obj_ioblkID); note_d2p_tuple(trace_d2p, ccache_already_had_obj_ioblkID); } else { note_dedup_attrs(trace_d2pv, key, iodedupID, ioblkID); note_d2p_tuple(trace_d2p, ioblkID); } ***************************************************************/ /* We are here only upon a ccache miss after metadata hit, * so ccache_already_had_flag == 0 mandatory! */ //assert(ccache_already_had_flag == 0);//not true for wif note_dedup_attrs(trace_d2pv, key, iodedupID, ioblkID); note_d2p_tuple(trace_d2p, ioblkID); add_d2p_tuple_to_map(trace_d2p, trace_d2pv); ret = hashtab_insert(deduptab.table, trace_d2pv->dhashkey, trace_d2pv); setDedupMap(trace_d2pv->iodedupID, trace_d2pv); ret = updateBlockio(ioblkID, lastblk_flag, iodedupID); if (ret) RET_ERR("updateBlockio() error'ed\n"); } else { __u32 iodedupID; iodedupID = trace_d2pv->iodedupID; if (NULL == get_nondeduped_d2p(trace_d2pv, ioblkID)) { trace_d2p = calloc (1, sizeof(D2P_tuple_t)); //assert(ccache_already_had_flag == 0); //not true note_d2p_tuple(trace_d2p, ioblkID); add_d2p_tuple_to_map(trace_d2p, trace_d2pv); } ret = updateBlockio(ioblkID, lastblk_flag, iodedupID); if (ret) RET_ERR("updateBlockio() error'ed\n"); } //if current ioblk is the only one in old sector-list, //then delete cmaphit_d2pv from hash-table, else let //it stay there. if (slist_len(&cmaphit_d2pv->d2pmaps) > 1) { del_d2p_from_d2pmaps(cmaphit_d2pv, ioblkID); } else { del_d2p_from_d2pmaps(cmaphit_d2pv, ioblkID); hashtab_remove(deduptab.table, cmaphit_d2pv->dhashkey); setDedupMap(cmaphit_iodedupID, NULL); //d2pv freed } //mark trace_d2pv as curr_d2pv for self-hits/misses below! curr_d2pv = trace_d2pv; }//end: fix for inconsistent trace #endif //update the ioblkID for counts of self-hits/misses //copied from iodeduping.c, if change in 1 place, change both if (!ccache_already_had_flag) //set in __arc_add curr_d2pv->ioblkID = ioblkID; //ensure counts line up -- self else curr_d2pv->ioblkID = ccache_already_had_obj_ioblkID; return 0; }
//update the ioblkID for counts of self-hits/misses //copied from iodeduping.c, if change in 1 place, change both if (!ccache_already_had_flag) //set in __arc_add curr_d2pv->ioblkID = ioblkID; //ensure counts line up -- self else curr_d2pv->ioblkID = ccache_already_had_obj_ioblkID; return 0; } /* Note the D2P tuple for this dedup */ d2p = calloc (1, sizeof(D2P_tuple_t)); note_d2p_tuple(d2p, ioblkID); stime = gettime(); /* START IODEDUP map-update-hashtab-search time */ dedupd2pv = (d2pv_datum*) hashtab_search(deduptab.table, key); if (dedupd2pv) { etime = gettime(); /* END IODEDUP map-update-hashtab-search time */ ACCESSTIME_PRINT("iodedmap-map-update-component-hashtab-search-success time: %llu\n", etime - stime); #ifdef STRICT_NO_HASH_COLLISION if (!disksimflag){ if (!DISKSIM_RUNTIMEMAP_COLLECTFORMAT_VMBUNCHREPLAY && !DISKSIM_RUNTIMEMAP_COLLECTFORMAT_PIOEVENTSREPLAY) { assert(DISKSIM_SCANNINGTRACE_COLLECTFORMAT_PIOEVENTSREPLAY || DISKSIM_RUNTIMEMAP_NOCOLLECTFORMAT_PIOEVENTSREPLAY); oldbuf = NULL; if (get_fulldedup(dedupd2pv, &oldbuf)) RET_ERR("error in get_fulldedup\n"); if (memcmp(buf, oldbuf, BLKSIZE))
user_datum_t *declare_user(void) { char *id = queue_remove(id_queue), *dest_id = NULL; user_datum_t *user = NULL, *dest_user = NULL; int retval; uint32_t value = 0; if (id == NULL) { yyerror("no user name"); return NULL; } if ((user = (user_datum_t *) malloc(sizeof(*user))) == NULL) { yyerror("Out of memory!"); free(id); return NULL; } user_datum_init(user); retval = declare_symbol(SYM_USERS, id, (hashtab_datum_t *) user, &value, &value); if (retval == 0) { user->s.value = value; if ((dest_id = strdup(id)) == NULL) { yyerror("Out of memory!"); return NULL; } } else { /* this user was already declared in this module, or error */ dest_id = id; user_datum_destroy(user); free(user); } if (retval == 0 || retval == 1) { /* create a new user_datum_t for this decl, if necessary */ hashtab_t users_tab; assert(stack_top->type == 1); if (stack_top->parent == NULL) { /* in parent, so use global symbol table */ users_tab = policydbp->p_users.table; } else { users_tab = stack_top->decl->p_users.table; } dest_user = (user_datum_t *) hashtab_search(users_tab, dest_id); if (dest_user == NULL) { if ((dest_user = (user_datum_t *) malloc(sizeof(*dest_user))) == NULL) { yyerror("Out of memory!"); free(dest_id); return NULL; } user_datum_init(dest_user); dest_user->s.value = value; if (user_implicit_bounds(users_tab, dest_id, dest_user)) { free(dest_id); user_datum_destroy(dest_user); free(dest_user); return NULL; } if (hashtab_insert(users_tab, dest_id, dest_user)) { yyerror("Out of memory!"); free(dest_id); user_datum_destroy(dest_user); free(dest_user); return NULL; } } else { free(dest_id); } } else { free(dest_id); } switch (retval) { case -3:{ yyerror("Out of memory!"); return NULL; } case -2:{ yyerror("duplicate declaration of user"); return NULL; } case -1:{ yyerror("could not declare user here"); return NULL; } case 0:{ return dest_user; } case 1:{ return dest_user; /* user already declared for this block */ } default:{ assert(0); /* should never get here */ } } }
role_datum_t *declare_role(void) { char *id = queue_remove(id_queue), *dest_id = NULL; role_datum_t *role = NULL, *dest_role = NULL; int retval; uint32_t value; if (id == NULL) { yyerror("no role name"); return NULL; } if ((role = (role_datum_t *) malloc(sizeof(*role))) == NULL) { yyerror("Out of memory!"); free(id); return NULL; } role_datum_init(role); retval = declare_symbol(SYM_ROLES, id, (hashtab_datum_t *) role, &value, &value); if (retval == 0) { role->s.value = value; if ((dest_id = strdup(id)) == NULL) { yyerror("Out of memory!"); return NULL; } } else { /* this role was already declared in this module, or error */ dest_id = id; role_datum_destroy(role); free(role); } if (retval == 0 || retval == 1) { /* create a new role_datum_t for this decl, if necessary */ hashtab_t roles_tab; assert(stack_top->type == 1); if (stack_top->parent == NULL) { /* in parent, so use global symbol table */ roles_tab = policydbp->p_roles.table; } else { roles_tab = stack_top->decl->p_roles.table; } dest_role = (role_datum_t *) hashtab_search(roles_tab, dest_id); if (dest_role == NULL) { if ((dest_role = (role_datum_t *) malloc(sizeof(*dest_role))) == NULL) { yyerror("Out of memory!"); free(dest_id); return NULL; } role_datum_init(dest_role); dest_role->s.value = value; if (role_implicit_bounds(roles_tab, dest_id, dest_role)) { free(dest_id); role_datum_destroy(dest_role); free(dest_role); return NULL; } if (hashtab_insert(roles_tab, dest_id, dest_role)) { yyerror("Out of memory!"); free(dest_id); role_datum_destroy(dest_role); free(dest_role); return NULL; } } else { free(dest_id); } } else { free(dest_id); } switch (retval) { case -3:{ yyerror("Out of memory!"); return NULL; } case -2:{ yyerror("duplicate declaration of role"); return NULL; } case -1:{ yyerror("could not declare role here"); return NULL; } case 0:{ if (ebitmap_set_bit(&dest_role->dominates, role->s.value - 1, 1)) { yyerror("out of memory"); return NULL; } return dest_role; } case 1:{ return dest_role; /* role already declared for this block */ } default:{ assert(0); /* should never get here */ } } }
static void set_permissive(const hashtab_key_t domain, policydb_t *pdb) { type_datum_t *type = hashtab_search(pdb->p_types.table, domain); ebitmap_set_bit(&pdb->permissive_map, type->s.value, 1); }
int main_seinject(int argc, char **argv) { char *policy = NULL, *source = NULL, *target = NULL, *clazz = NULL, *perm = NULL, *perm_token = NULL, *perm_saveptr = NULL, *outfile = NULL, *permissive = NULL; policydb_t policydb; struct policy_file pf, outpf; sidtab_t sidtab; int ret_add_rule; int load = 0; int quiet = 0; FILE *fp; int i; for (i=1; i<argc; i++) { if (argv[i][0] == '-') { if (argv[i][1] == 's') { i++; source = argv[i]; continue; } if (argv[i][1] == 't') { i++; target = argv[i]; continue; } if (argv[i][1] == 'c') { i++; clazz = argv[i]; continue; } if (argv[i][1] == 'p') { i++; perm = argv[i]; continue; } if (argv[i][1] == 'P') { i++; policy = argv[i]; continue; } if (argv[i][1] == 'o') { i++; outfile = argv[i]; continue; } if (argv[i][1] == 'Z') { i++; permissive = argv[i]; continue; } if (argv[i][1] == 'l') { load = 1; continue; } if (argv[i][1] == 'q') { quiet = 1; continue; } break; } } if (i < argc || argc == 1 || ((!source || !target || !clazz || !perm) && !permissive)) { fprintf(stderr, "%s -s <source type> -t <target type> -c <class> -p <perm>[,<perm2>,<perm3>,...] [-P <policy file>] [-o <output file>] [-l|--load]\n", argv[0]); fprintf(stderr, "%s -Z permissive_type [-P <policy file>] [-o <output file>] [-l|--load]\n", argv[0]); exit(1); } if (!policy) policy = "/sys/fs/selinux/policy"; sepol_set_policydb(&policydb); sepol_set_sidtab(&sidtab); if (load_policy(policy, &policydb, &pf)) { fprintf(stderr, "Could not load policy\n"); return 1; } if (policydb_load_isids(&policydb, &sidtab)) return 1; if (permissive) { type_datum_t *type; type = hashtab_search(policydb.p_types.table, permissive); if (type == NULL) { fprintf(stderr, "type %s does not exist\n", permissive); return 2; } if (ebitmap_set_bit(&policydb.permissive_map, type->s.value, 1)) { fprintf(stderr, "Could not set bit in permissive map\n"); return 1; } } else { perm_token = strtok_r(perm, ",", &perm_saveptr); while (perm_token) { ret_add_rule = add_rule(source, target, clazz, perm_token, &policydb); if (ret_add_rule) { fprintf(stderr, "Could not add rule for perm: %s\n", perm_token); return ret_add_rule; } perm_token = strtok_r(NULL, ",", &perm_saveptr); } } if (outfile) { fp = fopen(outfile, "wb"); if (!fp) { fprintf(stderr, "Could not open outfile\n"); return 1; } policy_file_init(&outpf); outpf.type = PF_USE_STDIO; outpf.fp = fp; if (policydb_write(&policydb, &outpf)) { fprintf(stderr, "Could not write policy\n"); return 1; } fclose(fp); } if (load) { if (load_policy_into_kernel(&policydb)) { fprintf(stderr, "Could not load new policy into kernel\n"); return 1; } } policydb_destroy(&policydb); if (quiet == 0) fprintf(stdout, "Success\n"); return 0; }
static int load_booleans(struct policydb *policydb, const char *path, int *changesp) { FILE *boolf; char *buffer = NULL; size_t size = 0; char localbools[BUFSIZ]; char name[BUFSIZ]; int val; int errors = 0, changes = 0; struct cond_bool_datum *datum; boolf = fopen(path, "r"); if (boolf == NULL) goto localbool; #ifdef DARWIN if ((buffer = (char *)malloc(255 * sizeof(char))) == NULL) { ERR(NULL, "out of memory"); return -1; } while(fgets(buffer, 255, boolf) != NULL) { #else while (getline(&buffer, &size, boolf) > 0) { #endif int ret = process_boolean(buffer, name, sizeof(name), &val); if (ret == -1) errors++; if (ret == 1) { datum = hashtab_search(policydb->p_bools.table, name); if (!datum) { ERR(NULL, "unknown boolean %s", name); errors++; continue; } if (datum->state != val) { datum->state = val; changes++; } } } fclose(boolf); localbool: snprintf(localbools, sizeof(localbools), "%s.local", path); boolf = fopen(localbools, "r"); if (boolf != NULL) { #ifdef DARWIN while(fgets(buffer, 255, boolf) != NULL) { #else while (getline(&buffer, &size, boolf) > 0) { #endif int ret = process_boolean(buffer, name, sizeof(name), &val); if (ret == -1) errors++; if (ret == 1) { datum = hashtab_search(policydb->p_bools.table, name); if (!datum) { ERR(NULL, "unknown boolean %s", name); errors++; continue; } if (datum->state != val) { datum->state = val; changes++; } } } fclose(boolf); } free(buffer); if (errors) errno = EINVAL; *changesp = changes; return errors ? -1 : 0; } int sepol_genbools(void *data, size_t len, char *booleans) { struct policydb policydb; struct policy_file pf; int rc, changes = 0; if (policydb_init(&policydb)) goto err; if (policydb_from_image(NULL, data, len, &policydb) < 0) goto err; if (load_booleans(&policydb, booleans, &changes) < 0) { WARN(NULL, "error while reading %s", booleans); } if (!changes) goto out; if (evaluate_conds(&policydb) < 0) { ERR(NULL, "error while re-evaluating conditionals"); errno = EINVAL; goto err_destroy; } policy_file_init(&pf); pf.type = PF_USE_MEMORY; pf.data = data; pf.len = len; rc = policydb_write(&policydb, &pf); if (rc) { ERR(NULL, "unable to write new binary policy image"); errno = EINVAL; goto err_destroy; } out: policydb_destroy(&policydb); return 0; err_destroy: policydb_destroy(&policydb); err: return -1; } int hidden sepol_genbools_policydb(policydb_t * policydb, const char *booleans) { int rc, changes = 0; rc = load_booleans(policydb, booleans, &changes); if (!rc && changes) rc = evaluate_conds(policydb); if (rc) errno = EINVAL; return rc; } /* -- End Deprecated -- */ int sepol_genbools_array(void *data, size_t len, char **names, int *values, int nel) { struct policydb policydb; struct policy_file pf; int rc, i, errors = 0; struct cond_bool_datum *datum; /* Create policy database from image */ if (policydb_init(&policydb)) goto err; if (policydb_from_image(NULL, data, len, &policydb) < 0) goto err; for (i = 0; i < nel; i++) { datum = hashtab_search(policydb.p_bools.table, names[i]); if (!datum) { ERR(NULL, "boolean %s no longer in policy", names[i]); errors++; continue; } if (values[i] != 0 && values[i] != 1) { ERR(NULL, "illegal value %d for boolean %s", values[i], names[i]); errors++; continue; } datum->state = values[i]; } if (evaluate_conds(&policydb) < 0) { ERR(NULL, "error while re-evaluating conditionals"); errno = EINVAL; goto err_destroy; } policy_file_init(&pf); pf.type = PF_USE_MEMORY; pf.data = data; pf.len = len; rc = policydb_write(&policydb, &pf); if (rc) { ERR(NULL, "unable to write binary policy"); errno = EINVAL; goto err_destroy; } if (errors) { errno = EINVAL; goto err_destroy; } policydb_destroy(&policydb); return 0; err_destroy: policydb_destroy(&policydb); err: return -1; }