aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/ebitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss/ebitmap.c')
-rw-r--r--security/selinux/ss/ebitmap.c20
1 files changed, 18 insertions, 2 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
216int 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 */
221int 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;