📄 mls.c
字号:
/* * Implementation of the multi-level security (MLS) policy. * * Author : Stephen Smalley, <sds@epoch.ncsc.mil> */#include <linux/kernel.h>#include <linux/slab.h>#include <linux/string.h>#include <linux/errno.h>#include "mls.h"#include "policydb.h"#include "services.h"/* * Remove any permissions from `allowed' that are * denied by the MLS policy. */void mls_compute_av(struct context *scontext, struct context *tcontext, struct class_datum *tclass, u32 *allowed){ unsigned int rel[2]; int l; for (l = 0; l < 2; l++) rel[l] = mls_level_relation(scontext->range.level[l], tcontext->range.level[l]); if (rel[1] != MLS_RELATION_EQ) { if (rel[1] != MLS_RELATION_DOM && !ebitmap_get_bit(&policydb.trustedreaders, scontext->type - 1) && !ebitmap_get_bit(&policydb.trustedobjects, tcontext->type - 1)) { /* read(s,t) = (s.high >= t.high) = False */ *allowed = (*allowed) & ~(tclass->mlsperms.read); } if (rel[1] != MLS_RELATION_DOMBY && !ebitmap_get_bit(&policydb.trustedreaders, tcontext->type - 1) && !ebitmap_get_bit(&policydb.trustedobjects, scontext->type - 1)) { /* readby(s,t) = read(t,s) = False */ *allowed = (*allowed) & ~(tclass->mlsperms.readby); } } if (((rel[0] != MLS_RELATION_DOMBY && rel[0] != MLS_RELATION_EQ) || ((!mls_level_eq(tcontext->range.level[0], tcontext->range.level[1])) && (rel[1] != MLS_RELATION_DOM && rel[1] != MLS_RELATION_EQ))) && !ebitmap_get_bit(&policydb.trustedwriters, scontext->type - 1) && !ebitmap_get_bit(&policydb.trustedobjects, tcontext->type - 1)) { /* * write(s,t) = ((s.low <= t.low = t.high) or (s.low * <= t.low <= t.high <= s.high)) = False */ *allowed = (*allowed) & ~(tclass->mlsperms.write); } if (((rel[0] != MLS_RELATION_DOM && rel[0] != MLS_RELATION_EQ) || ((!mls_level_eq(scontext->range.level[0], scontext->range.level[1])) && (rel[1] != MLS_RELATION_DOMBY && rel[1] != MLS_RELATION_EQ))) && !ebitmap_get_bit(&policydb.trustedwriters, tcontext->type - 1) && !ebitmap_get_bit(&policydb.trustedobjects, scontext->type - 1)) { /* writeby(s,t) = write(t,s) = False */ *allowed = (*allowed) & ~(tclass->mlsperms.writeby); }}/* * 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; len = 0; for (l = 0; l < 2; l++) { len += strlen(policydb.p_sens_val_to_name[context->range.level[l].sens - 1]) + 1; for (i = 1; i <= ebitmap_length(&context->range.level[l].cat); i++) if (ebitmap_get_bit(&context->range.level[l].cat, i - 1)) len += strlen(policydb.p_cat_val_to_name[i - 1]) + 1; if (mls_level_relation(context->range.level[0], context->range.level[1]) == MLS_RELATION_EQ) break; } 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. */int mls_sid_to_context(struct context *context, char **scontext){ char *scontextp; int i, l; scontextp = *scontext; for (l = 0; l < 2; l++) { strcpy(scontextp, policydb.p_sens_val_to_name[context->range.level[l].sens - 1]); scontextp += strlen(policydb.p_sens_val_to_name[context->range.level[l].sens - 1]); *scontextp = ':'; scontextp++; for (i = 1; i <= ebitmap_length(&context->range.level[l].cat); i++) if (ebitmap_get_bit(&context->range.level[l].cat, i - 1)) { strcpy(scontextp, policydb.p_cat_val_to_name[i - 1]); scontextp += strlen(policydb.p_cat_val_to_name[i - 1]); *scontextp = ','; scontextp++; } if (mls_level_relation(context->range.level[0], context->range.level[1]) != MLS_RELATION_EQ) { scontextp--; sprintf(scontextp, "-"); scontextp++; } else { break; } } *scontext = scontextp; 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;}/* * 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. */int mls_context_to_sid(char oldc, char **scontext, struct context *context){ char delim; char *scontextp, *p; struct level_datum *levdatum; struct cat_datum *catdatum; int l, rc = -EINVAL; if (!oldc) { /* No MLS component to the security context. Try to use a default 'unclassified' value. */ levdatum = hashtab_search(policydb.p_levels.table, "unclassified"); if (!levdatum) goto out; context->range.level[0].sens = levdatum->level->sens; context->range.level[1].sens = context->range.level[0].sens; rc = 0; 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) goto out; context->range.level[l].sens = levdatum->level->sens; if (delim == ':') { /* Extract low category set. */ while (1) { scontextp = p; while (*p && *p != ',' && *p != '-') p++; delim = *p; if (delim != 0) *p++ = 0; catdatum = hashtab_search(policydb.p_cats.table, scontextp); if (!catdatum) goto out; rc = ebitmap_set_bit(&context->range.level[l].cat, catdatum->value - 1, 1); if (rc) goto out; if (delim != ',') break; } } if (delim == '-') { /* Extract high sensitivity. */ scontextp = p; while (*p && *p != ':') p++; delim = *p; if (delim != 0) *p++ = 0; } else break; } if (l == 0) { context->range.level[1].sens = context->range.level[0].sens; rc = ebitmap_cpy(&context->range.level[1].cat, &context->range.level[0].cat); if (rc) goto out; } *scontext = ++p; rc = 0;out: return rc;}/* * Copies the MLS range from `src' into `dst'. */static inline int mls_copy_context(struct context *dst, struct context *src){ int l, rc = 0; /* Copy the MLS range from the source context */ for (l = 0; l < 2; l++) { dst->range.level[l].sens = src->range.level[l].sens; rc = ebitmap_cpy(&dst->range.level[l].cat, &src->range.level[l].cat); if (rc) break; } return rc;}/* * 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;}int mls_compute_sid(struct context *scontext, struct context *tcontext, u16 tclass, u32 specified, struct context *newcontext){ switch (specified) { case AVTAB_TRANSITION: case AVTAB_CHANGE: /* Use the process MLS attributes. */ return mls_copy_context(newcontext, scontext); case AVTAB_MEMBER: /* Only polyinstantiate the MLS attributes if the type is being polyinstantiated */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -