diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/selinux/ss/ebitmap.c | 20 | ||||
-rw-r--r-- | security/selinux/ss/ebitmap.h | 2 | ||||
-rw-r--r-- | security/selinux/ss/mls.c | 22 | ||||
-rw-r--r-- | security/selinux/ss/mls_types.h | 2 |
4 files changed, 27 insertions, 19 deletions
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c index 30f119b1d1ec..820313a04d49 100644 --- a/security/selinux/ss/ebitmap.c +++ b/security/selinux/ss/ebitmap.c | |||
@@ -213,7 +213,12 @@ netlbl_import_failure: | |||
213 | } | 213 | } |
214 | #endif /* CONFIG_NETLABEL */ | 214 | #endif /* CONFIG_NETLABEL */ |
215 | 215 | ||
216 | int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2) | 216 | /* |
217 | * Check to see if all the bits set in e2 are also set in e1. Optionally, | ||
218 | * if last_e2bit is non-zero, the highest set bit in e2 cannot exceed | ||
219 | * last_e2bit. | ||
220 | */ | ||
221 | int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2, u32 last_e2bit) | ||
217 | { | 222 | { |
218 | struct ebitmap_node *n1, *n2; | 223 | struct ebitmap_node *n1, *n2; |
219 | int i; | 224 | int i; |
@@ -223,14 +228,25 @@ int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2) | |||
223 | 228 | ||
224 | n1 = e1->node; | 229 | n1 = e1->node; |
225 | n2 = e2->node; | 230 | n2 = e2->node; |
231 | |||
226 | while (n1 && n2 && (n1->startbit <= n2->startbit)) { | 232 | while (n1 && n2 && (n1->startbit <= n2->startbit)) { |
227 | if (n1->startbit < n2->startbit) { | 233 | if (n1->startbit < n2->startbit) { |
228 | n1 = n1->next; | 234 | n1 = n1->next; |
229 | continue; | 235 | continue; |
230 | } | 236 | } |
231 | for (i = 0; i < EBITMAP_UNIT_NUMS; i++) { | 237 | for (i = EBITMAP_UNIT_NUMS - 1; (i >= 0) && !n2->maps[i]; ) |
238 | i--; /* Skip trailing NULL map entries */ | ||
239 | if (last_e2bit && (i >= 0)) { | ||
240 | u32 lastsetbit = n2->startbit + i * EBITMAP_UNIT_SIZE + | ||
241 | __fls(n2->maps[i]); | ||
242 | if (lastsetbit > last_e2bit) | ||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | while (i >= 0) { | ||
232 | if ((n1->maps[i] & n2->maps[i]) != n2->maps[i]) | 247 | if ((n1->maps[i] & n2->maps[i]) != n2->maps[i]) |
233 | return 0; | 248 | return 0; |
249 | i--; | ||
234 | } | 250 | } |
235 | 251 | ||
236 | n1 = n1->next; | 252 | n1 = n1->next; |
diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h index 922f8afa89dd..e7eb3a9c5ab7 100644 --- a/security/selinux/ss/ebitmap.h +++ b/security/selinux/ss/ebitmap.h | |||
@@ -117,7 +117,7 @@ static inline void ebitmap_node_clr_bit(struct ebitmap_node *n, | |||
117 | 117 | ||
118 | int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2); | 118 | int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2); |
119 | int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src); | 119 | int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src); |
120 | int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2); | 120 | int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2, u32 last_e2bit); |
121 | int ebitmap_get_bit(struct ebitmap *e, unsigned long bit); | 121 | int ebitmap_get_bit(struct ebitmap *e, unsigned long bit); |
122 | int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value); | 122 | int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value); |
123 | void ebitmap_destroy(struct ebitmap *e); | 123 | void ebitmap_destroy(struct ebitmap *e); |
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index 40de8d3f208e..c85bc1ec040c 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c | |||
@@ -160,8 +160,6 @@ void mls_sid_to_context(struct context *context, | |||
160 | int mls_level_isvalid(struct policydb *p, struct mls_level *l) | 160 | int mls_level_isvalid(struct policydb *p, struct mls_level *l) |
161 | { | 161 | { |
162 | struct level_datum *levdatum; | 162 | struct level_datum *levdatum; |
163 | struct ebitmap_node *node; | ||
164 | int i; | ||
165 | 163 | ||
166 | if (!l->sens || l->sens > p->p_levels.nprim) | 164 | if (!l->sens || l->sens > p->p_levels.nprim) |
167 | return 0; | 165 | return 0; |
@@ -170,19 +168,13 @@ int mls_level_isvalid(struct policydb *p, struct mls_level *l) | |||
170 | if (!levdatum) | 168 | if (!levdatum) |
171 | return 0; | 169 | return 0; |
172 | 170 | ||
173 | ebitmap_for_each_positive_bit(&l->cat, node, i) { | 171 | /* |
174 | if (i > p->p_cats.nprim) | 172 | * Return 1 iff all the bits set in l->cat are also be set in |
175 | return 0; | 173 | * levdatum->level->cat and no bit in l->cat is larger than |
176 | if (!ebitmap_get_bit(&levdatum->level->cat, i)) { | 174 | * p->p_cats.nprim. |
177 | /* | 175 | */ |
178 | * Category may not be associated with | 176 | return ebitmap_contains(&levdatum->level->cat, &l->cat, |
179 | * sensitivity. | 177 | p->p_cats.nprim); |
180 | */ | ||
181 | return 0; | ||
182 | } | ||
183 | } | ||
184 | |||
185 | return 1; | ||
186 | } | 178 | } |
187 | 179 | ||
188 | int mls_range_isvalid(struct policydb *p, struct mls_range *r) | 180 | int mls_range_isvalid(struct policydb *p, struct mls_range *r) |
diff --git a/security/selinux/ss/mls_types.h b/security/selinux/ss/mls_types.h index 03bed52a8052..e93648774137 100644 --- a/security/selinux/ss/mls_types.h +++ b/security/selinux/ss/mls_types.h | |||
@@ -35,7 +35,7 @@ static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2) | |||
35 | static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2) | 35 | static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2) |
36 | { | 36 | { |
37 | return ((l1->sens >= l2->sens) && | 37 | return ((l1->sens >= l2->sens) && |
38 | ebitmap_contains(&l1->cat, &l2->cat)); | 38 | ebitmap_contains(&l1->cat, &l2->cat, 0)); |
39 | } | 39 | } |
40 | 40 | ||
41 | #define mls_level_incomp(l1, l2) \ | 41 | #define mls_level_incomp(l1, l2) \ |