?? services.c
字號:
} break; default: *out_sid = SECINITSID_NODE; goto out; } if (c) { if (!c->sid[0]) { rc = sidtab_context_to_sid(&sidtab, &c->context[0], &c->sid[0]); if (rc) goto out; } *out_sid = c->sid[0]; } else { *out_sid = SECINITSID_NODE; }out: POLICY_RDUNLOCK; return rc;}#define SIDS_NEL 25/** * security_get_user_sids - Obtain reachable SIDs for a user. * @fromsid: starting SID * @username: username * @sids: array of reachable SIDs for user * @nel: number of elements in @sids * * Generate the set of SIDs for legal security contexts * for a given user that can be reached by @fromsid. * Set *@sids to point to a dynamically allocated * array containing the set of SIDs. Set *@nel to the * number of elements in the array. */int security_get_user_sids(u32 fromsid, char *username, u32 **sids, u32 *nel){ struct context *fromcon, usercon; u32 *mysids = NULL, *mysids2, sid; u32 mynel = 0, maxnel = SIDS_NEL; struct user_datum *user; struct role_datum *role; struct ebitmap_node *rnode, *tnode; int rc = 0, i, j; *sids = NULL; *nel = 0; if (!ss_initialized) goto out; POLICY_RDLOCK; fromcon = sidtab_search(&sidtab, fromsid); if (!fromcon) { rc = -EINVAL; goto out_unlock; } user = hashtab_search(policydb.p_users.table, username); if (!user) { rc = -EINVAL; goto out_unlock; } usercon.user = user->value; mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC); if (!mysids) { rc = -ENOMEM; goto out_unlock; } ebitmap_for_each_positive_bit(&user->roles, rnode, i) { role = policydb.role_val_to_struct[i]; usercon.role = i+1; ebitmap_for_each_positive_bit(&role->types, tnode, j) { usercon.type = j+1; if (mls_setup_user_range(fromcon, user, &usercon)) continue; rc = sidtab_context_to_sid(&sidtab, &usercon, &sid); if (rc) goto out_unlock; if (mynel < maxnel) { mysids[mynel++] = sid; } else { maxnel += SIDS_NEL; mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC); if (!mysids2) { rc = -ENOMEM; goto out_unlock; } memcpy(mysids2, mysids, mynel * sizeof(*mysids2)); kfree(mysids); mysids = mysids2; mysids[mynel++] = sid; } } }out_unlock: POLICY_RDUNLOCK; if (rc || !mynel) { kfree(mysids); goto out; } mysids2 = kcalloc(mynel, sizeof(*mysids2), GFP_KERNEL); if (!mysids2) { rc = -ENOMEM; kfree(mysids); goto out; } for (i = 0, j = 0; i < mynel; i++) { rc = avc_has_perm_noaudit(fromsid, mysids[i], SECCLASS_PROCESS, PROCESS__TRANSITION, AVC_STRICT, NULL); if (!rc) mysids2[j++] = mysids[i]; cond_resched(); } rc = 0; kfree(mysids); *sids = mysids2; *nel = j;out: return rc;}/** * security_genfs_sid - Obtain a SID for a file in a filesystem * @fstype: filesystem type * @path: path from root of mount * @sclass: file security class * @sid: SID for path * * Obtain a SID to use for a file in a filesystem that * cannot support xattr or use a fixed labeling behavior like * transition SIDs or task SIDs. */int security_genfs_sid(const char *fstype, char *path, u16 sclass, u32 *sid){ int len; struct genfs *genfs; struct ocontext *c; int rc = 0, cmp = 0; while (path[0] == '/' && path[1] == '/') path++; POLICY_RDLOCK; for (genfs = policydb.genfs; genfs; genfs = genfs->next) { cmp = strcmp(fstype, genfs->fstype); if (cmp <= 0) break; } if (!genfs || cmp) { *sid = SECINITSID_UNLABELED; rc = -ENOENT; goto out; } for (c = genfs->head; c; c = c->next) { len = strlen(c->u.name); if ((!c->v.sclass || sclass == c->v.sclass) && (strncmp(c->u.name, path, len) == 0)) break; } if (!c) { *sid = SECINITSID_UNLABELED; rc = -ENOENT; goto out; } if (!c->sid[0]) { rc = sidtab_context_to_sid(&sidtab, &c->context[0], &c->sid[0]); if (rc) goto out; } *sid = c->sid[0];out: POLICY_RDUNLOCK; return rc;}/** * security_fs_use - Determine how to handle labeling for a filesystem. * @fstype: filesystem type * @behavior: labeling behavior * @sid: SID for filesystem (superblock) */int security_fs_use( const char *fstype, unsigned int *behavior, u32 *sid){ int rc = 0; struct ocontext *c; POLICY_RDLOCK; c = policydb.ocontexts[OCON_FSUSE]; while (c) { if (strcmp(fstype, c->u.name) == 0) break; c = c->next; } if (c) { *behavior = c->v.behavior; if (!c->sid[0]) { rc = sidtab_context_to_sid(&sidtab, &c->context[0], &c->sid[0]); if (rc) goto out; } *sid = c->sid[0]; } else { rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid); if (rc) { *behavior = SECURITY_FS_USE_NONE; rc = 0; } else { *behavior = SECURITY_FS_USE_GENFS; } }out: POLICY_RDUNLOCK; return rc;}int security_get_bools(int *len, char ***names, int **values){ int i, rc = -ENOMEM; POLICY_RDLOCK; *names = NULL; *values = NULL; *len = policydb.p_bools.nprim; if (!*len) { rc = 0; goto out; } *names = kcalloc(*len, sizeof(char*), GFP_ATOMIC); if (!*names) goto err; *values = kcalloc(*len, sizeof(int), GFP_ATOMIC); if (!*values) goto err; for (i = 0; i < *len; i++) { size_t name_len; (*values)[i] = policydb.bool_val_to_struct[i]->state; name_len = strlen(policydb.p_bool_val_to_name[i]) + 1; (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC); if (!(*names)[i]) goto err; strncpy((*names)[i], policydb.p_bool_val_to_name[i], name_len); (*names)[i][name_len - 1] = 0; } rc = 0;out: POLICY_RDUNLOCK; return rc;err: if (*names) { for (i = 0; i < *len; i++) kfree((*names)[i]); } kfree(*values); goto out;}int security_set_bools(int len, int *values){ int i, rc = 0; int lenp, seqno = 0; struct cond_node *cur; POLICY_WRLOCK; lenp = policydb.p_bools.nprim; if (len != lenp) { rc = -EFAULT; goto out; } for (i = 0; i < len; i++) { if (!!values[i] != policydb.bool_val_to_struct[i]->state) { audit_log(current->audit_context, GFP_ATOMIC, AUDIT_MAC_CONFIG_CHANGE, "bool=%s val=%d old_val=%d auid=%u", policydb.p_bool_val_to_name[i], !!values[i], policydb.bool_val_to_struct[i]->state, audit_get_loginuid(current->audit_context)); } if (values[i]) { policydb.bool_val_to_struct[i]->state = 1; } else { policydb.bool_val_to_struct[i]->state = 0; } } for (cur = policydb.cond_list; cur != NULL; cur = cur->next) { rc = evaluate_cond_node(&policydb, cur); if (rc) goto out; } seqno = ++latest_granting;out: POLICY_WRUNLOCK; if (!rc) { avc_ss_reset(seqno); selnl_notify_policyload(seqno); selinux_xfrm_notify_policyload(); } return rc;}int security_get_bool_value(int bool){ int rc = 0; int len; POLICY_RDLOCK; len = policydb.p_bools.nprim; if (bool >= len) { rc = -EFAULT; goto out; } rc = policydb.bool_val_to_struct[bool]->state;out: POLICY_RDUNLOCK; return rc;}static int security_preserve_bools(struct policydb *p){ int rc, nbools = 0, *bvalues = NULL, i; char **bnames = NULL; struct cond_bool_datum *booldatum; struct cond_node *cur; rc = security_get_bools(&nbools, &bnames, &bvalues); if (rc) goto out; for (i = 0; i < nbools; i++) { booldatum = hashtab_search(p->p_bools.table, bnames[i]); if (booldatum) booldatum->state = bvalues[i]; } for (cur = p->cond_list; cur != NULL; cur = cur->next) { rc = evaluate_cond_node(p, cur); if (rc) goto out; }out: if (bnames) { for (i = 0; i < nbools; i++) kfree(bnames[i]); } kfree(bnames); kfree(bvalues); return rc;}/* * security_sid_mls_copy() - computes a new sid based on the given * sid and the mls portion of mls_sid. */int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid){ struct context *context1; struct context *context2; struct context newcon; char *s; u32 len; int rc = 0; if (!ss_initialized || !selinux_mls_enabled) { *new_sid = sid; goto out; } context_init(&newcon); POLICY_RDLOCK; context1 = sidtab_search(&sidtab, sid); if (!context1) { printk(KERN_ERR "security_sid_mls_copy: unrecognized SID " "%d\n", sid); rc = -EINVAL; goto out_unlock; } context2 = sidtab_search(&sidtab, mls_sid); if (!context2) { printk(KERN_ERR "security_sid_mls_copy: unrecognized SID " "%d\n", mls_sid); rc = -EINVAL; goto out_unlock; } newcon.user = context1->user; newcon.role = context1->role; newcon.type = context1->type; rc = mls_context_cpy(&newcon, context2); if (rc) goto out_unlock; /* Check the validity of the new context. */ if (!policydb_context_isvalid(&policydb, &newcon)) { rc = convert_context_handle_invalid_context(&newcon); if (rc) goto bad; } rc = sidtab_context_to_sid(&sidtab, &newcon, new_sid); goto out_unlock;bad: if (!context_struct_to_string(&newcon, &s, &len)) { audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, "security_sid_mls_copy: invalid context %s", s); kfree(s); }out_unlock: POLICY_RDUNLOCK; context_destroy(&newcon);out: return rc;}static int get_classes_callback(void *k, void *d, void *args){ struct class_datum *datum = d; char *name = k, **classes = args; int value = datum->value - 1; classes[value] = kstrdup(name, GFP_ATOMIC); if (!classes[value]) return -ENOMEM; return 0;}int security_get_classes(char ***classes, int *nclasses){ int rc = -ENOMEM; POLICY_RDLOCK; *nclasses = policydb.p_classes.nprim; *classes = kcalloc(*nclasses, sizeof(*classes), GFP_ATOMIC); if (!*classes) goto out; rc = hashtab_map(policydb.p_classes.table, get_classes_callback, *classes); if (rc < 0) { int i; for (i = 0; i < *nclasses; i++) kfree((*classes)[i]); kfree(*classes); }out: POLICY_RDUNLOCK; return rc;}static int get_permissions_callback(void *k, void *d, void *args){ struct perm_datum *datum = d; char *name = k, **perms = args; int value = datum->value - 1; perms[value] = kstrdup(name, GFP_ATOMIC); if (!perms[value]) return -ENOMEM; return 0;}int security_get_permissions(char *class, char ***perms, int *nperms){ int rc = -ENOMEM, i; struct class_datum *match; POLICY_RDLOCK; match = hashtab_search(policydb.p_classes.table, class); if (!match) { printk(KERN_ERR "%s: unrecognized class %s\n",
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -