libsmack: fix parsing of CIPSO settings 33/32633/1
authorRafal Krypa <r.krypa@samsung.com>
Sat, 20 Dec 2014 01:31:05 +0000 (01:31 +0000)
committerRafal Krypa <r.krypa@samsung.com>
Sat, 20 Dec 2014 01:31:54 +0000 (01:31 +0000)
Adjust CIPSO parsing to expected kernel format:
- maximum number of categories is 184
- each category value must be between 1 and 184

To decrease size of struct cipso_mapping, categories are now stored in a
bit array. Thanks to this, category bitmap occupies 96 bits instead of 736.

Change-Id: I38b8fa5bd0830abc59de9dc3ebf208e18a82bbeb
Signed-off-by: Rafal Krypa <r.krypa@samsung.com>
libsmack/libsmack.c

index 269055d..48cd4e0 100644 (file)
 #define LEVEL_MAX 255
 #define NUM_LEN 4
 #define BUF_SIZE 512
-#define CAT_MAX_COUNT 240
-#define CAT_MAX_VALUE 63
+#define CAT_MAX_COUNT 184
 #define CIPSO_POS(i)   (SMACK_LABEL_LEN + 1 + NUM_LEN + NUM_LEN + i * NUM_LEN)
 #define CIPSO_MAX_SIZE CIPSO_POS(CAT_MAX_COUNT)
 #define CIPSO_NUM_LEN_STR "%-4d"
 
+#define BITMASK(b)    (1 << ((b) % 8))
+#define BITSLOT(b)    ((b) / 8)
+#define BITSET(a, b)  ((a)[BITSLOT(b)] |= BITMASK(b))
+#define BITTEST(a, b) ((a)[BITSLOT(b)] & BITMASK(b))
+#define BITNSLOTS(nb) ((nb + 7) / 8)
+
 #define ACCESS_TYPE_R 0x01
 #define ACCESS_TYPE_W 0x02
 #define ACCESS_TYPE_X 0x04
@@ -109,7 +114,7 @@ struct smack_accesses {
 
 struct cipso_mapping {
        char label[SMACK_LABEL_LEN + 1];
-       int cats[CAT_MAX_VALUE];
+       uint8_t cats[BITNSLOTS(CAT_MAX_COUNT)];
        int ncats;
        int level;
        struct cipso_mapping *next;
@@ -470,9 +475,11 @@ int smack_cipso_apply(struct smack_cipso *cipso)
                sprintf(&buf[offset], CIPSO_NUM_LEN_STR, m->ncats);
                offset += NUM_LEN;
 
-               for (i = 0; i < m->ncats; i++){
-                       sprintf(&buf[offset], CIPSO_NUM_LEN_STR, m->cats[i]);
-                       offset += NUM_LEN;
+               for (i = 0; i < CAT_MAX_COUNT; i++) {
+                       if (BITTEST(m->cats, i)) {
+                               sprintf(&buf[offset], CIPSO_NUM_LEN_STR, i + 1);
+                               offset += NUM_LEN;
+                       }
                }
 
                if (write(fd, buf, offset) < 0) {
@@ -539,16 +546,17 @@ int smack_cipso_add_from_file(struct smack_cipso *cipso, int fd)
                        if (errno)
                                goto err_out;
 
-                       if (val < 0 || val > CAT_MAX_VALUE)
+                       if (val <= 0 || val > CAT_MAX_COUNT)
                                goto err_out;
 
-                       mapping->cats[i] = val;
+                       if (!BITTEST(mapping->cats, val - 1)) {
+                               BITSET(mapping->cats, val - 1);
+                               ++(mapping->ncats);
+                       }
 
                        cat = strtok_r(NULL, " \t\n", &ptr);
                }
 
-               mapping->ncats = i;
-
                if (cipso->first == NULL) {
                        cipso->first = cipso->last = mapping;
                } else {