📄 mls.c
字号:
/* * Implementation of the multi-level security (MLS) policy. * * Author : Stephen Smalley, <sds@epoch.ncsc.mil> *//* * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> * * Support for enhanced MLS infrastructure. * * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. *//* * Updated: Hewlett-Packard <paul.moore@hp.com> * * Added support to import/export the MLS label from NetLabel * * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 */#include <linux/kernel.h>#include <linux/slab.h>#include <linux/string.h>#include <linux/errno.h>#include <net/netlabel.h>#include "sidtab.h"#include "mls.h"#include "policydb.h"#include "services.h"/* * Return the length in bytes for the MLS fields of the * security context string representation of `context'. */int mls_compute_context_len(struct context * context){ int i, l, len, head, prev; char *nm; struct ebitmap *e; struct ebitmap_node *node; if (!selinux_mls_enabled) return 0; len = 1; /* for the beginning ":" */ for (l = 0; l < 2; l++) { int index_sens = context->range.level[l].sens; len += strlen(policydb.p_sens_val_to_name[index_sens - 1]); /* categories */ head = -2; prev = -2; e = &context->range.level[l].cat; ebitmap_for_each_positive_bit(e, node, i) { if (i - prev > 1) { /* one or more negative bits are skipped */ if (head != prev) { nm = policydb.p_cat_val_to_name[prev]; len += strlen(nm) + 1; } nm = policydb.p_cat_val_to_name[i]; len += strlen(nm) + 1; head = i; } prev = i; } if (prev != head) { nm = policydb.p_cat_val_to_name[prev]; len += strlen(nm) + 1; } if (l == 0) { if (mls_level_eq(&context->range.level[0], &context->range.level[1])) break; else len++; } } return len;}/* * Write the security context string representation of * the MLS fields of `context' into the string `*scontext'. * Update `*scontext' to point to the end of the MLS fields. */void mls_sid_to_context(struct context *context, char **scontext){ char *scontextp, *nm; int i, l, head, prev; struct ebitmap *e; struct ebitmap_node *node; if (!selinux_mls_enabled) return; scontextp = *scontext; *scontextp = ':'; scontextp++; for (l = 0; l < 2; l++) { strcpy(scontextp, policydb.p_sens_val_to_name[context->range.level[l].sens - 1]); scontextp += strlen(scontextp); /* categories */ head = -2; prev = -2; e = &context->range.level[l].cat; ebitmap_for_each_positive_bit(e, node, i) { if (i - prev > 1) { /* one or more negative bits are skipped */ if (prev != head) { if (prev - head > 1) *scontextp++ = '.'; else *scontextp++ = ','; nm = policydb.p_cat_val_to_name[prev]; strcpy(scontextp, nm); scontextp += strlen(nm); } if (prev < 0) *scontextp++ = ':'; else *scontextp++ = ','; nm = policydb.p_cat_val_to_name[i]; strcpy(scontextp, nm); scontextp += strlen(nm); head = i; } prev = i; } if (prev != head) { if (prev - head > 1) *scontextp++ = '.'; else *scontextp++ = ','; nm = policydb.p_cat_val_to_name[prev]; strcpy(scontextp, nm); scontextp += strlen(nm); } if (l == 0) { if (mls_level_eq(&context->range.level[0], &context->range.level[1])) break; else *scontextp++ = '-'; } } *scontext = scontextp; return;}int mls_level_isvalid(struct policydb *p, struct mls_level *l){ struct level_datum *levdatum; struct ebitmap_node *node; int i; if (!l->sens || l->sens > p->p_levels.nprim) return 0; levdatum = hashtab_search(p->p_levels.table, p->p_sens_val_to_name[l->sens - 1]); if (!levdatum) return 0; ebitmap_for_each_positive_bit(&l->cat, node, i) { if (i > p->p_cats.nprim) return 0; if (!ebitmap_get_bit(&levdatum->level->cat, i)) { /* * Category may not be associated with * sensitivity. */ return 0; } } return 1;}int mls_range_isvalid(struct policydb *p, struct mls_range *r){ return (mls_level_isvalid(p, &r->level[0]) && mls_level_isvalid(p, &r->level[1]) && mls_level_dom(&r->level[1], &r->level[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){ struct user_datum *usrdatum; if (!selinux_mls_enabled) return 1; if (!mls_range_isvalid(p, &c->range)) 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]; if (!mls_range_contains(usrdatum->range, c->range)) return 0; /* user may not be associated with range */ return 1;}/* * Set the MLS fields in the security context structure * `context' based on the string representation in * the string `*scontext'. Update `*scontext' to * point to the end of the string representation of * the MLS fields. * * This function modifies the string in place, inserting * NULL characters to terminate the MLS fields. * * If a def_sid is provided and no MLS field is present, * copy the MLS field of the associated default context. * Used for upgraded to MLS systems where objects may lack * MLS fields. * * Policy read-lock must be held for sidtab lookup. * */int mls_context_to_sid(char oldc, char **scontext, struct context *context, struct sidtab *s, u32 def_sid){ char delim; char *scontextp, *p, *rngptr; struct level_datum *levdatum; struct cat_datum *catdatum, *rngdatum; int l, rc = -EINVAL; if (!selinux_mls_enabled) { if (def_sid != SECSID_NULL && oldc) *scontext += strlen(*scontext)+1; return 0; } /* * No MLS component to the security context, try and map to * default if provided. */ if (!oldc) { struct context *defcon; if (def_sid == SECSID_NULL) goto out; defcon = sidtab_search(s, def_sid); if (!defcon) goto out; rc = mls_context_cpy(context, defcon); goto out; } /* Extract low sensitivity. */ scontextp = p = *scontext; while (*p && *p != ':' && *p != '-') p++; delim = *p; if (delim != 0) *p++ = 0; for (l = 0; l < 2; l++) { levdatum = hashtab_search(policydb.p_levels.table, scontextp); if (!levdatum) { rc = -EINVAL; goto out; } context->range.level[l].sens = levdatum->level->sens; if (delim == ':') { /* Extract category set. */ while (1) { scontextp = p; while (*p && *p != ',' && *p != '-') p++; delim = *p; if (delim != 0) *p++ = 0; /* Separate into range if exists */ if ((rngptr = strchr(scontextp, '.')) != NULL) { /* Remove '.' */ *rngptr++ = 0; } catdatum = hashtab_search(policydb.p_cats.table, scontextp); if (!catdatum) { rc = -EINVAL; goto out; } rc = ebitmap_set_bit(&context->range.level[l].cat, catdatum->value - 1, 1); if (rc) goto out; /* If range, set all categories in range */ if (rngptr) { int i; rngdatum = hashtab_search(policydb.p_cats.table, rngptr); if (!rngdatum) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -