ebitmap.c (0bd2af46839ad6262d25714a6ec0365db9d6b98f) | ebitmap.c (02752760359db6b00a3ffb1acfc13ef8d9eb1e3f) |
---|---|
1/* 2 * Implementation of the extensible bitmap type. 3 * 4 * Author : Stephen Smalley, <sds@epoch.ncsc.mil> 5 */ 6/* 7 * Updated: Hewlett-Packard <paul.moore@hp.com> 8 * | 1/* 2 * Implementation of the extensible bitmap type. 3 * 4 * Author : Stephen Smalley, <sds@epoch.ncsc.mil> 5 */ 6/* 7 * Updated: Hewlett-Packard <paul.moore@hp.com> 8 * |
9 * Added ebitmap_export() and ebitmap_import() | 9 * Added support to import/export the NetLabel category bitmap |
10 * 11 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 12 */ 13 14#include <linux/kernel.h> 15#include <linux/slab.h> 16#include <linux/errno.h> | 10 * 11 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 12 */ 13 14#include <linux/kernel.h> 15#include <linux/slab.h> 16#include <linux/errno.h> |
17#include <net/netlabel.h> |
|
17#include "ebitmap.h" 18#include "policydb.h" 19 20int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2) 21{ 22 struct ebitmap_node *n1, *n2; 23 24 if (e1->highbit != e2->highbit) --- 37 unchanged lines hidden (view full) --- 62 prev = new; 63 n = n->next; 64 } 65 66 dst->highbit = src->highbit; 67 return 0; 68} 69 | 18#include "ebitmap.h" 19#include "policydb.h" 20 21int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2) 22{ 23 struct ebitmap_node *n1, *n2; 24 25 if (e1->highbit != e2->highbit) --- 37 unchanged lines hidden (view full) --- 63 prev = new; 64 n = n->next; 65 } 66 67 dst->highbit = src->highbit; 68 return 0; 69} 70 |
71#ifdef CONFIG_NETLABEL |
|
70/** | 72/** |
71 * ebitmap_export - Export an ebitmap to a unsigned char bitmap string 72 * @src: the ebitmap to export 73 * @dst: the resulting bitmap string 74 * @dst_len: length of dst in bytes | 73 * ebitmap_netlbl_export - Export an ebitmap into a NetLabel category bitmap 74 * @ebmap: the ebitmap to export 75 * @catmap: the NetLabel category bitmap |
75 * 76 * Description: | 76 * 77 * Description: |
77 * Allocate a buffer at least src->highbit bits long and export the extensible 78 * bitmap into the buffer. The bitmap string will be in little endian format, 79 * i.e. LSB first. The value returned in dst_len may not the true size of the 80 * buffer as the length of the buffer is rounded up to a multiple of MAPTYPE. 81 * The caller must free the buffer when finished. Returns zero on success, 82 * negative values on failure. | 78 * Export a SELinux extensibile bitmap into a NetLabel category bitmap. 79 * Returns zero on success, negative values on error. |
83 * 84 */ | 80 * 81 */ |
85int ebitmap_export(const struct ebitmap *src, 86 unsigned char **dst, 87 size_t *dst_len) | 82int ebitmap_netlbl_export(struct ebitmap *ebmap, 83 struct netlbl_lsm_secattr_catmap **catmap) |
88{ | 84{ |
89 size_t bitmap_len; 90 unsigned char *bitmap; 91 struct ebitmap_node *iter_node; 92 MAPTYPE node_val; 93 size_t bitmap_byte; 94 unsigned char bitmask; | 85 struct ebitmap_node *e_iter = ebmap->node; 86 struct netlbl_lsm_secattr_catmap *c_iter; 87 u32 cmap_idx; |
95 | 88 |
96 if (src->highbit == 0) { 97 *dst = NULL; 98 *dst_len = 0; | 89 /* This function is a much simpler because SELinux's MAPTYPE happens 90 * to be the same as NetLabel's NETLBL_CATMAP_MAPTYPE, if MAPTYPE is 91 * changed from a u64 this function will most likely need to be changed 92 * as well. It's not ideal but I think the tradeoff in terms of 93 * neatness and speed is worth it. */ 94 95 if (e_iter == NULL) { 96 *catmap = NULL; |
99 return 0; 100 } 101 | 97 return 0; 98 } 99 |
102 bitmap_len = src->highbit / 8; 103 if (src->highbit % 7) 104 bitmap_len += 1; 105 106 bitmap = kzalloc((bitmap_len & ~(sizeof(MAPTYPE) - 1)) + 107 sizeof(MAPTYPE), 108 GFP_ATOMIC); 109 if (bitmap == NULL) | 100 c_iter = netlbl_secattr_catmap_alloc(GFP_ATOMIC); 101 if (c_iter == NULL) |
110 return -ENOMEM; | 102 return -ENOMEM; |
103 *catmap = c_iter; 104 c_iter->startbit = e_iter->startbit & ~(NETLBL_CATMAP_SIZE - 1); |
|
111 | 105 |
112 iter_node = src->node; 113 do { 114 bitmap_byte = iter_node->startbit / 8; 115 bitmask = 0x80; 116 node_val = iter_node->map; 117 do { 118 if (bitmask == 0) { 119 bitmap_byte++; 120 bitmask = 0x80; 121 } 122 if (node_val & (MAPTYPE)0x01) 123 bitmap[bitmap_byte] |= bitmask; 124 node_val >>= 1; 125 bitmask >>= 1; 126 } while (node_val > 0); 127 iter_node = iter_node->next; 128 } while (iter_node); | 106 while (e_iter != NULL) { 107 if (e_iter->startbit >= 108 (c_iter->startbit + NETLBL_CATMAP_SIZE)) { 109 c_iter->next = netlbl_secattr_catmap_alloc(GFP_ATOMIC); 110 if (c_iter->next == NULL) 111 goto netlbl_export_failure; 112 c_iter = c_iter->next; 113 c_iter->startbit = e_iter->startbit & 114 ~(NETLBL_CATMAP_SIZE - 1); 115 } 116 cmap_idx = (e_iter->startbit - c_iter->startbit) / 117 NETLBL_CATMAP_MAPSIZE; 118 c_iter->bitmap[cmap_idx] = e_iter->map; 119 e_iter = e_iter->next; 120 } |
129 | 121 |
130 *dst = bitmap; 131 *dst_len = bitmap_len; | |
132 return 0; | 122 return 0; |
123 124netlbl_export_failure: 125 netlbl_secattr_catmap_free(*catmap); 126 return -ENOMEM; |
|
133} 134 135/** | 127} 128 129/** |
136 * ebitmap_import - Import an unsigned char bitmap string into an ebitmap 137 * @src: the bitmap string 138 * @src_len: the bitmap length in bytes 139 * @dst: the empty ebitmap | 130 * ebitmap_netlbl_import - Import a NetLabel category bitmap into an ebitmap 131 * @ebmap: the ebitmap to export 132 * @catmap: the NetLabel category bitmap |
140 * 141 * Description: | 133 * 134 * Description: |
142 * This function takes a little endian bitmap string in src and imports it into 143 * the ebitmap pointed to by dst. Returns zero on success, negative values on 144 * failure. | 135 * Import a NetLabel category bitmap into a SELinux extensibile bitmap. 136 * Returns zero on success, negative values on error. |
145 * 146 */ | 137 * 138 */ |
147int ebitmap_import(const unsigned char *src, 148 size_t src_len, 149 struct ebitmap *dst) | 139int ebitmap_netlbl_import(struct ebitmap *ebmap, 140 struct netlbl_lsm_secattr_catmap *catmap) |
150{ | 141{ |
151 size_t src_off = 0; 152 size_t node_limit; 153 struct ebitmap_node *node_new; 154 struct ebitmap_node *node_last = NULL; 155 u32 i_byte; 156 u32 i_bit; 157 unsigned char src_byte; | 142 struct ebitmap_node *e_iter = NULL; 143 struct ebitmap_node *emap_prev = NULL; 144 struct netlbl_lsm_secattr_catmap *c_iter = catmap; 145 u32 c_idx; |
158 | 146 |
159 while (src_off < src_len) { 160 if (src_len - src_off >= sizeof(MAPTYPE)) { 161 if (*(MAPTYPE *)&src[src_off] == 0) { 162 src_off += sizeof(MAPTYPE); | 147 /* This function is a much simpler because SELinux's MAPTYPE happens 148 * to be the same as NetLabel's NETLBL_CATMAP_MAPTYPE, if MAPTYPE is 149 * changed from a u64 this function will most likely need to be changed 150 * as well. It's not ideal but I think the tradeoff in terms of 151 * neatness and speed is worth it. */ 152 153 do { 154 for (c_idx = 0; c_idx < NETLBL_CATMAP_MAPCNT; c_idx++) { 155 if (c_iter->bitmap[c_idx] == 0) |
163 continue; | 156 continue; |
164 } 165 node_limit = sizeof(MAPTYPE); 166 } else { 167 for (src_byte = 0, i_byte = src_off; 168 i_byte < src_len && src_byte == 0; 169 i_byte++) 170 src_byte |= src[i_byte]; 171 if (src_byte == 0) 172 break; 173 node_limit = src_len - src_off; 174 } | |
175 | 157 |
176 node_new = kzalloc(sizeof(*node_new), GFP_ATOMIC); 177 if (unlikely(node_new == NULL)) { 178 ebitmap_destroy(dst); 179 return -ENOMEM; 180 } 181 node_new->startbit = src_off * 8; 182 for (i_byte = 0; i_byte < node_limit; i_byte++) { 183 src_byte = src[src_off++]; 184 for (i_bit = i_byte * 8; src_byte != 0; i_bit++) { 185 if (src_byte & 0x80) 186 node_new->map |= MAPBIT << i_bit; 187 src_byte <<= 1; 188 } 189 } | 158 e_iter = kzalloc(sizeof(*e_iter), GFP_ATOMIC); 159 if (e_iter == NULL) 160 goto netlbl_import_failure; 161 if (emap_prev == NULL) 162 ebmap->node = e_iter; 163 else 164 emap_prev->next = e_iter; 165 emap_prev = e_iter; |
190 | 166 |
191 if (node_last != NULL) 192 node_last->next = node_new; 193 else 194 dst->node = node_new; 195 node_last = node_new; 196 } 197 198 if (likely(node_last != NULL)) 199 dst->highbit = node_last->startbit + MAPSIZE; | 167 e_iter->startbit = c_iter->startbit + 168 NETLBL_CATMAP_MAPSIZE * c_idx; 169 e_iter->map = c_iter->bitmap[c_idx]; 170 } 171 c_iter = c_iter->next; 172 } while (c_iter != NULL); 173 if (e_iter != NULL) 174 ebmap->highbit = e_iter->startbit + MAPSIZE; |
200 else | 175 else |
201 ebitmap_init(dst); | 176 ebitmap_destroy(ebmap); |
202 203 return 0; | 177 178 return 0; |
179 180netlbl_import_failure: 181 ebitmap_destroy(ebmap); 182 return -ENOMEM; |
|
204} | 183} |
184#endif /* CONFIG_NETLABEL */ |
|
205 206int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2) 207{ 208 struct ebitmap_node *n1, *n2; 209 210 if (e1->highbit < e2->highbit) 211 return 0; 212 --- 223 unchanged lines hidden --- | 185 186int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2) 187{ 188 struct ebitmap_node *n1, *n2; 189 190 if (e1->highbit < e2->highbit) 191 return 0; 192 --- 223 unchanged lines hidden --- |