^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Implementation of the multi-level security (MLS) policy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Author : Stephen Smalley, <sds@tycho.nsa.gov>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Support for enhanced MLS infrastructure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Updated: Hewlett-Packard <paul@paul-moore.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Added support to import/export the MLS label from NetLabel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <net/netlabel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "sidtab.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "mls.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "policydb.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "services.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * Return the length in bytes for the MLS fields of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * security context string representation of `context'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) int mls_compute_context_len(struct policydb *p, struct context *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) int i, l, len, head, prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) char *nm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct ebitmap *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct ebitmap_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (!p->mls_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) len = 1; /* for the beginning ":" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) for (l = 0; l < 2; l++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) int index_sens = context->range.level[l].sens;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) len += strlen(sym_name(p, SYM_LEVELS, index_sens - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* categories */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) head = -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) prev = -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) e = &context->range.level[l].cat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) ebitmap_for_each_positive_bit(e, node, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (i - prev > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* one or more negative bits are skipped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if (head != prev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) nm = sym_name(p, SYM_CATS, prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) len += strlen(nm) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) nm = sym_name(p, SYM_CATS, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) len += strlen(nm) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) head = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) prev = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (prev != head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) nm = sym_name(p, SYM_CATS, prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) len += strlen(nm) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (l == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (mls_level_eq(&context->range.level[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) &context->range.level[1]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * Write the security context string representation of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * the MLS fields of `context' into the string `*scontext'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * Update `*scontext' to point to the end of the MLS fields.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) void mls_sid_to_context(struct policydb *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct context *context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) char **scontext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) char *scontextp, *nm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) int i, l, head, prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct ebitmap *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct ebitmap_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (!p->mls_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) scontextp = *scontext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) *scontextp = ':';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) scontextp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) for (l = 0; l < 2; l++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) strcpy(scontextp, sym_name(p, SYM_LEVELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) context->range.level[l].sens - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) scontextp += strlen(scontextp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* categories */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) head = -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) prev = -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) e = &context->range.level[l].cat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) ebitmap_for_each_positive_bit(e, node, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (i - prev > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /* one or more negative bits are skipped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (prev != head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (prev - head > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) *scontextp++ = '.';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) *scontextp++ = ',';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) nm = sym_name(p, SYM_CATS, prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) strcpy(scontextp, nm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) scontextp += strlen(nm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (prev < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) *scontextp++ = ':';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) *scontextp++ = ',';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) nm = sym_name(p, SYM_CATS, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) strcpy(scontextp, nm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) scontextp += strlen(nm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) head = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) prev = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (prev != head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (prev - head > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) *scontextp++ = '.';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) *scontextp++ = ',';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) nm = sym_name(p, SYM_CATS, prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) strcpy(scontextp, nm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) scontextp += strlen(nm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (l == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (mls_level_eq(&context->range.level[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) &context->range.level[1]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) *scontextp++ = '-';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) *scontext = scontextp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) int mls_level_isvalid(struct policydb *p, struct mls_level *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct level_datum *levdatum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (!l->sens || l->sens > p->p_levels.nprim)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) levdatum = symtab_search(&p->p_levels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) sym_name(p, SYM_LEVELS, l->sens - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (!levdatum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * Return 1 iff all the bits set in l->cat are also be set in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * levdatum->level->cat and no bit in l->cat is larger than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * p->p_cats.nprim.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return ebitmap_contains(&levdatum->level->cat, &l->cat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) p->p_cats.nprim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) int mls_range_isvalid(struct policydb *p, struct mls_range *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return (mls_level_isvalid(p, &r->level[0]) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) mls_level_isvalid(p, &r->level[1]) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) mls_level_dom(&r->level[1], &r->level[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * Return 1 if the MLS fields in the security context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * structure `c' are valid. Return 0 otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) int mls_context_isvalid(struct policydb *p, struct context *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct user_datum *usrdatum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (!p->mls_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (!mls_range_isvalid(p, &c->range))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (c->role == OBJECT_R_VAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * User must be authorized for the MLS range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (!c->user || c->user > p->p_users.nprim)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) usrdatum = p->user_val_to_struct[c->user - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (!mls_range_contains(usrdatum->range, c->range))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return 0; /* user may not be associated with range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * Set the MLS fields in the security context structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * `context' based on the string representation in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * the string `scontext'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * This function modifies the string in place, inserting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * NULL characters to terminate the MLS fields.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * If a def_sid is provided and no MLS field is present,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * copy the MLS field of the associated default context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * Used for upgraded to MLS systems where objects may lack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * MLS fields.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * Policy read-lock must be held for sidtab lookup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) int mls_context_to_sid(struct policydb *pol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) char oldc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) char *scontext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct context *context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct sidtab *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) u32 def_sid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) char *sensitivity, *cur_cat, *next_cat, *rngptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct level_datum *levdatum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct cat_datum *catdatum, *rngdatum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) int l, rc, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) char *rangep[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (!pol->mls_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * With no MLS, only return -EINVAL if there is a MLS field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * and it did not come from an xattr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (oldc && def_sid == SECSID_NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * No MLS component to the security context, try and map to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * default if provided.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (!oldc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct context *defcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (def_sid == SECSID_NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) defcon = sidtab_search(s, def_sid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (!defcon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return mls_context_cpy(context, defcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * If we're dealing with a range, figure out where the two parts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * of the range begin.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) rangep[0] = scontext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) rangep[1] = strchr(scontext, '-');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (rangep[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) rangep[1][0] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) rangep[1]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /* For each part of the range: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) for (l = 0; l < 2; l++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /* Split sensitivity and category set. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) sensitivity = rangep[l];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (sensitivity == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) next_cat = strchr(sensitivity, ':');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (next_cat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) *(next_cat++) = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) /* Parse sensitivity. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) levdatum = symtab_search(&pol->p_levels, sensitivity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (!levdatum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) context->range.level[l].sens = levdatum->level->sens;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /* Extract category set. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) while (next_cat != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) cur_cat = next_cat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) next_cat = strchr(next_cat, ',');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (next_cat != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) *(next_cat++) = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /* Separate into range if exists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) rngptr = strchr(cur_cat, '.');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (rngptr != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /* Remove '.' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) *rngptr++ = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) catdatum = symtab_search(&pol->p_cats, cur_cat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (!catdatum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) rc = ebitmap_set_bit(&context->range.level[l].cat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) catdatum->value - 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /* If range, set all categories in range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (rngptr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) rngdatum = symtab_search(&pol->p_cats, rngptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (!rngdatum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (catdatum->value >= rngdatum->value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) for (i = catdatum->value; i < rngdatum->value; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) rc = ebitmap_set_bit(&context->range.level[l].cat, i, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /* If we didn't see a '-', the range start is also the range end. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (rangep[1] == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) context->range.level[1].sens = context->range.level[0].sens;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) rc = ebitmap_cpy(&context->range.level[1].cat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) &context->range.level[0].cat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * Set the MLS fields in the security context structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * `context' based on the string representation in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * the string `str'. This function will allocate temporary memory with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * given constraints of gfp_mask.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) int mls_from_string(struct policydb *p, char *str, struct context *context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) gfp_t gfp_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) char *tmpstr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (!p->mls_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) tmpstr = kstrdup(str, gfp_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (!tmpstr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) rc = mls_context_to_sid(p, ':', tmpstr, context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) NULL, SECSID_NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) kfree(tmpstr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) * Copies the MLS range `range' into `context'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) int mls_range_set(struct context *context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct mls_range *range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) int l, rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) /* Copy the MLS range into the context */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) for (l = 0; l < 2; l++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) context->range.level[l].sens = range->level[l].sens;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) rc = ebitmap_cpy(&context->range.level[l].cat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) &range->level[l].cat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) int mls_setup_user_range(struct policydb *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) struct context *fromcon, struct user_datum *user,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct context *usercon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (p->mls_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct mls_level *fromcon_sen = &(fromcon->range.level[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) struct mls_level *fromcon_clr = &(fromcon->range.level[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) struct mls_level *user_low = &(user->range.level[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) struct mls_level *user_clr = &(user->range.level[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) struct mls_level *user_def = &(user->dfltlevel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) struct mls_level *usercon_sen = &(usercon->range.level[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) struct mls_level *usercon_clr = &(usercon->range.level[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /* Honor the user's default level if we can */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (mls_level_between(user_def, fromcon_sen, fromcon_clr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) *usercon_sen = *user_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) else if (mls_level_between(fromcon_sen, user_def, user_clr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) *usercon_sen = *fromcon_sen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) else if (mls_level_between(fromcon_clr, user_low, user_def))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) *usercon_sen = *user_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /* Lower the clearance of available contexts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if the clearance of "fromcon" is lower than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) that of the user's default clearance (but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) only if the "fromcon" clearance dominates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) the user's computed sensitivity level) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (mls_level_dom(user_clr, fromcon_clr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) *usercon_clr = *fromcon_clr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) else if (mls_level_dom(fromcon_clr, user_clr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) *usercon_clr = *user_clr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) * Convert the MLS fields in the security context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * structure `oldc' from the values specified in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) * policy `oldp' to the values specified in the policy `newp',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * storing the resulting context in `newc'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) int mls_convert_context(struct policydb *oldp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) struct policydb *newp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) struct context *oldc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) struct context *newc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) struct level_datum *levdatum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) struct cat_datum *catdatum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) struct ebitmap_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) int l, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (!oldp->mls_enabled || !newp->mls_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) for (l = 0; l < 2; l++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) char *name = sym_name(oldp, SYM_LEVELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) oldc->range.level[l].sens - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) levdatum = symtab_search(&newp->p_levels, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (!levdatum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) newc->range.level[l].sens = levdatum->level->sens;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) ebitmap_for_each_positive_bit(&oldc->range.level[l].cat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) node, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) catdatum = symtab_search(&newp->p_cats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) sym_name(oldp, SYM_CATS, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (!catdatum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) rc = ebitmap_set_bit(&newc->range.level[l].cat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) catdatum->value - 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) int mls_compute_sid(struct policydb *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) struct context *scontext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) struct context *tcontext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) u16 tclass,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) u32 specified,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) struct context *newcontext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) bool sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) struct range_trans rtr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) struct mls_range *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) struct class_datum *cladatum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) int default_range = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (!p->mls_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) switch (specified) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) case AVTAB_TRANSITION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /* Look for a range transition rule. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) rtr.source_type = scontext->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) rtr.target_type = tcontext->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) rtr.target_class = tclass;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) r = policydb_rangetr_search(p, &rtr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) return mls_range_set(newcontext, r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (tclass && tclass <= p->p_classes.nprim) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) cladatum = p->class_val_to_struct[tclass - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (cladatum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) default_range = cladatum->default_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) switch (default_range) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) case DEFAULT_SOURCE_LOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) return mls_context_cpy_low(newcontext, scontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) case DEFAULT_SOURCE_HIGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return mls_context_cpy_high(newcontext, scontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) case DEFAULT_SOURCE_LOW_HIGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) return mls_context_cpy(newcontext, scontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) case DEFAULT_TARGET_LOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return mls_context_cpy_low(newcontext, tcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) case DEFAULT_TARGET_HIGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return mls_context_cpy_high(newcontext, tcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) case DEFAULT_TARGET_LOW_HIGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return mls_context_cpy(newcontext, tcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) case DEFAULT_GLBLUB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) return mls_context_glblub(newcontext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) scontext, tcontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) case AVTAB_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if ((tclass == p->process_class) || sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /* Use the process MLS attributes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return mls_context_cpy(newcontext, scontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) /* Use the process effective MLS attributes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return mls_context_cpy_low(newcontext, scontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) case AVTAB_MEMBER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) /* Use the process effective MLS attributes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return mls_context_cpy_low(newcontext, scontext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) #ifdef CONFIG_NETLABEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * mls_export_netlbl_lvl - Export the MLS sensitivity levels to NetLabel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * @context: the security context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) * @secattr: the NetLabel security attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * Given the security context copy the low MLS sensitivity level into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * NetLabel MLS sensitivity level field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) void mls_export_netlbl_lvl(struct policydb *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct context *context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) struct netlbl_lsm_secattr *secattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (!p->mls_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) secattr->attr.mls.lvl = context->range.level[0].sens - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) secattr->flags |= NETLBL_SECATTR_MLS_LVL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * mls_import_netlbl_lvl - Import the NetLabel MLS sensitivity levels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * @context: the security context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * @secattr: the NetLabel security attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) * Given the security context and the NetLabel security attributes, copy the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) * NetLabel MLS sensitivity level into the context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) void mls_import_netlbl_lvl(struct policydb *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) struct context *context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) struct netlbl_lsm_secattr *secattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (!p->mls_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) context->range.level[0].sens = secattr->attr.mls.lvl + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) context->range.level[1].sens = context->range.level[0].sens;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) * mls_export_netlbl_cat - Export the MLS categories to NetLabel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) * @context: the security context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) * @secattr: the NetLabel security attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) * Given the security context copy the low MLS categories into the NetLabel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) * MLS category field. Returns zero on success, negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) int mls_export_netlbl_cat(struct policydb *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) struct context *context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) struct netlbl_lsm_secattr *secattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (!p->mls_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) rc = ebitmap_netlbl_export(&context->range.level[0].cat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) &secattr->attr.mls.cat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if (rc == 0 && secattr->attr.mls.cat != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) secattr->flags |= NETLBL_SECATTR_MLS_CAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) * mls_import_netlbl_cat - Import the MLS categories from NetLabel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) * @context: the security context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) * @secattr: the NetLabel security attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) * Copy the NetLabel security attributes into the SELinux context; since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) * NetLabel security attribute only contains a single MLS category use it for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) * both the low and high categories of the context. Returns zero on success,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) * negative values on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) int mls_import_netlbl_cat(struct policydb *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) struct context *context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) struct netlbl_lsm_secattr *secattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (!p->mls_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) rc = ebitmap_netlbl_import(&context->range.level[0].cat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) secattr->attr.mls.cat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) goto import_netlbl_cat_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) memcpy(&context->range.level[1].cat, &context->range.level[0].cat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) sizeof(context->range.level[0].cat));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) import_netlbl_cat_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) ebitmap_destroy(&context->range.level[0].cat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) #endif /* CONFIG_NETLABEL */