X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=security%2Fselinux%2Fss%2Febitmap.c;h=ce492a6b38ed64110e2f8b0db68510df12281782;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=d8ce9cc0b9f15042c50bc7abf2b3bea9202031bb;hpb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;p=linux-2.6.git diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c index d8ce9cc0b..ce492a6b3 100644 --- a/security/selinux/ss/ebitmap.c +++ b/security/selinux/ss/ebitmap.c @@ -3,9 +3,18 @@ * * Author : Stephen Smalley, */ +/* + * Updated: Hewlett-Packard + * + * Added support to import/export the NetLabel category bitmap + * + * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 + */ + #include #include #include +#include #include "ebitmap.h" #include "policydb.h" @@ -39,12 +48,11 @@ int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src) n = src->node; prev = NULL; while (n) { - new = kmalloc(sizeof(*new), GFP_ATOMIC); + new = kzalloc(sizeof(*new), GFP_ATOMIC); if (!new) { ebitmap_destroy(dst); return -ENOMEM; } - memset(new, 0, sizeof(*new)); new->startbit = n->startbit; new->map = n->map; new->next = NULL; @@ -60,6 +68,121 @@ int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src) return 0; } +#ifdef CONFIG_NETLABEL +/** + * ebitmap_netlbl_export - Export an ebitmap into a NetLabel category bitmap + * @ebmap: the ebitmap to export + * @catmap: the NetLabel category bitmap + * + * Description: + * Export a SELinux extensibile bitmap into a NetLabel category bitmap. + * Returns zero on success, negative values on error. + * + */ +int ebitmap_netlbl_export(struct ebitmap *ebmap, + struct netlbl_lsm_secattr_catmap **catmap) +{ + struct ebitmap_node *e_iter = ebmap->node; + struct netlbl_lsm_secattr_catmap *c_iter; + u32 cmap_idx; + + /* This function is a much simpler because SELinux's MAPTYPE happens + * to be the same as NetLabel's NETLBL_CATMAP_MAPTYPE, if MAPTYPE is + * changed from a u64 this function will most likely need to be changed + * as well. It's not ideal but I think the tradeoff in terms of + * neatness and speed is worth it. */ + + if (e_iter == NULL) { + *catmap = NULL; + return 0; + } + + c_iter = netlbl_secattr_catmap_alloc(GFP_ATOMIC); + if (c_iter == NULL) + return -ENOMEM; + *catmap = c_iter; + c_iter->startbit = e_iter->startbit & ~(NETLBL_CATMAP_SIZE - 1); + + while (e_iter != NULL) { + if (e_iter->startbit >= + (c_iter->startbit + NETLBL_CATMAP_SIZE)) { + c_iter->next = netlbl_secattr_catmap_alloc(GFP_ATOMIC); + if (c_iter->next == NULL) + goto netlbl_export_failure; + c_iter = c_iter->next; + c_iter->startbit = e_iter->startbit & + ~(NETLBL_CATMAP_SIZE - 1); + } + cmap_idx = (e_iter->startbit - c_iter->startbit) / + NETLBL_CATMAP_MAPSIZE; + c_iter->bitmap[cmap_idx] = e_iter->map; + e_iter = e_iter->next; + } + + return 0; + +netlbl_export_failure: + netlbl_secattr_catmap_free(*catmap); + return -ENOMEM; +} + +/** + * ebitmap_netlbl_import - Import a NetLabel category bitmap into an ebitmap + * @ebmap: the ebitmap to export + * @catmap: the NetLabel category bitmap + * + * Description: + * Import a NetLabel category bitmap into a SELinux extensibile bitmap. + * Returns zero on success, negative values on error. + * + */ +int ebitmap_netlbl_import(struct ebitmap *ebmap, + struct netlbl_lsm_secattr_catmap *catmap) +{ + struct ebitmap_node *e_iter = NULL; + struct ebitmap_node *emap_prev = NULL; + struct netlbl_lsm_secattr_catmap *c_iter = catmap; + u32 c_idx; + + /* This function is a much simpler because SELinux's MAPTYPE happens + * to be the same as NetLabel's NETLBL_CATMAP_MAPTYPE, if MAPTYPE is + * changed from a u64 this function will most likely need to be changed + * as well. It's not ideal but I think the tradeoff in terms of + * neatness and speed is worth it. */ + + do { + for (c_idx = 0; c_idx < NETLBL_CATMAP_MAPCNT; c_idx++) { + if (c_iter->bitmap[c_idx] == 0) + continue; + + e_iter = kzalloc(sizeof(*e_iter), GFP_ATOMIC); + if (e_iter == NULL) + goto netlbl_import_failure; + if (emap_prev == NULL) + ebmap->node = e_iter; + else + emap_prev->next = e_iter; + emap_prev = e_iter; + + e_iter->startbit = c_iter->startbit + + NETLBL_CATMAP_MAPSIZE * c_idx; + e_iter->map = c_iter->bitmap[c_idx]; + } + c_iter = c_iter->next; + } while (c_iter != NULL); + if (e_iter != NULL) + ebmap->highbit = e_iter->startbit + MAPSIZE; + else + ebitmap_destroy(ebmap); + + return 0; + +netlbl_import_failure: + ebitmap_destroy(ebmap); + return -ENOMEM; +} +#endif /* CONFIG_NETLABEL */ + int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2) { struct ebitmap_node *n1, *n2; @@ -150,10 +273,9 @@ int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value) if (!value) return 0; - new = kmalloc(sizeof(*new), GFP_ATOMIC); + new = kzalloc(sizeof(*new), GFP_ATOMIC); if (!new) return -ENOMEM; - memset(new, 0, sizeof(*new)); new->startbit = bit & ~(MAPSIZE - 1); new->map = (MAPBIT << (bit - new->startbit)); @@ -196,8 +318,9 @@ int ebitmap_read(struct ebitmap *e, void *fp) { int rc; struct ebitmap_node *n, *l; - u32 buf[3], mapsize, count, i; - u64 map; + __le32 buf[3]; + u32 mapsize, count, i; + __le64 map; ebitmap_init(e); @@ -231,13 +354,12 @@ int ebitmap_read(struct ebitmap *e, void *fp) printk(KERN_ERR "security: ebitmap: truncated map\n"); goto bad; } - n = kmalloc(sizeof(*n), GFP_KERNEL); + n = kzalloc(sizeof(*n), GFP_KERNEL); if (!n) { printk(KERN_ERR "security: ebitmap: out of memory\n"); rc = -ENOMEM; goto bad; } - memset(n, 0, sizeof(*n)); n->startbit = le32_to_cpu(buf[0]);