aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2014-08-01 11:17:17 -0400
committerPaul Moore <pmoore@redhat.com>2014-08-01 11:17:17 -0400
commit4b8feff251da3d7058b5779e21b33a85c686b974 (patch)
tree600fb14c92a11abf730e9f26236d33ba5ae9c278
parent41c3bd2039e0d7b3dc32313141773f20716ec524 (diff)
netlabel: fix the horribly broken catmap functions
The NetLabel secattr catmap functions, and the SELinux import/export glue routines, were broken in many horrible ways and the SELinux glue code fiddled with the NetLabel catmap structures in ways that we probably shouldn't allow. At some point this "worked", but that was likely due to a bit of dumb luck and sub-par testing (both inflicted by yours truly). This patch corrects these problems by basically gutting the code in favor of something less obtuse and restoring the NetLabel abstractions in the SELinux catmap glue code. Everything is working now, and if it decides to break itself in the future this code will be much easier to debug than the code it replaces. One noteworthy side effect of the changes is that it is no longer necessary to allocate a NetLabel catmap before calling one of the NetLabel APIs to set a bit in the catmap. NetLabel will automatically allocate the catmap nodes when needed, resulting in less allocations when the lowest bit is greater than 255 and less code in the LSMs. Cc: stable@vger.kernel.org Reported-by: Christian Evans <frodox@zoho.com> Signed-off-by: Paul Moore <pmoore@redhat.com> Tested-by: Casey Schaufler <casey@schaufler-ca.com>
-rw-r--r--include/net/netlabel.h26
-rw-r--r--net/ipv4/cipso_ipv4.c12
-rw-r--r--net/netlabel/netlabel_kapi.c216
-rw-r--r--security/selinux/ss/ebitmap.c127
-rw-r--r--security/smack/smack_access.c5
5 files changed, 240 insertions, 146 deletions
diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index 1c40d658d008..bda7a121f31e 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -285,11 +285,11 @@ static inline void netlbl_secattr_catmap_free(
285{ 285{
286 struct netlbl_lsm_secattr_catmap *iter; 286 struct netlbl_lsm_secattr_catmap *iter;
287 287
288 do { 288 while (catmap) {
289 iter = catmap; 289 iter = catmap;
290 catmap = catmap->next; 290 catmap = catmap->next;
291 kfree(iter); 291 kfree(iter);
292 } while (catmap); 292 }
293} 293}
294 294
295/** 295/**
@@ -394,6 +394,9 @@ int netlbl_secattr_catmap_walk(struct netlbl_lsm_secattr_catmap *catmap,
394 u32 offset); 394 u32 offset);
395int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap, 395int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap,
396 u32 offset); 396 u32 offset);
397int netlbl_secattr_catmap_getlong(struct netlbl_lsm_secattr_catmap *catmap,
398 u32 *offset,
399 unsigned long *bitmap);
397int netlbl_secattr_catmap_setbit(struct netlbl_lsm_secattr_catmap **catmap, 400int netlbl_secattr_catmap_setbit(struct netlbl_lsm_secattr_catmap **catmap,
398 u32 bit, 401 u32 bit,
399 gfp_t flags); 402 gfp_t flags);
@@ -401,6 +404,10 @@ int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap **catmap,
401 u32 start, 404 u32 start,
402 u32 end, 405 u32 end,
403 gfp_t flags); 406 gfp_t flags);
407int netlbl_secattr_catmap_setlong(struct netlbl_lsm_secattr_catmap **catmap,
408 u32 offset,
409 unsigned long bitmap,
410 gfp_t flags);
404 411
405/* 412/*
406 * LSM protocol operations (NetLabel LSM/kernel API) 413 * LSM protocol operations (NetLabel LSM/kernel API)
@@ -504,6 +511,13 @@ static inline int netlbl_secattr_catmap_walk_rng(
504{ 511{
505 return -ENOENT; 512 return -ENOENT;
506} 513}
514static inline int netlbl_secattr_catmap_getlong(
515 struct netlbl_lsm_secattr_catmap *catmap,
516 u32 *offset,
517 unsigned long *bitmap)
518{
519 return 0;
520}
507static inline int netlbl_secattr_catmap_setbit( 521static inline int netlbl_secattr_catmap_setbit(
508 struct netlbl_lsm_secattr_catmap **catmap, 522 struct netlbl_lsm_secattr_catmap **catmap,
509 u32 bit, 523 u32 bit,
@@ -519,6 +533,14 @@ static inline int netlbl_secattr_catmap_setrng(
519{ 533{
520 return 0; 534 return 0;
521} 535}
536static int netlbl_secattr_catmap_setlong(
537 struct netlbl_lsm_secattr_catmap **catmap,
538 u32 offset,
539 unsigned long bitmap,
540 gfp_t flags)
541{
542 return 0;
543}
522static inline int netlbl_enabled(void) 544static inline int netlbl_enabled(void)
523{ 545{
524 return 0; 546 return 0;
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index dd433c943537..8a0c7bd6eff4 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -1335,10 +1335,6 @@ static int cipso_v4_parsetag_rbm(const struct cipso_v4_doi *doi_def,
1335 secattr->flags |= NETLBL_SECATTR_MLS_LVL; 1335 secattr->flags |= NETLBL_SECATTR_MLS_LVL;
1336 1336
1337 if (tag_len > 4) { 1337 if (tag_len > 4) {
1338 secattr->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
1339 if (secattr->attr.mls.cat == NULL)
1340 return -ENOMEM;
1341
1342 ret_val = cipso_v4_map_cat_rbm_ntoh(doi_def, 1338 ret_val = cipso_v4_map_cat_rbm_ntoh(doi_def,
1343 &tag[4], 1339 &tag[4],
1344 tag_len - 4, 1340 tag_len - 4,
@@ -1430,10 +1426,6 @@ static int cipso_v4_parsetag_enum(const struct cipso_v4_doi *doi_def,
1430 secattr->flags |= NETLBL_SECATTR_MLS_LVL; 1426 secattr->flags |= NETLBL_SECATTR_MLS_LVL;
1431 1427
1432 if (tag_len > 4) { 1428 if (tag_len > 4) {
1433 secattr->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
1434 if (secattr->attr.mls.cat == NULL)
1435 return -ENOMEM;
1436
1437 ret_val = cipso_v4_map_cat_enum_ntoh(doi_def, 1429 ret_val = cipso_v4_map_cat_enum_ntoh(doi_def,
1438 &tag[4], 1430 &tag[4],
1439 tag_len - 4, 1431 tag_len - 4,
@@ -1524,10 +1516,6 @@ static int cipso_v4_parsetag_rng(const struct cipso_v4_doi *doi_def,
1524 secattr->flags |= NETLBL_SECATTR_MLS_LVL; 1516 secattr->flags |= NETLBL_SECATTR_MLS_LVL;
1525 1517
1526 if (tag_len > 4) { 1518 if (tag_len > 4) {
1527 secattr->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
1528 if (secattr->attr.mls.cat == NULL)
1529 return -ENOMEM;
1530
1531 ret_val = cipso_v4_map_cat_rng_ntoh(doi_def, 1519 ret_val = cipso_v4_map_cat_rng_ntoh(doi_def,
1532 &tag[4], 1520 &tag[4],
1533 tag_len - 4, 1521 tag_len - 4,
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index 84e810bef39a..d9e10466b928 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -405,6 +405,63 @@ out_entry:
405 * Security Attribute Functions 405 * Security Attribute Functions
406 */ 406 */
407 407
408#define _CM_F_NONE 0x00000000
409#define _CM_F_ALLOC 0x00000001
410
411/**
412 * _netlbl_secattr_catmap_getnode - Get a individual node from a catmap
413 * @catmap: pointer to the category bitmap
414 * @offset: the requested offset
415 * @cm_flags: catmap flags, see _CM_F_*
416 * @gfp_flags: memory allocation flags
417 *
418 * Description:
419 * Iterate through the catmap looking for the node associated with @offset; if
420 * the _CM_F_ALLOC flag is set in @cm_flags and there is no associated node,
421 * one will be created and inserted into the catmap. Returns a pointer to the
422 * node on success, NULL on failure.
423 *
424 */
425static struct netlbl_lsm_secattr_catmap *_netlbl_secattr_catmap_getnode(
426 struct netlbl_lsm_secattr_catmap **catmap,
427 u32 offset,
428 unsigned int cm_flags,
429 gfp_t gfp_flags)
430{
431 struct netlbl_lsm_secattr_catmap *iter = *catmap;
432 struct netlbl_lsm_secattr_catmap *prev = NULL;
433
434 if (iter == NULL || offset < iter->startbit)
435 goto secattr_catmap_getnode_alloc;
436 while (iter && offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
437 prev = iter;
438 iter = iter->next;
439 }
440 if (iter == NULL || offset < iter->startbit)
441 goto secattr_catmap_getnode_alloc;
442
443 return iter;
444
445secattr_catmap_getnode_alloc:
446 if (!(cm_flags & _CM_F_ALLOC))
447 return NULL;
448
449 iter = netlbl_secattr_catmap_alloc(gfp_flags);
450 if (iter == NULL)
451 return NULL;
452 iter->startbit = offset & ~(NETLBL_CATMAP_SIZE - 1);
453
454 if (prev == NULL) {
455 iter->next = *catmap;
456 *catmap = iter;
457 } else {
458 iter->next = prev->next;
459 prev->next = iter;
460 }
461
462 return iter;
463}
464
408/** 465/**
409 * netlbl_secattr_catmap_walk - Walk a LSM secattr catmap looking for a bit 466 * netlbl_secattr_catmap_walk - Walk a LSM secattr catmap looking for a bit
410 * @catmap: the category bitmap 467 * @catmap: the category bitmap
@@ -521,6 +578,54 @@ int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap,
521} 578}
522 579
523/** 580/**
581 * netlbl_secattr_catmap_getlong - Export an unsigned long bitmap
582 * @catmap: pointer to the category bitmap
583 * @offset: pointer to the requested offset
584 * @bitmap: the exported bitmap
585 *
586 * Description:
587 * Export a bitmap with an offset greater than or equal to @offset and return
588 * it in @bitmap. The @offset must be aligned to an unsigned long and will be
589 * updated on return if different from what was requested; if the catmap is
590 * empty at the requested offset and beyond, the @offset is set to (u32)-1.
591 * Returns zero on sucess, negative values on failure.
592 *
593 */
594int netlbl_secattr_catmap_getlong(struct netlbl_lsm_secattr_catmap *catmap,
595 u32 *offset,
596 unsigned long *bitmap)
597{
598 struct netlbl_lsm_secattr_catmap *iter;
599 u32 off = *offset;
600 u32 idx;
601
602 /* only allow aligned offsets */
603 if ((off & (BITS_PER_LONG - 1)) != 0)
604 return -EINVAL;
605
606 if (off < catmap->startbit) {
607 off = catmap->startbit;
608 *offset = off;
609 }
610 iter = _netlbl_secattr_catmap_getnode(&catmap, off, _CM_F_NONE, 0);
611 if (iter == NULL) {
612 *offset = (u32)-1;
613 return 0;
614 }
615
616 if (off < iter->startbit) {
617 off = iter->startbit;
618 *offset = off;
619 } else
620 off -= iter->startbit;
621
622 idx = off / NETLBL_CATMAP_MAPSIZE;
623 *bitmap = iter->bitmap[idx] >> (off % NETLBL_CATMAP_SIZE);
624
625 return 0;
626}
627
628/**
524 * netlbl_secattr_catmap_setbit - Set a bit in a LSM secattr catmap 629 * netlbl_secattr_catmap_setbit - Set a bit in a LSM secattr catmap
525 * @catmap: pointer to the category bitmap 630 * @catmap: pointer to the category bitmap
526 * @bit: the bit to set 631 * @bit: the bit to set
@@ -535,32 +640,16 @@ int netlbl_secattr_catmap_setbit(struct netlbl_lsm_secattr_catmap **catmap,
535 u32 bit, 640 u32 bit,
536 gfp_t flags) 641 gfp_t flags)
537{ 642{
538 struct netlbl_lsm_secattr_catmap *iter = *catmap; 643 struct netlbl_lsm_secattr_catmap *iter;
539 u32 node_bit; 644 u32 idx;
540 u32 node_idx;
541 645
542 while (iter->next != NULL && 646 iter = _netlbl_secattr_catmap_getnode(catmap, bit, _CM_F_ALLOC, flags);
543 bit >= (iter->startbit + NETLBL_CATMAP_SIZE)) 647 if (iter == NULL)
544 iter = iter->next; 648 return -ENOMEM;
545 if (bit < iter->startbit) {
546 iter = netlbl_secattr_catmap_alloc(flags);
547 if (iter == NULL)
548 return -ENOMEM;
549 iter->next = *catmap;
550 iter->startbit = bit & ~(NETLBL_CATMAP_SIZE - 1);
551 *catmap = iter;
552 } else if (bit >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
553 iter->next = netlbl_secattr_catmap_alloc(flags);
554 if (iter->next == NULL)
555 return -ENOMEM;
556 iter = iter->next;
557 iter->startbit = bit & ~(NETLBL_CATMAP_SIZE - 1);
558 }
559 649
560 /* gcc always rounds to zero when doing integer division */ 650 bit -= iter->startbit;
561 node_idx = (bit - iter->startbit) / NETLBL_CATMAP_MAPSIZE; 651 idx = bit / NETLBL_CATMAP_MAPSIZE;
562 node_bit = bit - iter->startbit - (NETLBL_CATMAP_MAPSIZE * node_idx); 652 iter->bitmap[idx] |= NETLBL_CATMAP_BIT << (bit % NETLBL_CATMAP_MAPSIZE);
563 iter->bitmap[node_idx] |= NETLBL_CATMAP_BIT << node_bit;
564 653
565 return 0; 654 return 0;
566} 655}
@@ -582,34 +671,61 @@ int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap **catmap,
582 u32 end, 671 u32 end,
583 gfp_t flags) 672 gfp_t flags)
584{ 673{
585 int ret_val = 0; 674 int rc = 0;
586 struct netlbl_lsm_secattr_catmap *iter = *catmap; 675 u32 spot = start;
587 u32 iter_max_spot; 676
588 u32 spot; 677 while (rc == 0 && spot <= end) {
589 u32 orig_spot = iter->startbit; 678 if (((spot & (BITS_PER_LONG - 1)) != 0) &&
590 679 ((end - spot) > BITS_PER_LONG)) {
591 /* XXX - This could probably be made a bit faster by combining writes 680 rc = netlbl_secattr_catmap_setlong(catmap,
592 * to the catmap instead of setting a single bit each time, but for 681 spot,
593 * right now skipping to the start of the range in the catmap should 682 (unsigned long)-1,
594 * be a nice improvement over calling the individual setbit function 683 flags);
595 * repeatedly from a loop. */ 684 spot += BITS_PER_LONG;
596 685 } else
597 while (iter->next != NULL && 686 rc = netlbl_secattr_catmap_setbit(catmap,
598 start >= (iter->startbit + NETLBL_CATMAP_SIZE)) 687 spot++,
599 iter = iter->next; 688 flags);
600 iter_max_spot = iter->startbit + NETLBL_CATMAP_SIZE;
601
602 for (spot = start; spot <= end && ret_val == 0; spot++) {
603 if (spot >= iter_max_spot && iter->next != NULL) {
604 iter = iter->next;
605 iter_max_spot = iter->startbit + NETLBL_CATMAP_SIZE;
606 }
607 ret_val = netlbl_secattr_catmap_setbit(&iter, spot, flags);
608 if (iter->startbit < orig_spot)
609 *catmap = iter;
610 } 689 }
611 690
612 return ret_val; 691 return rc;
692}
693
694/**
695 * netlbl_secattr_catmap_setlong - Import an unsigned long bitmap
696 * @catmap: pointer to the category bitmap
697 * @offset: offset to the start of the imported bitmap
698 * @bitmap: the bitmap to import
699 * @flags: memory allocation flags
700 *
701 * Description:
702 * Import the bitmap specified in @bitmap into @catmap, using the offset
703 * in @offset. The offset must be aligned to an unsigned long. Returns zero
704 * on success, negative values on failure.
705 *
706 */
707int netlbl_secattr_catmap_setlong(struct netlbl_lsm_secattr_catmap **catmap,
708 u32 offset,
709 unsigned long bitmap,
710 gfp_t flags)
711{
712 struct netlbl_lsm_secattr_catmap *iter;
713 u32 idx;
714
715 /* only allow aligned offsets */
716 if ((offset & (BITS_PER_LONG - 1)) != 0)
717 return -EINVAL;
718
719 iter = _netlbl_secattr_catmap_getnode(catmap,
720 offset, _CM_F_ALLOC, flags);
721 if (iter == NULL)
722 return -ENOMEM;
723
724 offset -= iter->startbit;
725 idx = offset / NETLBL_CATMAP_MAPSIZE;
726 iter->bitmap[idx] |= bitmap << (offset % NETLBL_CATMAP_MAPSIZE);
727
728 return 0;
613} 729}
614 730
615/* 731/*
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index 820313a04d49..842deca9484d 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -89,48 +89,33 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap,
89 struct netlbl_lsm_secattr_catmap **catmap) 89 struct netlbl_lsm_secattr_catmap **catmap)
90{ 90{
91 struct ebitmap_node *e_iter = ebmap->node; 91 struct ebitmap_node *e_iter = ebmap->node;
92 struct netlbl_lsm_secattr_catmap *c_iter; 92 unsigned long e_map;
93 u32 cmap_idx, cmap_sft; 93 u32 offset;
94 int i; 94 unsigned int iter;
95 95 int rc;
96 /* NetLabel's NETLBL_CATMAP_MAPTYPE is defined as an array of u64,
97 * however, it is not always compatible with an array of unsigned long
98 * in ebitmap_node.
99 * In addition, you should pay attention the following implementation
100 * assumes unsigned long has a width equal with or less than 64-bit.
101 */
102 96
103 if (e_iter == NULL) { 97 if (e_iter == NULL) {
104 *catmap = NULL; 98 *catmap = NULL;
105 return 0; 99 return 0;
106 } 100 }
107 101
108 c_iter = netlbl_secattr_catmap_alloc(GFP_ATOMIC); 102 if (*catmap != NULL)
109 if (c_iter == NULL) 103 netlbl_secattr_catmap_free(*catmap);
110 return -ENOMEM; 104 *catmap = NULL;
111 *catmap = c_iter;
112 c_iter->startbit = e_iter->startbit & ~(NETLBL_CATMAP_SIZE - 1);
113 105
114 while (e_iter) { 106 while (e_iter) {
115 for (i = 0; i < EBITMAP_UNIT_NUMS; i++) { 107 offset = e_iter->startbit;
116 unsigned int delta, e_startbit, c_endbit; 108 for (iter = 0; iter < EBITMAP_UNIT_NUMS; iter++) {
117 109 e_map = e_iter->maps[iter];
118 e_startbit = e_iter->startbit + i * EBITMAP_UNIT_SIZE; 110 if (e_map != 0) {
119 c_endbit = c_iter->startbit + NETLBL_CATMAP_SIZE; 111 rc = netlbl_secattr_catmap_setlong(catmap,
120 if (e_startbit >= c_endbit) { 112 offset,
121 c_iter->next 113 e_map,
122 = netlbl_secattr_catmap_alloc(GFP_ATOMIC); 114 GFP_ATOMIC);
123 if (c_iter->next == NULL) 115 if (rc != 0)
124 goto netlbl_export_failure; 116 goto netlbl_export_failure;
125 c_iter = c_iter->next;
126 c_iter->startbit
127 = e_startbit & ~(NETLBL_CATMAP_SIZE - 1);
128 } 117 }
129 delta = e_startbit - c_iter->startbit; 118 offset += EBITMAP_UNIT_SIZE;
130 cmap_idx = delta / NETLBL_CATMAP_MAPSIZE;
131 cmap_sft = delta % NETLBL_CATMAP_MAPSIZE;
132 c_iter->bitmap[cmap_idx]
133 |= e_iter->maps[i] << cmap_sft;
134 } 119 }
135 e_iter = e_iter->next; 120 e_iter = e_iter->next;
136 } 121 }
@@ -155,56 +140,42 @@ netlbl_export_failure:
155int ebitmap_netlbl_import(struct ebitmap *ebmap, 140int ebitmap_netlbl_import(struct ebitmap *ebmap,
156 struct netlbl_lsm_secattr_catmap *catmap) 141 struct netlbl_lsm_secattr_catmap *catmap)
157{ 142{
143 int rc;
158 struct ebitmap_node *e_iter = NULL; 144 struct ebitmap_node *e_iter = NULL;
159 struct ebitmap_node *emap_prev = NULL; 145 struct ebitmap_node *e_prev = NULL;
160 struct netlbl_lsm_secattr_catmap *c_iter = catmap; 146 u32 offset = 0, idx;
161 u32 c_idx, c_pos, e_idx, e_sft; 147 unsigned long bitmap;
162 148
163 /* NetLabel's NETLBL_CATMAP_MAPTYPE is defined as an array of u64, 149 for (;;) {
164 * however, it is not always compatible with an array of unsigned long 150 rc = netlbl_secattr_catmap_getlong(catmap, &offset, &bitmap);
165 * in ebitmap_node. 151 if (rc < 0)
166 * In addition, you should pay attention the following implementation 152 goto netlbl_import_failure;
167 * assumes unsigned long has a width equal with or less than 64-bit. 153 if (offset == (u32)-1)
168 */ 154 return 0;
169
170 do {
171 for (c_idx = 0; c_idx < NETLBL_CATMAP_MAPCNT; c_idx++) {
172 unsigned int delta;
173 u64 map = c_iter->bitmap[c_idx];
174
175 if (!map)
176 continue;
177 155
178 c_pos = c_iter->startbit 156 if (e_iter == NULL ||
179 + c_idx * NETLBL_CATMAP_MAPSIZE; 157 offset >= e_iter->startbit + EBITMAP_SIZE) {
180 if (!e_iter 158 e_prev = e_iter;
181 || c_pos >= e_iter->startbit + EBITMAP_SIZE) { 159 e_iter = kzalloc(sizeof(*e_iter), GFP_ATOMIC);
182 e_iter = kzalloc(sizeof(*e_iter), GFP_ATOMIC); 160 if (e_iter == NULL)
183 if (!e_iter) 161 goto netlbl_import_failure;
184 goto netlbl_import_failure; 162 e_iter->startbit = offset & ~(EBITMAP_SIZE - 1);
185 e_iter->startbit 163 if (e_prev == NULL)
186 = c_pos - (c_pos % EBITMAP_SIZE); 164 ebmap->node = e_iter;
187 if (emap_prev == NULL) 165 else
188 ebmap->node = e_iter; 166 e_prev->next = e_iter;
189 else 167 ebmap->highbit = e_iter->startbit + EBITMAP_SIZE;
190 emap_prev->next = e_iter;
191 emap_prev = e_iter;
192 }
193 delta = c_pos - e_iter->startbit;
194 e_idx = delta / EBITMAP_UNIT_SIZE;
195 e_sft = delta % EBITMAP_UNIT_SIZE;
196 while (map) {
197 e_iter->maps[e_idx++] |= map & (-1UL);
198 map = EBITMAP_SHIFT_UNIT_SIZE(map);
199 }
200 } 168 }
201 c_iter = c_iter->next;
202 } while (c_iter);
203 if (e_iter != NULL)
204 ebmap->highbit = e_iter->startbit + EBITMAP_SIZE;
205 else
206 ebitmap_destroy(ebmap);
207 169
170 /* offset will always be aligned to an unsigned long */
171 idx = EBITMAP_NODE_INDEX(e_iter, offset);
172 e_iter->maps[idx] = bitmap;
173
174 /* next */
175 offset += EBITMAP_UNIT_SIZE;
176 }
177
178 /* NOTE: we should never reach this return */
208 return 0; 179 return 0;
209 180
210netlbl_import_failure: 181netlbl_import_failure:
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index 9ecf4f4b67a1..ea1bc5055792 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -435,10 +435,7 @@ int smk_netlbl_mls(int level, char *catset, struct netlbl_lsm_secattr *sap,
435 435
436 sap->flags |= NETLBL_SECATTR_MLS_CAT; 436 sap->flags |= NETLBL_SECATTR_MLS_CAT;
437 sap->attr.mls.lvl = level; 437 sap->attr.mls.lvl = level;
438 sap->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC); 438 sap->attr.mls.cat = NULL;
439 if (!sap->attr.mls.cat)
440 return -ENOMEM;
441 sap->attr.mls.cat->startbit = 0;
442 439
443 for (cat = 1, cp = catset, byte = 0; byte < len; cp++, byte++) 440 for (cat = 1, cp = catset, byte = 0; byte < len; cp++, byte++)
444 for (m = 0x80; m != 0; m >>= 1, cat++) { 441 for (m = 0x80; m != 0; m >>= 1, cat++) {