aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Morris <james.l.morris@oracle.com>2014-08-02 08:58:02 -0400
committerJames Morris <james.l.morris@oracle.com>2014-08-02 08:58:02 -0400
commit103ae675b12dee75ec099abf3d22857d1384b3bc (patch)
treea6b4f71bc911e7283b6573ee5833cd36a3ac2469
parenta3d64df849bcb84220bf6db5773a10eee1fad4dc (diff)
parent4fbe63d1c773cceef3fe1f6ed0c9c268f4f24760 (diff)
Merge branch 'next' of git://git.infradead.org/users/pcmoore/selinux into next
-rw-r--r--include/net/netlabel.h94
-rw-r--r--net/ipv4/cipso_ipv4.c47
-rw-r--r--net/netlabel/netlabel_kapi.c327
-rw-r--r--security/selinux/ss/ebitmap.c133
-rw-r--r--security/selinux/ss/ebitmap.h8
-rw-r--r--security/smack/smack_access.c11
-rw-r--r--security/smack/smack_lsm.c6
-rw-r--r--security/smack/smackfs.c14
8 files changed, 366 insertions, 274 deletions
diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index 4fe018c48ed9..a4fc39bb3e4f 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -139,7 +139,7 @@ struct netlbl_lsm_cache {
139}; 139};
140 140
141/** 141/**
142 * struct netlbl_lsm_secattr_catmap - NetLabel LSM secattr category bitmap 142 * struct netlbl_lsm_catmap - NetLabel LSM secattr category bitmap
143 * @startbit: the value of the lowest order bit in the bitmap 143 * @startbit: the value of the lowest order bit in the bitmap
144 * @bitmap: the category bitmap 144 * @bitmap: the category bitmap
145 * @next: pointer to the next bitmap "node" or NULL 145 * @next: pointer to the next bitmap "node" or NULL
@@ -162,10 +162,10 @@ struct netlbl_lsm_cache {
162#define NETLBL_CATMAP_SIZE (NETLBL_CATMAP_MAPSIZE * \ 162#define NETLBL_CATMAP_SIZE (NETLBL_CATMAP_MAPSIZE * \
163 NETLBL_CATMAP_MAPCNT) 163 NETLBL_CATMAP_MAPCNT)
164#define NETLBL_CATMAP_BIT (NETLBL_CATMAP_MAPTYPE)0x01 164#define NETLBL_CATMAP_BIT (NETLBL_CATMAP_MAPTYPE)0x01
165struct netlbl_lsm_secattr_catmap { 165struct netlbl_lsm_catmap {
166 u32 startbit; 166 u32 startbit;
167 NETLBL_CATMAP_MAPTYPE bitmap[NETLBL_CATMAP_MAPCNT]; 167 NETLBL_CATMAP_MAPTYPE bitmap[NETLBL_CATMAP_MAPCNT];
168 struct netlbl_lsm_secattr_catmap *next; 168 struct netlbl_lsm_catmap *next;
169}; 169};
170 170
171/** 171/**
@@ -209,7 +209,7 @@ struct netlbl_lsm_secattr {
209 struct netlbl_lsm_cache *cache; 209 struct netlbl_lsm_cache *cache;
210 struct { 210 struct {
211 struct { 211 struct {
212 struct netlbl_lsm_secattr_catmap *cat; 212 struct netlbl_lsm_catmap *cat;
213 u32 lvl; 213 u32 lvl;
214 } mls; 214 } mls;
215 u32 secid; 215 u32 secid;
@@ -258,7 +258,7 @@ static inline void netlbl_secattr_cache_free(struct netlbl_lsm_cache *cache)
258} 258}
259 259
260/** 260/**
261 * netlbl_secattr_catmap_alloc - Allocate a LSM secattr catmap 261 * netlbl_catmap_alloc - Allocate a LSM secattr catmap
262 * @flags: memory allocation flags 262 * @flags: memory allocation flags
263 * 263 *
264 * Description: 264 * Description:
@@ -266,30 +266,28 @@ static inline void netlbl_secattr_cache_free(struct netlbl_lsm_cache *cache)
266 * on failure. 266 * on failure.
267 * 267 *
268 */ 268 */
269static inline struct netlbl_lsm_secattr_catmap *netlbl_secattr_catmap_alloc( 269static inline struct netlbl_lsm_catmap *netlbl_catmap_alloc(gfp_t flags)
270 gfp_t flags)
271{ 270{
272 return kzalloc(sizeof(struct netlbl_lsm_secattr_catmap), flags); 271 return kzalloc(sizeof(struct netlbl_lsm_catmap), flags);
273} 272}
274 273
275/** 274/**
276 * netlbl_secattr_catmap_free - Free a LSM secattr catmap 275 * netlbl_catmap_free - Free a LSM secattr catmap
277 * @catmap: the category bitmap 276 * @catmap: the category bitmap
278 * 277 *
279 * Description: 278 * Description:
280 * Free a LSM secattr catmap. 279 * Free a LSM secattr catmap.
281 * 280 *
282 */ 281 */
283static inline void netlbl_secattr_catmap_free( 282static inline void netlbl_catmap_free(struct netlbl_lsm_catmap *catmap)
284 struct netlbl_lsm_secattr_catmap *catmap)
285{ 283{
286 struct netlbl_lsm_secattr_catmap *iter; 284 struct netlbl_lsm_catmap *iter;
287 285
288 do { 286 while (catmap) {
289 iter = catmap; 287 iter = catmap;
290 catmap = catmap->next; 288 catmap = catmap->next;
291 kfree(iter); 289 kfree(iter);
292 } while (catmap); 290 }
293} 291}
294 292
295/** 293/**
@@ -321,7 +319,7 @@ static inline void netlbl_secattr_destroy(struct netlbl_lsm_secattr *secattr)
321 if (secattr->flags & NETLBL_SECATTR_CACHE) 319 if (secattr->flags & NETLBL_SECATTR_CACHE)
322 netlbl_secattr_cache_free(secattr->cache); 320 netlbl_secattr_cache_free(secattr->cache);
323 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) 321 if (secattr->flags & NETLBL_SECATTR_MLS_CAT)
324 netlbl_secattr_catmap_free(secattr->attr.mls.cat); 322 netlbl_catmap_free(secattr->attr.mls.cat);
325} 323}
326 324
327/** 325/**
@@ -390,17 +388,22 @@ int netlbl_cfg_cipsov4_map_add(u32 doi,
390/* 388/*
391 * LSM security attribute operations 389 * LSM security attribute operations
392 */ 390 */
393int netlbl_secattr_catmap_walk(struct netlbl_lsm_secattr_catmap *catmap, 391int netlbl_catmap_walk(struct netlbl_lsm_catmap *catmap, u32 offset);
394 u32 offset); 392int netlbl_catmap_walkrng(struct netlbl_lsm_catmap *catmap, u32 offset);
395int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap, 393int netlbl_catmap_getlong(struct netlbl_lsm_catmap *catmap,
396 u32 offset); 394 u32 *offset,
397int netlbl_secattr_catmap_setbit(struct netlbl_lsm_secattr_catmap *catmap, 395 unsigned long *bitmap);
398 u32 bit, 396int netlbl_catmap_setbit(struct netlbl_lsm_catmap **catmap,
399 gfp_t flags); 397 u32 bit,
400int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap, 398 gfp_t flags);
401 u32 start, 399int netlbl_catmap_setrng(struct netlbl_lsm_catmap **catmap,
402 u32 end, 400 u32 start,
403 gfp_t flags); 401 u32 end,
402 gfp_t flags);
403int netlbl_catmap_setlong(struct netlbl_lsm_catmap **catmap,
404 u32 offset,
405 unsigned long bitmap,
406 gfp_t flags);
404 407
405/* 408/*
406 * LSM protocol operations (NetLabel LSM/kernel API) 409 * LSM protocol operations (NetLabel LSM/kernel API)
@@ -492,30 +495,39 @@ static inline int netlbl_cfg_cipsov4_map_add(u32 doi,
492{ 495{
493 return -ENOSYS; 496 return -ENOSYS;
494} 497}
495static inline int netlbl_secattr_catmap_walk( 498static inline int netlbl_catmap_walk(struct netlbl_lsm_catmap *catmap,
496 struct netlbl_lsm_secattr_catmap *catmap, 499 u32 offset)
497 u32 offset)
498{ 500{
499 return -ENOENT; 501 return -ENOENT;
500} 502}
501static inline int netlbl_secattr_catmap_walk_rng( 503static inline int netlbl_catmap_walkrng(struct netlbl_lsm_catmap *catmap,
502 struct netlbl_lsm_secattr_catmap *catmap, 504 u32 offset)
503 u32 offset)
504{ 505{
505 return -ENOENT; 506 return -ENOENT;
506} 507}
507static inline int netlbl_secattr_catmap_setbit( 508static inline int netlbl_catmap_getlong(struct netlbl_lsm_catmap *catmap,
508 struct netlbl_lsm_secattr_catmap *catmap, 509 u32 *offset,
509 u32 bit, 510 unsigned long *bitmap)
510 gfp_t flags)
511{ 511{
512 return 0; 512 return 0;
513} 513}
514static inline int netlbl_secattr_catmap_setrng( 514static inline int netlbl_catmap_setbit(struct netlbl_lsm_catmap **catmap,
515 struct netlbl_lsm_secattr_catmap *catmap, 515 u32 bit,
516 u32 start, 516 gfp_t flags)
517 u32 end, 517{
518 gfp_t flags) 518 return 0;
519}
520static inline int netlbl_catmap_setrng(struct netlbl_lsm_catmap **catmap,
521 u32 start,
522 u32 end,
523 gfp_t flags)
524{
525 return 0;
526}
527static int netlbl_catmap_setlong(struct netlbl_lsm_catmap **catmap,
528 u32 offset,
529 unsigned long bitmap,
530 gfp_t flags)
519{ 531{
520 return 0; 532 return 0;
521} 533}
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index 69e77c8ff285..05b708bbdb0d 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -890,8 +890,8 @@ static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def,
890 } 890 }
891 891
892 for (;;) { 892 for (;;) {
893 host_spot = netlbl_secattr_catmap_walk(secattr->attr.mls.cat, 893 host_spot = netlbl_catmap_walk(secattr->attr.mls.cat,
894 host_spot + 1); 894 host_spot + 1);
895 if (host_spot < 0) 895 if (host_spot < 0)
896 break; 896 break;
897 897
@@ -973,7 +973,7 @@ static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,
973 return -EPERM; 973 return -EPERM;
974 break; 974 break;
975 } 975 }
976 ret_val = netlbl_secattr_catmap_setbit(secattr->attr.mls.cat, 976 ret_val = netlbl_catmap_setbit(&secattr->attr.mls.cat,
977 host_spot, 977 host_spot,
978 GFP_ATOMIC); 978 GFP_ATOMIC);
979 if (ret_val != 0) 979 if (ret_val != 0)
@@ -1039,8 +1039,7 @@ static int cipso_v4_map_cat_enum_hton(const struct cipso_v4_doi *doi_def,
1039 u32 cat_iter = 0; 1039 u32 cat_iter = 0;
1040 1040
1041 for (;;) { 1041 for (;;) {
1042 cat = netlbl_secattr_catmap_walk(secattr->attr.mls.cat, 1042 cat = netlbl_catmap_walk(secattr->attr.mls.cat, cat + 1);
1043 cat + 1);
1044 if (cat < 0) 1043 if (cat < 0)
1045 break; 1044 break;
1046 if ((cat_iter + 2) > net_cat_len) 1045 if ((cat_iter + 2) > net_cat_len)
@@ -1075,9 +1074,9 @@ static int cipso_v4_map_cat_enum_ntoh(const struct cipso_v4_doi *doi_def,
1075 u32 iter; 1074 u32 iter;
1076 1075
1077 for (iter = 0; iter < net_cat_len; iter += 2) { 1076 for (iter = 0; iter < net_cat_len; iter += 2) {
1078 ret_val = netlbl_secattr_catmap_setbit(secattr->attr.mls.cat, 1077 ret_val = netlbl_catmap_setbit(&secattr->attr.mls.cat,
1079 get_unaligned_be16(&net_cat[iter]), 1078 get_unaligned_be16(&net_cat[iter]),
1080 GFP_ATOMIC); 1079 GFP_ATOMIC);
1081 if (ret_val != 0) 1080 if (ret_val != 0)
1082 return ret_val; 1081 return ret_val;
1083 } 1082 }
@@ -1155,8 +1154,7 @@ static int cipso_v4_map_cat_rng_hton(const struct cipso_v4_doi *doi_def,
1155 return -ENOSPC; 1154 return -ENOSPC;
1156 1155
1157 for (;;) { 1156 for (;;) {
1158 iter = netlbl_secattr_catmap_walk(secattr->attr.mls.cat, 1157 iter = netlbl_catmap_walk(secattr->attr.mls.cat, iter + 1);
1159 iter + 1);
1160 if (iter < 0) 1158 if (iter < 0)
1161 break; 1159 break;
1162 cat_size += (iter == 0 ? 0 : sizeof(u16)); 1160 cat_size += (iter == 0 ? 0 : sizeof(u16));
@@ -1164,8 +1162,7 @@ static int cipso_v4_map_cat_rng_hton(const struct cipso_v4_doi *doi_def,
1164 return -ENOSPC; 1162 return -ENOSPC;
1165 array[array_cnt++] = iter; 1163 array[array_cnt++] = iter;
1166 1164
1167 iter = netlbl_secattr_catmap_walk_rng(secattr->attr.mls.cat, 1165 iter = netlbl_catmap_walkrng(secattr->attr.mls.cat, iter);
1168 iter);
1169 if (iter < 0) 1166 if (iter < 0)
1170 return -EFAULT; 1167 return -EFAULT;
1171 cat_size += sizeof(u16); 1168 cat_size += sizeof(u16);
@@ -1217,10 +1214,10 @@ static int cipso_v4_map_cat_rng_ntoh(const struct cipso_v4_doi *doi_def,
1217 else 1214 else
1218 cat_low = 0; 1215 cat_low = 0;
1219 1216
1220 ret_val = netlbl_secattr_catmap_setrng(secattr->attr.mls.cat, 1217 ret_val = netlbl_catmap_setrng(&secattr->attr.mls.cat,
1221 cat_low, 1218 cat_low,
1222 cat_high, 1219 cat_high,
1223 GFP_ATOMIC); 1220 GFP_ATOMIC);
1224 if (ret_val != 0) 1221 if (ret_val != 0)
1225 return ret_val; 1222 return ret_val;
1226 } 1223 }
@@ -1335,16 +1332,12 @@ static int cipso_v4_parsetag_rbm(const struct cipso_v4_doi *doi_def,
1335 secattr->flags |= NETLBL_SECATTR_MLS_LVL; 1332 secattr->flags |= NETLBL_SECATTR_MLS_LVL;
1336 1333
1337 if (tag_len > 4) { 1334 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, 1335 ret_val = cipso_v4_map_cat_rbm_ntoh(doi_def,
1343 &tag[4], 1336 &tag[4],
1344 tag_len - 4, 1337 tag_len - 4,
1345 secattr); 1338 secattr);
1346 if (ret_val != 0) { 1339 if (ret_val != 0) {
1347 netlbl_secattr_catmap_free(secattr->attr.mls.cat); 1340 netlbl_catmap_free(secattr->attr.mls.cat);
1348 return ret_val; 1341 return ret_val;
1349 } 1342 }
1350 1343
@@ -1430,16 +1423,12 @@ static int cipso_v4_parsetag_enum(const struct cipso_v4_doi *doi_def,
1430 secattr->flags |= NETLBL_SECATTR_MLS_LVL; 1423 secattr->flags |= NETLBL_SECATTR_MLS_LVL;
1431 1424
1432 if (tag_len > 4) { 1425 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, 1426 ret_val = cipso_v4_map_cat_enum_ntoh(doi_def,
1438 &tag[4], 1427 &tag[4],
1439 tag_len - 4, 1428 tag_len - 4,
1440 secattr); 1429 secattr);
1441 if (ret_val != 0) { 1430 if (ret_val != 0) {
1442 netlbl_secattr_catmap_free(secattr->attr.mls.cat); 1431 netlbl_catmap_free(secattr->attr.mls.cat);
1443 return ret_val; 1432 return ret_val;
1444 } 1433 }
1445 1434
@@ -1524,16 +1513,12 @@ static int cipso_v4_parsetag_rng(const struct cipso_v4_doi *doi_def,
1524 secattr->flags |= NETLBL_SECATTR_MLS_LVL; 1513 secattr->flags |= NETLBL_SECATTR_MLS_LVL;
1525 1514
1526 if (tag_len > 4) { 1515 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, 1516 ret_val = cipso_v4_map_cat_rng_ntoh(doi_def,
1532 &tag[4], 1517 &tag[4],
1533 tag_len - 4, 1518 tag_len - 4,
1534 secattr); 1519 secattr);
1535 if (ret_val != 0) { 1520 if (ret_val != 0) {
1536 netlbl_secattr_catmap_free(secattr->attr.mls.cat); 1521 netlbl_catmap_free(secattr->attr.mls.cat);
1537 return ret_val; 1522 return ret_val;
1538 } 1523 }
1539 1524
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index 3045a964f39c..05ea4a4cc0ac 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -405,8 +405,72 @@ 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#define _CM_F_WALK 0x00000002
411
408/** 412/**
409 * netlbl_secattr_catmap_walk - Walk a LSM secattr catmap looking for a bit 413 * _netlbl_catmap_getnode - Get a individual node from a catmap
414 * @catmap: pointer to the category bitmap
415 * @offset: the requested offset
416 * @cm_flags: catmap flags, see _CM_F_*
417 * @gfp_flags: memory allocation flags
418 *
419 * Description:
420 * Iterate through the catmap looking for the node associated with @offset.
421 * If the _CM_F_ALLOC flag is set in @cm_flags and there is no associated node,
422 * one will be created and inserted into the catmap. If the _CM_F_WALK flag is
423 * set in @cm_flags and there is no associated node, the next highest node will
424 * be returned. Returns a pointer to the node on success, NULL on failure.
425 *
426 */
427static struct netlbl_lsm_catmap *_netlbl_catmap_getnode(
428 struct netlbl_lsm_catmap **catmap,
429 u32 offset,
430 unsigned int cm_flags,
431 gfp_t gfp_flags)
432{
433 struct netlbl_lsm_catmap *iter = *catmap;
434 struct netlbl_lsm_catmap *prev = NULL;
435
436 if (iter == NULL)
437 goto catmap_getnode_alloc;
438 if (offset < iter->startbit)
439 goto catmap_getnode_walk;
440 while (iter && offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
441 prev = iter;
442 iter = iter->next;
443 }
444 if (iter == NULL || offset < iter->startbit)
445 goto catmap_getnode_walk;
446
447 return iter;
448
449catmap_getnode_walk:
450 if (cm_flags & _CM_F_WALK)
451 return iter;
452catmap_getnode_alloc:
453 if (!(cm_flags & _CM_F_ALLOC))
454 return NULL;
455
456 iter = netlbl_catmap_alloc(gfp_flags);
457 if (iter == NULL)
458 return NULL;
459 iter->startbit = offset & ~(NETLBL_CATMAP_SIZE - 1);
460
461 if (prev == NULL) {
462 iter->next = *catmap;
463 *catmap = iter;
464 } else {
465 iter->next = prev->next;
466 prev->next = iter;
467 }
468
469 return iter;
470}
471
472/**
473 * netlbl_catmap_walk - Walk a LSM secattr catmap looking for a bit
410 * @catmap: the category bitmap 474 * @catmap: the category bitmap
411 * @offset: the offset to start searching at, in bits 475 * @offset: the offset to start searching at, in bits
412 * 476 *
@@ -415,54 +479,51 @@ out_entry:
415 * returns the spot of the first set bit or -ENOENT if no bits are set. 479 * returns the spot of the first set bit or -ENOENT if no bits are set.
416 * 480 *
417 */ 481 */
418int netlbl_secattr_catmap_walk(struct netlbl_lsm_secattr_catmap *catmap, 482int netlbl_catmap_walk(struct netlbl_lsm_catmap *catmap, u32 offset)
419 u32 offset)
420{ 483{
421 struct netlbl_lsm_secattr_catmap *iter = catmap; 484 struct netlbl_lsm_catmap *iter = catmap;
422 u32 node_idx; 485 u32 idx;
423 u32 node_bit; 486 u32 bit;
424 NETLBL_CATMAP_MAPTYPE bitmap; 487 NETLBL_CATMAP_MAPTYPE bitmap;
425 488
489 iter = _netlbl_catmap_getnode(&catmap, offset, _CM_F_WALK, 0);
490 if (iter == NULL)
491 return -ENOENT;
426 if (offset > iter->startbit) { 492 if (offset > iter->startbit) {
427 while (offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) { 493 offset -= iter->startbit;
428 iter = iter->next; 494 idx = offset / NETLBL_CATMAP_MAPSIZE;
429 if (iter == NULL) 495 bit = offset % NETLBL_CATMAP_MAPSIZE;
430 return -ENOENT;
431 }
432 node_idx = (offset - iter->startbit) / NETLBL_CATMAP_MAPSIZE;
433 node_bit = offset - iter->startbit -
434 (NETLBL_CATMAP_MAPSIZE * node_idx);
435 } else { 496 } else {
436 node_idx = 0; 497 idx = 0;
437 node_bit = 0; 498 bit = 0;
438 } 499 }
439 bitmap = iter->bitmap[node_idx] >> node_bit; 500 bitmap = iter->bitmap[idx] >> bit;
440 501
441 for (;;) { 502 for (;;) {
442 if (bitmap != 0) { 503 if (bitmap != 0) {
443 while ((bitmap & NETLBL_CATMAP_BIT) == 0) { 504 while ((bitmap & NETLBL_CATMAP_BIT) == 0) {
444 bitmap >>= 1; 505 bitmap >>= 1;
445 node_bit++; 506 bit++;
446 } 507 }
447 return iter->startbit + 508 return iter->startbit +
448 (NETLBL_CATMAP_MAPSIZE * node_idx) + node_bit; 509 (NETLBL_CATMAP_MAPSIZE * idx) + bit;
449 } 510 }
450 if (++node_idx >= NETLBL_CATMAP_MAPCNT) { 511 if (++idx >= NETLBL_CATMAP_MAPCNT) {
451 if (iter->next != NULL) { 512 if (iter->next != NULL) {
452 iter = iter->next; 513 iter = iter->next;
453 node_idx = 0; 514 idx = 0;
454 } else 515 } else
455 return -ENOENT; 516 return -ENOENT;
456 } 517 }
457 bitmap = iter->bitmap[node_idx]; 518 bitmap = iter->bitmap[idx];
458 node_bit = 0; 519 bit = 0;
459 } 520 }
460 521
461 return -ENOENT; 522 return -ENOENT;
462} 523}
463 524
464/** 525/**
465 * netlbl_secattr_catmap_walk_rng - Find the end of a string of set bits 526 * netlbl_catmap_walkrng - Find the end of a string of set bits
466 * @catmap: the category bitmap 527 * @catmap: the category bitmap
467 * @offset: the offset to start searching at, in bits 528 * @offset: the offset to start searching at, in bits
468 * 529 *
@@ -472,57 +533,105 @@ int netlbl_secattr_catmap_walk(struct netlbl_lsm_secattr_catmap *catmap,
472 * the end of the bitmap. 533 * the end of the bitmap.
473 * 534 *
474 */ 535 */
475int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap, 536int netlbl_catmap_walkrng(struct netlbl_lsm_catmap *catmap, u32 offset)
476 u32 offset)
477{ 537{
478 struct netlbl_lsm_secattr_catmap *iter = catmap; 538 struct netlbl_lsm_catmap *iter;
479 u32 node_idx; 539 struct netlbl_lsm_catmap *prev = NULL;
480 u32 node_bit; 540 u32 idx;
541 u32 bit;
481 NETLBL_CATMAP_MAPTYPE bitmask; 542 NETLBL_CATMAP_MAPTYPE bitmask;
482 NETLBL_CATMAP_MAPTYPE bitmap; 543 NETLBL_CATMAP_MAPTYPE bitmap;
483 544
545 iter = _netlbl_catmap_getnode(&catmap, offset, _CM_F_WALK, 0);
546 if (iter == NULL)
547 return -ENOENT;
484 if (offset > iter->startbit) { 548 if (offset > iter->startbit) {
485 while (offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) { 549 offset -= iter->startbit;
486 iter = iter->next; 550 idx = offset / NETLBL_CATMAP_MAPSIZE;
487 if (iter == NULL) 551 bit = offset % NETLBL_CATMAP_MAPSIZE;
488 return -ENOENT;
489 }
490 node_idx = (offset - iter->startbit) / NETLBL_CATMAP_MAPSIZE;
491 node_bit = offset - iter->startbit -
492 (NETLBL_CATMAP_MAPSIZE * node_idx);
493 } else { 552 } else {
494 node_idx = 0; 553 idx = 0;
495 node_bit = 0; 554 bit = 0;
496 } 555 }
497 bitmask = NETLBL_CATMAP_BIT << node_bit; 556 bitmask = NETLBL_CATMAP_BIT << bit;
498 557
499 for (;;) { 558 for (;;) {
500 bitmap = iter->bitmap[node_idx]; 559 bitmap = iter->bitmap[idx];
501 while (bitmask != 0 && (bitmap & bitmask) != 0) { 560 while (bitmask != 0 && (bitmap & bitmask) != 0) {
502 bitmask <<= 1; 561 bitmask <<= 1;
503 node_bit++; 562 bit++;
504 } 563 }
505 564
506 if (bitmask != 0) 565 if (prev && idx == 0 && bit == 0)
566 return prev->startbit + NETLBL_CATMAP_SIZE - 1;
567 else if (bitmask != 0)
507 return iter->startbit + 568 return iter->startbit +
508 (NETLBL_CATMAP_MAPSIZE * node_idx) + 569 (NETLBL_CATMAP_MAPSIZE * idx) + bit - 1;
509 node_bit - 1; 570 else if (++idx >= NETLBL_CATMAP_MAPCNT) {
510 else if (++node_idx >= NETLBL_CATMAP_MAPCNT) {
511 if (iter->next == NULL) 571 if (iter->next == NULL)
512 return iter->startbit + NETLBL_CATMAP_SIZE - 1; 572 return iter->startbit + NETLBL_CATMAP_SIZE - 1;
573 prev = iter;
513 iter = iter->next; 574 iter = iter->next;
514 node_idx = 0; 575 idx = 0;
515 } 576 }
516 bitmask = NETLBL_CATMAP_BIT; 577 bitmask = NETLBL_CATMAP_BIT;
517 node_bit = 0; 578 bit = 0;
518 } 579 }
519 580
520 return -ENOENT; 581 return -ENOENT;
521} 582}
522 583
523/** 584/**
524 * netlbl_secattr_catmap_setbit - Set a bit in a LSM secattr catmap 585 * netlbl_catmap_getlong - Export an unsigned long bitmap
525 * @catmap: the category bitmap 586 * @catmap: pointer to the category bitmap
587 * @offset: pointer to the requested offset
588 * @bitmap: the exported bitmap
589 *
590 * Description:
591 * Export a bitmap with an offset greater than or equal to @offset and return
592 * it in @bitmap. The @offset must be aligned to an unsigned long and will be
593 * updated on return if different from what was requested; if the catmap is
594 * empty at the requested offset and beyond, the @offset is set to (u32)-1.
595 * Returns zero on sucess, negative values on failure.
596 *
597 */
598int netlbl_catmap_getlong(struct netlbl_lsm_catmap *catmap,
599 u32 *offset,
600 unsigned long *bitmap)
601{
602 struct netlbl_lsm_catmap *iter;
603 u32 off = *offset;
604 u32 idx;
605
606 /* only allow aligned offsets */
607 if ((off & (BITS_PER_LONG - 1)) != 0)
608 return -EINVAL;
609
610 if (off < catmap->startbit) {
611 off = catmap->startbit;
612 *offset = off;
613 }
614 iter = _netlbl_catmap_getnode(&catmap, off, _CM_F_NONE, 0);
615 if (iter == NULL) {
616 *offset = (u32)-1;
617 return 0;
618 }
619
620 if (off < iter->startbit) {
621 off = iter->startbit;
622 *offset = off;
623 } else
624 off -= iter->startbit;
625
626 idx = off / NETLBL_CATMAP_MAPSIZE;
627 *bitmap = iter->bitmap[idx] >> (off % NETLBL_CATMAP_SIZE);
628
629 return 0;
630}
631
632/**
633 * netlbl_catmap_setbit - Set a bit in a LSM secattr catmap
634 * @catmap: pointer to the category bitmap
526 * @bit: the bit to set 635 * @bit: the bit to set
527 * @flags: memory allocation flags 636 * @flags: memory allocation flags
528 * 637 *
@@ -531,36 +640,27 @@ int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap,
531 * negative values on failure. 640 * negative values on failure.
532 * 641 *
533 */ 642 */
534int netlbl_secattr_catmap_setbit(struct netlbl_lsm_secattr_catmap *catmap, 643int netlbl_catmap_setbit(struct netlbl_lsm_catmap **catmap,
535 u32 bit, 644 u32 bit,
536 gfp_t flags) 645 gfp_t flags)
537{ 646{
538 struct netlbl_lsm_secattr_catmap *iter = catmap; 647 struct netlbl_lsm_catmap *iter;
539 u32 node_bit; 648 u32 idx;
540 u32 node_idx;
541 649
542 while (iter->next != NULL && 650 iter = _netlbl_catmap_getnode(catmap, bit, _CM_F_ALLOC, flags);
543 bit >= (iter->startbit + NETLBL_CATMAP_SIZE)) 651 if (iter == NULL)
544 iter = iter->next; 652 return -ENOMEM;
545 if (bit >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
546 iter->next = netlbl_secattr_catmap_alloc(flags);
547 if (iter->next == NULL)
548 return -ENOMEM;
549 iter = iter->next;
550 iter->startbit = bit & ~(NETLBL_CATMAP_SIZE - 1);
551 }
552 653
553 /* gcc always rounds to zero when doing integer division */ 654 bit -= iter->startbit;
554 node_idx = (bit - iter->startbit) / NETLBL_CATMAP_MAPSIZE; 655 idx = bit / NETLBL_CATMAP_MAPSIZE;
555 node_bit = bit - iter->startbit - (NETLBL_CATMAP_MAPSIZE * node_idx); 656 iter->bitmap[idx] |= NETLBL_CATMAP_BIT << (bit % NETLBL_CATMAP_MAPSIZE);
556 iter->bitmap[node_idx] |= NETLBL_CATMAP_BIT << node_bit;
557 657
558 return 0; 658 return 0;
559} 659}
560 660
561/** 661/**
562 * netlbl_secattr_catmap_setrng - Set a range of bits in a LSM secattr catmap 662 * netlbl_catmap_setrng - Set a range of bits in a LSM secattr catmap
563 * @catmap: the category bitmap 663 * @catmap: pointer to the category bitmap
564 * @start: the starting bit 664 * @start: the starting bit
565 * @end: the last bit in the string 665 * @end: the last bit in the string
566 * @flags: memory allocation flags 666 * @flags: memory allocation flags
@@ -570,36 +670,63 @@ int netlbl_secattr_catmap_setbit(struct netlbl_lsm_secattr_catmap *catmap,
570 * on success, negative values on failure. 670 * on success, negative values on failure.
571 * 671 *
572 */ 672 */
573int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap, 673int netlbl_catmap_setrng(struct netlbl_lsm_catmap **catmap,
574 u32 start, 674 u32 start,
575 u32 end, 675 u32 end,
576 gfp_t flags) 676 gfp_t flags)
577{ 677{
578 int ret_val = 0; 678 int rc = 0;
579 struct netlbl_lsm_secattr_catmap *iter = catmap; 679 u32 spot = start;
580 u32 iter_max_spot; 680
581 u32 spot; 681 while (rc == 0 && spot <= end) {
582 682 if (((spot & (BITS_PER_LONG - 1)) != 0) &&
583 /* XXX - This could probably be made a bit faster by combining writes 683 ((end - spot) > BITS_PER_LONG)) {
584 * to the catmap instead of setting a single bit each time, but for 684 rc = netlbl_catmap_setlong(catmap,
585 * right now skipping to the start of the range in the catmap should 685 spot,
586 * be a nice improvement over calling the individual setbit function 686 (unsigned long)-1,
587 * repeatedly from a loop. */ 687 flags);
588 688 spot += BITS_PER_LONG;
589 while (iter->next != NULL && 689 } else
590 start >= (iter->startbit + NETLBL_CATMAP_SIZE)) 690 rc = netlbl_catmap_setbit(catmap, spot++, flags);
591 iter = iter->next;
592 iter_max_spot = iter->startbit + NETLBL_CATMAP_SIZE;
593
594 for (spot = start; spot <= end && ret_val == 0; spot++) {
595 if (spot >= iter_max_spot && iter->next != NULL) {
596 iter = iter->next;
597 iter_max_spot = iter->startbit + NETLBL_CATMAP_SIZE;
598 }
599 ret_val = netlbl_secattr_catmap_setbit(iter, spot, flags);
600 } 691 }
601 692
602 return ret_val; 693 return rc;
694}
695
696/**
697 * netlbl_catmap_setlong - Import an unsigned long bitmap
698 * @catmap: pointer to the category bitmap
699 * @offset: offset to the start of the imported bitmap
700 * @bitmap: the bitmap to import
701 * @flags: memory allocation flags
702 *
703 * Description:
704 * Import the bitmap specified in @bitmap into @catmap, using the offset
705 * in @offset. The offset must be aligned to an unsigned long. Returns zero
706 * on success, negative values on failure.
707 *
708 */
709int netlbl_catmap_setlong(struct netlbl_lsm_catmap **catmap,
710 u32 offset,
711 unsigned long bitmap,
712 gfp_t flags)
713{
714 struct netlbl_lsm_catmap *iter;
715 u32 idx;
716
717 /* only allow aligned offsets */
718 if ((offset & (BITS_PER_LONG - 1)) != 0)
719 return -EINVAL;
720
721 iter = _netlbl_catmap_getnode(catmap, offset, _CM_F_ALLOC, flags);
722 if (iter == NULL)
723 return -ENOMEM;
724
725 offset -= iter->startbit;
726 idx = offset / NETLBL_CATMAP_MAPSIZE;
727 iter->bitmap[idx] |= bitmap << (offset % NETLBL_CATMAP_MAPSIZE);
728
729 return 0;
603} 730}
604 731
605/* 732/*
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index 820313a04d49..afe6a269ec17 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -86,51 +86,36 @@ int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src)
86 * 86 *
87 */ 87 */
88int ebitmap_netlbl_export(struct ebitmap *ebmap, 88int ebitmap_netlbl_export(struct ebitmap *ebmap,
89 struct netlbl_lsm_secattr_catmap **catmap) 89 struct netlbl_lsm_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_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_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 }
@@ -138,7 +123,7 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap,
138 return 0; 123 return 0;
139 124
140netlbl_export_failure: 125netlbl_export_failure:
141 netlbl_secattr_catmap_free(*catmap); 126 netlbl_catmap_free(*catmap);
142 return -ENOMEM; 127 return -ENOMEM;
143} 128}
144 129
@@ -153,58 +138,44 @@ netlbl_export_failure:
153 * 138 *
154 */ 139 */
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_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_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/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h
index 712c8a7b8e8b..9637b8c71085 100644
--- a/security/selinux/ss/ebitmap.h
+++ b/security/selinux/ss/ebitmap.h
@@ -132,17 +132,17 @@ int ebitmap_write(struct ebitmap *e, void *fp);
132 132
133#ifdef CONFIG_NETLABEL 133#ifdef CONFIG_NETLABEL
134int ebitmap_netlbl_export(struct ebitmap *ebmap, 134int ebitmap_netlbl_export(struct ebitmap *ebmap,
135 struct netlbl_lsm_secattr_catmap **catmap); 135 struct netlbl_lsm_catmap **catmap);
136int ebitmap_netlbl_import(struct ebitmap *ebmap, 136int ebitmap_netlbl_import(struct ebitmap *ebmap,
137 struct netlbl_lsm_secattr_catmap *catmap); 137 struct netlbl_lsm_catmap *catmap);
138#else 138#else
139static inline int ebitmap_netlbl_export(struct ebitmap *ebmap, 139static inline int ebitmap_netlbl_export(struct ebitmap *ebmap,
140 struct netlbl_lsm_secattr_catmap **catmap) 140 struct netlbl_lsm_catmap **catmap)
141{ 141{
142 return -ENOMEM; 142 return -ENOMEM;
143} 143}
144static inline int ebitmap_netlbl_import(struct ebitmap *ebmap, 144static inline int ebitmap_netlbl_import(struct ebitmap *ebmap,
145 struct netlbl_lsm_secattr_catmap *catmap) 145 struct netlbl_lsm_catmap *catmap)
146{ 146{
147 return -ENOMEM; 147 return -ENOMEM;
148} 148}
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index c062e9467b62..f97d0842e621 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -457,19 +457,16 @@ int smk_netlbl_mls(int level, char *catset, struct netlbl_lsm_secattr *sap,
457 457
458 sap->flags |= NETLBL_SECATTR_MLS_CAT; 458 sap->flags |= NETLBL_SECATTR_MLS_CAT;
459 sap->attr.mls.lvl = level; 459 sap->attr.mls.lvl = level;
460 sap->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC); 460 sap->attr.mls.cat = NULL;
461 if (!sap->attr.mls.cat)
462 return -ENOMEM;
463 sap->attr.mls.cat->startbit = 0;
464 461
465 for (cat = 1, cp = catset, byte = 0; byte < len; cp++, byte++) 462 for (cat = 1, cp = catset, byte = 0; byte < len; cp++, byte++)
466 for (m = 0x80; m != 0; m >>= 1, cat++) { 463 for (m = 0x80; m != 0; m >>= 1, cat++) {
467 if ((m & *cp) == 0) 464 if ((m & *cp) == 0)
468 continue; 465 continue;
469 rc = netlbl_secattr_catmap_setbit(sap->attr.mls.cat, 466 rc = netlbl_catmap_setbit(&sap->attr.mls.cat,
470 cat, GFP_ATOMIC); 467 cat, GFP_ATOMIC);
471 if (rc < 0) { 468 if (rc < 0) {
472 netlbl_secattr_catmap_free(sap->attr.mls.cat); 469 netlbl_catmap_free(sap->attr.mls.cat);
473 return rc; 470 return rc;
474 } 471 }
475 } 472 }
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index f2c30801ce41..e6ab307ce86e 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -3209,9 +3209,9 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
3209 break; 3209 break;
3210 } 3210 }
3211 for (acat = -1, kcat = -1; acat == kcat; ) { 3211 for (acat = -1, kcat = -1; acat == kcat; ) {
3212 acat = netlbl_secattr_catmap_walk( 3212 acat = netlbl_catmap_walk(sap->attr.mls.cat,
3213 sap->attr.mls.cat, acat + 1); 3213 acat + 1);
3214 kcat = netlbl_secattr_catmap_walk( 3214 kcat = netlbl_catmap_walk(
3215 skp->smk_netlabel.attr.mls.cat, 3215 skp->smk_netlabel.attr.mls.cat,
3216 kcat + 1); 3216 kcat + 1);
3217 if (acat < 0 || kcat < 0) 3217 if (acat < 0 || kcat < 0)
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 32b248820840..3c720ff10591 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -787,7 +787,7 @@ static int cipso_seq_show(struct seq_file *s, void *v)
787 struct list_head *list = v; 787 struct list_head *list = v;
788 struct smack_known *skp = 788 struct smack_known *skp =
789 list_entry(list, struct smack_known, list); 789 list_entry(list, struct smack_known, list);
790 struct netlbl_lsm_secattr_catmap *cmp = skp->smk_netlabel.attr.mls.cat; 790 struct netlbl_lsm_catmap *cmp = skp->smk_netlabel.attr.mls.cat;
791 char sep = '/'; 791 char sep = '/';
792 int i; 792 int i;
793 793
@@ -804,8 +804,8 @@ static int cipso_seq_show(struct seq_file *s, void *v)
804 804
805 seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl); 805 seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl);
806 806
807 for (i = netlbl_secattr_catmap_walk(cmp, 0); i >= 0; 807 for (i = netlbl_catmap_walk(cmp, 0); i >= 0;
808 i = netlbl_secattr_catmap_walk(cmp, i + 1)) { 808 i = netlbl_catmap_walk(cmp, i + 1)) {
809 seq_printf(s, "%c%d", sep, i); 809 seq_printf(s, "%c%d", sep, i);
810 sep = ','; 810 sep = ',';
811 } 811 }
@@ -926,7 +926,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
926 926
927 rc = smk_netlbl_mls(maplevel, mapcatset, &ncats, SMK_CIPSOLEN); 927 rc = smk_netlbl_mls(maplevel, mapcatset, &ncats, SMK_CIPSOLEN);
928 if (rc >= 0) { 928 if (rc >= 0) {
929 netlbl_secattr_catmap_free(skp->smk_netlabel.attr.mls.cat); 929 netlbl_catmap_free(skp->smk_netlabel.attr.mls.cat);
930 skp->smk_netlabel.attr.mls.cat = ncats.attr.mls.cat; 930 skp->smk_netlabel.attr.mls.cat = ncats.attr.mls.cat;
931 skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl; 931 skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl;
932 rc = count; 932 rc = count;
@@ -976,14 +976,14 @@ static int cipso2_seq_show(struct seq_file *s, void *v)
976 struct list_head *list = v; 976 struct list_head *list = v;
977 struct smack_known *skp = 977 struct smack_known *skp =
978 list_entry(list, struct smack_known, list); 978 list_entry(list, struct smack_known, list);
979 struct netlbl_lsm_secattr_catmap *cmp = skp->smk_netlabel.attr.mls.cat; 979 struct netlbl_lsm_catmap *cmp = skp->smk_netlabel.attr.mls.cat;
980 char sep = '/'; 980 char sep = '/';
981 int i; 981 int i;
982 982
983 seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl); 983 seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl);
984 984
985 for (i = netlbl_secattr_catmap_walk(cmp, 0); i >= 0; 985 for (i = netlbl_catmap_walk(cmp, 0); i >= 0;
986 i = netlbl_secattr_catmap_walk(cmp, i + 1)) { 986 i = netlbl_catmap_walk(cmp, i + 1)) {
987 seq_printf(s, "%c%d", sep, i); 987 seq_printf(s, "%c%d", sep, i);
988 sep = ','; 988 sep = ',';
989 } 989 }