int sidtab_insert(struct sidtab *s, u32 sid, struct context *context) { int hvalue, rc = 0; struct sidtab_node *prev, *cur, *newnode; if ( !s ) { rc = -ENOMEM; goto out; } hvalue = SIDTAB_HASH(sid); prev = NULL; cur = s->htable[hvalue]; while ( cur != NULL && sid > cur->sid ) { prev = cur; cur = cur->next; } if ( cur && sid == cur->sid ) { rc = -EEXIST; goto out; } newnode = xmalloc(struct sidtab_node); if ( newnode == NULL ) { rc = -ENOMEM; goto out; } newnode->sid = sid; if ( context_cpy(&newnode->context, context) ) { xfree(newnode); rc = -ENOMEM; goto out; } if ( prev ) { newnode->next = prev->next; wmb(); prev->next = newnode; } else { newnode->next = s->htable[hvalue]; wmb(); s->htable[hvalue] = newnode; } s->nel++; if ( sid >= s->next_sid ) s->next_sid = sid + 1; out: return rc; }
/* Create a low level ibpkey structure from * a high level representation */ static int ibpkey_from_record(sepol_handle_t *handle, const policydb_t *policydb, ocontext_t **ibpkey, const sepol_ibpkey_t *data) { ocontext_t *tmp_ibpkey = NULL; context_struct_t *tmp_con = NULL; char *subnet_prefix_buf = NULL; int low = sepol_ibpkey_get_low(data); int high = sepol_ibpkey_get_high(data); tmp_ibpkey = (ocontext_t *)calloc(1, sizeof(*tmp_ibpkey)); if (!tmp_ibpkey) goto omem; tmp_ibpkey->u.ibpkey.subnet_prefix = sepol_ibpkey_get_subnet_prefix_bytes(data); /* Pkey range */ tmp_ibpkey->u.ibpkey.low_pkey = low; tmp_ibpkey->u.ibpkey.high_pkey = high; if (tmp_ibpkey->u.ibpkey.low_pkey > tmp_ibpkey->u.ibpkey.high_pkey) { ERR(handle, "low ibpkey %d exceeds high ibpkey %d", tmp_ibpkey->u.ibpkey.low_pkey, tmp_ibpkey->u.ibpkey.high_pkey); goto err; } /* Context */ if (context_from_record(handle, policydb, &tmp_con, sepol_ibpkey_get_con(data)) < 0) goto err; context_cpy(&tmp_ibpkey->context[0], tmp_con); context_destroy(tmp_con); free(tmp_con); tmp_con = NULL; *ibpkey = tmp_ibpkey; return STATUS_SUCCESS; omem: ERR(handle, "out of memory"); err: if (tmp_ibpkey) { context_destroy(&tmp_ibpkey->context[0]); free(tmp_ibpkey); } context_destroy(tmp_con); free(tmp_con); free(subnet_prefix_buf); ERR(handle, "could not create ibpkey structure"); return STATUS_ERR; }
/* * Convert the values in the security context * structure `c' from the values specified * in the policy `p->oldp' to the values specified * in the policy `p->newp'. Verify that the * context is valid under the new policy. */ static int convert_context(u32 key, struct context *c, void *p) { struct convert_context_args *args; struct context oldc; struct role_datum *role; struct type_datum *typdatum; struct user_datum *usrdatum; char *s; u32 len; int rc; args = p; rc = context_cpy(&oldc, c); if (rc) goto out; rc = -EINVAL; /* Convert the user. */ usrdatum = hashtab_search(args->newp->p_users.table, args->oldp->p_user_val_to_name[c->user - 1]); if (!usrdatum) { goto bad; } c->user = usrdatum->value; /* Convert the role. */ role = hashtab_search(args->newp->p_roles.table, args->oldp->p_role_val_to_name[c->role - 1]); if (!role) { goto bad; } c->role = role->value; /* Convert the type. */ typdatum = hashtab_search(args->newp->p_types.table, args->oldp->p_type_val_to_name[c->type - 1]); if (!typdatum) { goto bad; } c->type = typdatum->value; rc = mls_convert_context(args->oldp, args->newp, c); if (rc) goto bad; /* Check the validity of the new context. */ if (!policydb_context_isvalid(args->newp, c)) { rc = convert_context_handle_invalid_context(&oldc); if (rc) goto bad; } context_destroy(&oldc); out: return rc; bad: context_struct_to_string(&oldc, &s, &len); context_destroy(&oldc); printk(KERN_ERR "security: invalidating context %s\n", s); kfree(s); goto out; }
/* Create a low level node structure from * a high level representation */ static int node_from_record(sepol_handle_t * handle, const policydb_t * policydb, ocontext_t ** node, const sepol_node_t * data) { ocontext_t *tmp_node = NULL; context_struct_t *tmp_con = NULL; char *addr_buf = NULL, *mask_buf = NULL; tmp_node = (ocontext_t *) calloc(1, sizeof(ocontext_t)); if (!tmp_node) goto omem; size_t addr_bsize, mask_bsize; /* Address and netmask */ if (sepol_node_get_addr_bytes(handle, data, &addr_buf, &addr_bsize) < 0) goto err; if (sepol_node_get_mask_bytes(handle, data, &mask_buf, &mask_bsize) < 0) goto err; int proto = sepol_node_get_proto(data); switch (proto) { case SEPOL_PROTO_IP4: memcpy(&tmp_node->u.node.addr, addr_buf, addr_bsize); memcpy(&tmp_node->u.node.mask, mask_buf, mask_bsize); break; case SEPOL_PROTO_IP6: memcpy(tmp_node->u.node6.addr, addr_buf, addr_bsize); memcpy(tmp_node->u.node6.mask, mask_buf, mask_bsize); break; default: ERR(handle, "unsupported protocol %u", proto); goto err; } free(addr_buf); free(mask_buf); addr_buf = NULL; mask_buf = NULL; /* Context */ if (context_from_record(handle, policydb, &tmp_con, sepol_node_get_con(data)) < 0) goto err; context_cpy(&tmp_node->context[0], tmp_con); context_destroy(tmp_con); free(tmp_con); tmp_con = NULL; *node = tmp_node; return STATUS_SUCCESS; omem: ERR(handle, "out of memory"); err: if (tmp_node != NULL) { context_destroy(&tmp_node->context[0]); free(tmp_node); } context_destroy(tmp_con); free(tmp_con); free(addr_buf); free(mask_buf); ERR(handle, "could not create node structure"); return STATUS_ERR; }