Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Implementation of the extensible bitmap type.
0004  *
0005  * Author : Stephen Smalley, <sds@tycho.nsa.gov>
0006  */
0007 /*
0008  * Updated: Hewlett-Packard <paul@paul-moore.com>
0009  *
0010  *      Added support to import/export the NetLabel category bitmap
0011  *
0012  * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
0013  */
0014 /*
0015  * Updated: KaiGai Kohei <kaigai@ak.jp.nec.com>
0016  *      Applied standard bit operations to improve bitmap scanning.
0017  */
0018 
0019 #include <linux/kernel.h>
0020 #include <linux/slab.h>
0021 #include <linux/errno.h>
0022 #include <linux/jhash.h>
0023 #include <net/netlabel.h>
0024 #include "ebitmap.h"
0025 #include "policydb.h"
0026 
0027 #define BITS_PER_U64    (sizeof(u64) * 8)
0028 
0029 static struct kmem_cache *ebitmap_node_cachep __ro_after_init;
0030 
0031 int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2)
0032 {
0033     struct ebitmap_node *n1, *n2;
0034 
0035     if (e1->highbit != e2->highbit)
0036         return 0;
0037 
0038     n1 = e1->node;
0039     n2 = e2->node;
0040     while (n1 && n2 &&
0041            (n1->startbit == n2->startbit) &&
0042            !memcmp(n1->maps, n2->maps, EBITMAP_SIZE / 8)) {
0043         n1 = n1->next;
0044         n2 = n2->next;
0045     }
0046 
0047     if (n1 || n2)
0048         return 0;
0049 
0050     return 1;
0051 }
0052 
0053 int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src)
0054 {
0055     struct ebitmap_node *n, *new, *prev;
0056 
0057     ebitmap_init(dst);
0058     n = src->node;
0059     prev = NULL;
0060     while (n) {
0061         new = kmem_cache_zalloc(ebitmap_node_cachep, GFP_ATOMIC);
0062         if (!new) {
0063             ebitmap_destroy(dst);
0064             return -ENOMEM;
0065         }
0066         new->startbit = n->startbit;
0067         memcpy(new->maps, n->maps, EBITMAP_SIZE / 8);
0068         new->next = NULL;
0069         if (prev)
0070             prev->next = new;
0071         else
0072             dst->node = new;
0073         prev = new;
0074         n = n->next;
0075     }
0076 
0077     dst->highbit = src->highbit;
0078     return 0;
0079 }
0080 
0081 int ebitmap_and(struct ebitmap *dst, struct ebitmap *e1, struct ebitmap *e2)
0082 {
0083     struct ebitmap_node *n;
0084     int bit, rc;
0085 
0086     ebitmap_init(dst);
0087 
0088     ebitmap_for_each_positive_bit(e1, n, bit) {
0089         if (ebitmap_get_bit(e2, bit)) {
0090             rc = ebitmap_set_bit(dst, bit, 1);
0091             if (rc < 0)
0092                 return rc;
0093         }
0094     }
0095     return 0;
0096 }
0097 
0098 
0099 #ifdef CONFIG_NETLABEL
0100 /**
0101  * ebitmap_netlbl_export - Export an ebitmap into a NetLabel category bitmap
0102  * @ebmap: the ebitmap to export
0103  * @catmap: the NetLabel category bitmap
0104  *
0105  * Description:
0106  * Export a SELinux extensibile bitmap into a NetLabel category bitmap.
0107  * Returns zero on success, negative values on error.
0108  *
0109  */
0110 int ebitmap_netlbl_export(struct ebitmap *ebmap,
0111               struct netlbl_lsm_catmap **catmap)
0112 {
0113     struct ebitmap_node *e_iter = ebmap->node;
0114     unsigned long e_map;
0115     u32 offset;
0116     unsigned int iter;
0117     int rc;
0118 
0119     if (e_iter == NULL) {
0120         *catmap = NULL;
0121         return 0;
0122     }
0123 
0124     if (*catmap != NULL)
0125         netlbl_catmap_free(*catmap);
0126     *catmap = NULL;
0127 
0128     while (e_iter) {
0129         offset = e_iter->startbit;
0130         for (iter = 0; iter < EBITMAP_UNIT_NUMS; iter++) {
0131             e_map = e_iter->maps[iter];
0132             if (e_map != 0) {
0133                 rc = netlbl_catmap_setlong(catmap,
0134                                offset,
0135                                e_map,
0136                                GFP_ATOMIC);
0137                 if (rc != 0)
0138                     goto netlbl_export_failure;
0139             }
0140             offset += EBITMAP_UNIT_SIZE;
0141         }
0142         e_iter = e_iter->next;
0143     }
0144 
0145     return 0;
0146 
0147 netlbl_export_failure:
0148     netlbl_catmap_free(*catmap);
0149     return -ENOMEM;
0150 }
0151 
0152 /**
0153  * ebitmap_netlbl_import - Import a NetLabel category bitmap into an ebitmap
0154  * @ebmap: the ebitmap to import
0155  * @catmap: the NetLabel category bitmap
0156  *
0157  * Description:
0158  * Import a NetLabel category bitmap into a SELinux extensibile bitmap.
0159  * Returns zero on success, negative values on error.
0160  *
0161  */
0162 int ebitmap_netlbl_import(struct ebitmap *ebmap,
0163               struct netlbl_lsm_catmap *catmap)
0164 {
0165     int rc;
0166     struct ebitmap_node *e_iter = NULL;
0167     struct ebitmap_node *e_prev = NULL;
0168     u32 offset = 0, idx;
0169     unsigned long bitmap;
0170 
0171     for (;;) {
0172         rc = netlbl_catmap_getlong(catmap, &offset, &bitmap);
0173         if (rc < 0)
0174             goto netlbl_import_failure;
0175         if (offset == (u32)-1)
0176             return 0;
0177 
0178         /* don't waste ebitmap space if the netlabel bitmap is empty */
0179         if (bitmap == 0) {
0180             offset += EBITMAP_UNIT_SIZE;
0181             continue;
0182         }
0183 
0184         if (e_iter == NULL ||
0185             offset >= e_iter->startbit + EBITMAP_SIZE) {
0186             e_prev = e_iter;
0187             e_iter = kmem_cache_zalloc(ebitmap_node_cachep, GFP_ATOMIC);
0188             if (e_iter == NULL)
0189                 goto netlbl_import_failure;
0190             e_iter->startbit = offset - (offset % EBITMAP_SIZE);
0191             if (e_prev == NULL)
0192                 ebmap->node = e_iter;
0193             else
0194                 e_prev->next = e_iter;
0195             ebmap->highbit = e_iter->startbit + EBITMAP_SIZE;
0196         }
0197 
0198         /* offset will always be aligned to an unsigned long */
0199         idx = EBITMAP_NODE_INDEX(e_iter, offset);
0200         e_iter->maps[idx] = bitmap;
0201 
0202         /* next */
0203         offset += EBITMAP_UNIT_SIZE;
0204     }
0205 
0206     /* NOTE: we should never reach this return */
0207     return 0;
0208 
0209 netlbl_import_failure:
0210     ebitmap_destroy(ebmap);
0211     return -ENOMEM;
0212 }
0213 #endif /* CONFIG_NETLABEL */
0214 
0215 /*
0216  * Check to see if all the bits set in e2 are also set in e1. Optionally,
0217  * if last_e2bit is non-zero, the highest set bit in e2 cannot exceed
0218  * last_e2bit.
0219  */
0220 int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2, u32 last_e2bit)
0221 {
0222     struct ebitmap_node *n1, *n2;
0223     int i;
0224 
0225     if (e1->highbit < e2->highbit)
0226         return 0;
0227 
0228     n1 = e1->node;
0229     n2 = e2->node;
0230 
0231     while (n1 && n2 && (n1->startbit <= n2->startbit)) {
0232         if (n1->startbit < n2->startbit) {
0233             n1 = n1->next;
0234             continue;
0235         }
0236         for (i = EBITMAP_UNIT_NUMS - 1; (i >= 0) && !n2->maps[i]; )
0237             i--;    /* Skip trailing NULL map entries */
0238         if (last_e2bit && (i >= 0)) {
0239             u32 lastsetbit = n2->startbit + i * EBITMAP_UNIT_SIZE +
0240                      __fls(n2->maps[i]);
0241             if (lastsetbit > last_e2bit)
0242                 return 0;
0243         }
0244 
0245         while (i >= 0) {
0246             if ((n1->maps[i] & n2->maps[i]) != n2->maps[i])
0247                 return 0;
0248             i--;
0249         }
0250 
0251         n1 = n1->next;
0252         n2 = n2->next;
0253     }
0254 
0255     if (n2)
0256         return 0;
0257 
0258     return 1;
0259 }
0260 
0261 int ebitmap_get_bit(struct ebitmap *e, unsigned long bit)
0262 {
0263     struct ebitmap_node *n;
0264 
0265     if (e->highbit < bit)
0266         return 0;
0267 
0268     n = e->node;
0269     while (n && (n->startbit <= bit)) {
0270         if ((n->startbit + EBITMAP_SIZE) > bit)
0271             return ebitmap_node_get_bit(n, bit);
0272         n = n->next;
0273     }
0274 
0275     return 0;
0276 }
0277 
0278 int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value)
0279 {
0280     struct ebitmap_node *n, *prev, *new;
0281 
0282     prev = NULL;
0283     n = e->node;
0284     while (n && n->startbit <= bit) {
0285         if ((n->startbit + EBITMAP_SIZE) > bit) {
0286             if (value) {
0287                 ebitmap_node_set_bit(n, bit);
0288             } else {
0289                 unsigned int s;
0290 
0291                 ebitmap_node_clr_bit(n, bit);
0292 
0293                 s = find_first_bit(n->maps, EBITMAP_SIZE);
0294                 if (s < EBITMAP_SIZE)
0295                     return 0;
0296 
0297                 /* drop this node from the bitmap */
0298                 if (!n->next) {
0299                     /*
0300                      * this was the highest map
0301                      * within the bitmap
0302                      */
0303                     if (prev)
0304                         e->highbit = prev->startbit
0305                                  + EBITMAP_SIZE;
0306                     else
0307                         e->highbit = 0;
0308                 }
0309                 if (prev)
0310                     prev->next = n->next;
0311                 else
0312                     e->node = n->next;
0313                 kmem_cache_free(ebitmap_node_cachep, n);
0314             }
0315             return 0;
0316         }
0317         prev = n;
0318         n = n->next;
0319     }
0320 
0321     if (!value)
0322         return 0;
0323 
0324     new = kmem_cache_zalloc(ebitmap_node_cachep, GFP_ATOMIC);
0325     if (!new)
0326         return -ENOMEM;
0327 
0328     new->startbit = bit - (bit % EBITMAP_SIZE);
0329     ebitmap_node_set_bit(new, bit);
0330 
0331     if (!n)
0332         /* this node will be the highest map within the bitmap */
0333         e->highbit = new->startbit + EBITMAP_SIZE;
0334 
0335     if (prev) {
0336         new->next = prev->next;
0337         prev->next = new;
0338     } else {
0339         new->next = e->node;
0340         e->node = new;
0341     }
0342 
0343     return 0;
0344 }
0345 
0346 void ebitmap_destroy(struct ebitmap *e)
0347 {
0348     struct ebitmap_node *n, *temp;
0349 
0350     if (!e)
0351         return;
0352 
0353     n = e->node;
0354     while (n) {
0355         temp = n;
0356         n = n->next;
0357         kmem_cache_free(ebitmap_node_cachep, temp);
0358     }
0359 
0360     e->highbit = 0;
0361     e->node = NULL;
0362 }
0363 
0364 int ebitmap_read(struct ebitmap *e, void *fp)
0365 {
0366     struct ebitmap_node *n = NULL;
0367     u32 mapunit, count, startbit, index;
0368     __le32 ebitmap_start;
0369     u64 map;
0370     __le64 mapbits;
0371     __le32 buf[3];
0372     int rc, i;
0373 
0374     ebitmap_init(e);
0375 
0376     rc = next_entry(buf, fp, sizeof buf);
0377     if (rc < 0)
0378         goto out;
0379 
0380     mapunit = le32_to_cpu(buf[0]);
0381     e->highbit = le32_to_cpu(buf[1]);
0382     count = le32_to_cpu(buf[2]);
0383 
0384     if (mapunit != BITS_PER_U64) {
0385         pr_err("SELinux: ebitmap: map size %u does not "
0386                "match my size %zd (high bit was %d)\n",
0387                mapunit, BITS_PER_U64, e->highbit);
0388         goto bad;
0389     }
0390 
0391     /* round up e->highbit */
0392     e->highbit += EBITMAP_SIZE - 1;
0393     e->highbit -= (e->highbit % EBITMAP_SIZE);
0394 
0395     if (!e->highbit) {
0396         e->node = NULL;
0397         goto ok;
0398     }
0399 
0400     if (e->highbit && !count)
0401         goto bad;
0402 
0403     for (i = 0; i < count; i++) {
0404         rc = next_entry(&ebitmap_start, fp, sizeof(u32));
0405         if (rc < 0) {
0406             pr_err("SELinux: ebitmap: truncated map\n");
0407             goto bad;
0408         }
0409         startbit = le32_to_cpu(ebitmap_start);
0410 
0411         if (startbit & (mapunit - 1)) {
0412             pr_err("SELinux: ebitmap start bit (%d) is "
0413                    "not a multiple of the map unit size (%u)\n",
0414                    startbit, mapunit);
0415             goto bad;
0416         }
0417         if (startbit > e->highbit - mapunit) {
0418             pr_err("SELinux: ebitmap start bit (%d) is "
0419                    "beyond the end of the bitmap (%u)\n",
0420                    startbit, (e->highbit - mapunit));
0421             goto bad;
0422         }
0423 
0424         if (!n || startbit >= n->startbit + EBITMAP_SIZE) {
0425             struct ebitmap_node *tmp;
0426             tmp = kmem_cache_zalloc(ebitmap_node_cachep, GFP_KERNEL);
0427             if (!tmp) {
0428                 pr_err("SELinux: ebitmap: out of memory\n");
0429                 rc = -ENOMEM;
0430                 goto bad;
0431             }
0432             /* round down */
0433             tmp->startbit = startbit - (startbit % EBITMAP_SIZE);
0434             if (n)
0435                 n->next = tmp;
0436             else
0437                 e->node = tmp;
0438             n = tmp;
0439         } else if (startbit <= n->startbit) {
0440             pr_err("SELinux: ebitmap: start bit %d"
0441                    " comes after start bit %d\n",
0442                    startbit, n->startbit);
0443             goto bad;
0444         }
0445 
0446         rc = next_entry(&mapbits, fp, sizeof(u64));
0447         if (rc < 0) {
0448             pr_err("SELinux: ebitmap: truncated map\n");
0449             goto bad;
0450         }
0451         map = le64_to_cpu(mapbits);
0452 
0453         index = (startbit - n->startbit) / EBITMAP_UNIT_SIZE;
0454         while (map) {
0455             n->maps[index++] = map & (-1UL);
0456             map = EBITMAP_SHIFT_UNIT_SIZE(map);
0457         }
0458     }
0459 ok:
0460     rc = 0;
0461 out:
0462     return rc;
0463 bad:
0464     if (!rc)
0465         rc = -EINVAL;
0466     ebitmap_destroy(e);
0467     goto out;
0468 }
0469 
0470 int ebitmap_write(struct ebitmap *e, void *fp)
0471 {
0472     struct ebitmap_node *n;
0473     u32 count;
0474     __le32 buf[3];
0475     u64 map;
0476     int bit, last_bit, last_startbit, rc;
0477 
0478     buf[0] = cpu_to_le32(BITS_PER_U64);
0479 
0480     count = 0;
0481     last_bit = 0;
0482     last_startbit = -1;
0483     ebitmap_for_each_positive_bit(e, n, bit) {
0484         if (rounddown(bit, (int)BITS_PER_U64) > last_startbit) {
0485             count++;
0486             last_startbit = rounddown(bit, BITS_PER_U64);
0487         }
0488         last_bit = roundup(bit + 1, BITS_PER_U64);
0489     }
0490     buf[1] = cpu_to_le32(last_bit);
0491     buf[2] = cpu_to_le32(count);
0492 
0493     rc = put_entry(buf, sizeof(u32), 3, fp);
0494     if (rc)
0495         return rc;
0496 
0497     map = 0;
0498     last_startbit = INT_MIN;
0499     ebitmap_for_each_positive_bit(e, n, bit) {
0500         if (rounddown(bit, (int)BITS_PER_U64) > last_startbit) {
0501             __le64 buf64[1];
0502 
0503             /* this is the very first bit */
0504             if (!map) {
0505                 last_startbit = rounddown(bit, BITS_PER_U64);
0506                 map = (u64)1 << (bit - last_startbit);
0507                 continue;
0508             }
0509 
0510             /* write the last node */
0511             buf[0] = cpu_to_le32(last_startbit);
0512             rc = put_entry(buf, sizeof(u32), 1, fp);
0513             if (rc)
0514                 return rc;
0515 
0516             buf64[0] = cpu_to_le64(map);
0517             rc = put_entry(buf64, sizeof(u64), 1, fp);
0518             if (rc)
0519                 return rc;
0520 
0521             /* set up for the next node */
0522             map = 0;
0523             last_startbit = rounddown(bit, BITS_PER_U64);
0524         }
0525         map |= (u64)1 << (bit - last_startbit);
0526     }
0527     /* write the last node */
0528     if (map) {
0529         __le64 buf64[1];
0530 
0531         /* write the last node */
0532         buf[0] = cpu_to_le32(last_startbit);
0533         rc = put_entry(buf, sizeof(u32), 1, fp);
0534         if (rc)
0535             return rc;
0536 
0537         buf64[0] = cpu_to_le64(map);
0538         rc = put_entry(buf64, sizeof(u64), 1, fp);
0539         if (rc)
0540             return rc;
0541     }
0542     return 0;
0543 }
0544 
0545 u32 ebitmap_hash(const struct ebitmap *e, u32 hash)
0546 {
0547     struct ebitmap_node *node;
0548 
0549     /* need to change hash even if ebitmap is empty */
0550     hash = jhash_1word(e->highbit, hash);
0551     for (node = e->node; node; node = node->next) {
0552         hash = jhash_1word(node->startbit, hash);
0553         hash = jhash(node->maps, sizeof(node->maps), hash);
0554     }
0555     return hash;
0556 }
0557 
0558 void __init ebitmap_cache_init(void)
0559 {
0560     ebitmap_node_cachep = kmem_cache_create("ebitmap_node",
0561                             sizeof(struct ebitmap_node),
0562                             0, SLAB_PANIC, NULL);
0563 }