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 | ||