diff options
Diffstat (limited to 'security/selinux/ss/mls.c')
| -rw-r--r-- | security/selinux/ss/mls.c | 66 |
1 files changed, 36 insertions, 30 deletions
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index 9a11deaaa9e7..fb5d70a6628d 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c | |||
| @@ -157,49 +157,55 @@ void mls_sid_to_context(struct context *context, | |||
| 157 | return; | 157 | return; |
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | int mls_level_isvalid(struct policydb *p, struct mls_level *l) | ||
| 161 | { | ||
| 162 | struct level_datum *levdatum; | ||
| 163 | struct ebitmap_node *node; | ||
| 164 | int i; | ||
| 165 | |||
| 166 | if (!l->sens || l->sens > p->p_levels.nprim) | ||
| 167 | return 0; | ||
| 168 | levdatum = hashtab_search(p->p_levels.table, | ||
| 169 | p->p_sens_val_to_name[l->sens - 1]); | ||
| 170 | if (!levdatum) | ||
| 171 | return 0; | ||
| 172 | |||
| 173 | ebitmap_for_each_positive_bit(&l->cat, node, i) { | ||
| 174 | if (i > p->p_cats.nprim) | ||
| 175 | return 0; | ||
| 176 | if (!ebitmap_get_bit(&levdatum->level->cat, i)) { | ||
| 177 | /* | ||
| 178 | * Category may not be associated with | ||
| 179 | * sensitivity. | ||
| 180 | */ | ||
| 181 | return 0; | ||
| 182 | } | ||
| 183 | } | ||
| 184 | |||
| 185 | return 1; | ||
| 186 | } | ||
| 187 | |||
| 188 | int mls_range_isvalid(struct policydb *p, struct mls_range *r) | ||
| 189 | { | ||
| 190 | return (mls_level_isvalid(p, &r->level[0]) && | ||
| 191 | mls_level_isvalid(p, &r->level[1]) && | ||
| 192 | mls_level_dom(&r->level[1], &r->level[0])); | ||
| 193 | } | ||
| 194 | |||
| 160 | /* | 195 | /* |
| 161 | * Return 1 if the MLS fields in the security context | 196 | * Return 1 if the MLS fields in the security context |
| 162 | * structure `c' are valid. Return 0 otherwise. | 197 | * structure `c' are valid. Return 0 otherwise. |
| 163 | */ | 198 | */ |
| 164 | int mls_context_isvalid(struct policydb *p, struct context *c) | 199 | int mls_context_isvalid(struct policydb *p, struct context *c) |
| 165 | { | 200 | { |
| 166 | struct level_datum *levdatum; | ||
| 167 | struct user_datum *usrdatum; | 201 | struct user_datum *usrdatum; |
| 168 | struct ebitmap_node *node; | ||
| 169 | int i, l; | ||
| 170 | 202 | ||
| 171 | if (!selinux_mls_enabled) | 203 | if (!selinux_mls_enabled) |
| 172 | return 1; | 204 | return 1; |
| 173 | 205 | ||
| 174 | /* | 206 | if (!mls_range_isvalid(p, &c->range)) |
| 175 | * MLS range validity checks: high must dominate low, low level must | ||
| 176 | * be valid (category set <-> sensitivity check), and high level must | ||
| 177 | * be valid (category set <-> sensitivity check) | ||
| 178 | */ | ||
| 179 | if (!mls_level_dom(&c->range.level[1], &c->range.level[0])) | ||
| 180 | /* High does not dominate low. */ | ||
| 181 | return 0; | 207 | return 0; |
| 182 | 208 | ||
| 183 | for (l = 0; l < 2; l++) { | ||
| 184 | if (!c->range.level[l].sens || c->range.level[l].sens > p->p_levels.nprim) | ||
| 185 | return 0; | ||
| 186 | levdatum = hashtab_search(p->p_levels.table, | ||
| 187 | p->p_sens_val_to_name[c->range.level[l].sens - 1]); | ||
| 188 | if (!levdatum) | ||
| 189 | return 0; | ||
| 190 | |||
| 191 | ebitmap_for_each_positive_bit(&c->range.level[l].cat, node, i) { | ||
| 192 | if (i > p->p_cats.nprim) | ||
| 193 | return 0; | ||
| 194 | if (!ebitmap_get_bit(&levdatum->level->cat, i)) | ||
| 195 | /* | ||
| 196 | * Category may not be associated with | ||
| 197 | * sensitivity in low level. | ||
| 198 | */ | ||
| 199 | return 0; | ||
| 200 | } | ||
| 201 | } | ||
| 202 | |||
| 203 | if (c->role == OBJECT_R_VAL) | 209 | if (c->role == OBJECT_R_VAL) |
| 204 | return 1; | 210 | return 1; |
| 205 | 211 | ||
