diff options
author | Paul Moore <paul.moore@hp.com> | 2006-11-29 13:18:18 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-03 00:31:36 -0500 |
commit | 02752760359db6b00a3ffb1acfc13ef8d9eb1e3f (patch) | |
tree | 796cd65fd4cd732b295e61dac194efbf36b78842 /security | |
parent | ef91fd522ba3c88d9c68261c243567bc4c5a8f55 (diff) |
NetLabel: convert to an extensibile/sparse category bitmap
The original NetLabel category bitmap was a straight char bitmap which worked
fine for the initial release as it only supported 240 bits due to limitations
in the CIPSO restricted bitmap tag (tag type 0x01). This patch converts that
straight char bitmap into an extensibile/sparse bitmap in order to lay the
foundation for other CIPSO tag types and protocols.
This patch also has a nice side effect in that all of the security attributes
passed by NetLabel into the LSM are now in a format which is in the host's
native byte/bit ordering which makes the LSM specific code much simpler; look
at the changes in security/selinux/ss/ebitmap.c as an example.
Signed-off-by: Paul Moore <paul.moore@hp.com>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security')
-rw-r--r-- | security/selinux/ss/ebitmap.c | 198 | ||||
-rw-r--r-- | security/selinux/ss/ebitmap.h | 26 | ||||
-rw-r--r-- | security/selinux/ss/mls.c | 156 | ||||
-rw-r--r-- | security/selinux/ss/mls.h | 46 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 23 |
5 files changed, 199 insertions, 250 deletions
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c index d539346ab3a2..ce492a6b38ed 100644 --- a/security/selinux/ss/ebitmap.c +++ b/security/selinux/ss/ebitmap.c | |||
@@ -6,7 +6,7 @@ | |||
6 | /* | 6 | /* |
7 | * Updated: Hewlett-Packard <paul.moore@hp.com> | 7 | * Updated: Hewlett-Packard <paul.moore@hp.com> |
8 | * | 8 | * |
9 | * Added ebitmap_export() and ebitmap_import() | 9 | * Added support to import/export the NetLabel category bitmap |
10 | * | 10 | * |
11 | * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 | 11 | * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 |
12 | */ | 12 | */ |
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
17 | #include <net/netlabel.h> | ||
17 | #include "ebitmap.h" | 18 | #include "ebitmap.h" |
18 | #include "policydb.h" | 19 | #include "policydb.h" |
19 | 20 | ||
@@ -67,141 +68,120 @@ int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src) | |||
67 | return 0; | 68 | return 0; |
68 | } | 69 | } |
69 | 70 | ||
71 | #ifdef CONFIG_NETLABEL | ||
70 | /** | 72 | /** |
71 | * ebitmap_export - Export an ebitmap to a unsigned char bitmap string | 73 | * ebitmap_netlbl_export - Export an ebitmap into a NetLabel category bitmap |
72 | * @src: the ebitmap to export | 74 | * @ebmap: the ebitmap to export |
73 | * @dst: the resulting bitmap string | 75 | * @catmap: the NetLabel category bitmap |
74 | * @dst_len: length of dst in bytes | ||
75 | * | 76 | * |
76 | * Description: | 77 | * Description: |
77 | * Allocate a buffer at least src->highbit bits long and export the extensible | 78 | * Export a SELinux extensibile bitmap into a NetLabel category bitmap. |
78 | * bitmap into the buffer. The bitmap string will be in little endian format, | 79 | * Returns zero on success, negative values on error. |
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. | ||
83 | * | 80 | * |
84 | */ | 81 | */ |
85 | int ebitmap_export(const struct ebitmap *src, | 82 | int ebitmap_netlbl_export(struct ebitmap *ebmap, |
86 | unsigned char **dst, | 83 | struct netlbl_lsm_secattr_catmap **catmap) |
87 | size_t *dst_len) | ||
88 | { | 84 | { |
89 | size_t bitmap_len; | 85 | struct ebitmap_node *e_iter = ebmap->node; |
90 | unsigned char *bitmap; | 86 | struct netlbl_lsm_secattr_catmap *c_iter; |
91 | struct ebitmap_node *iter_node; | 87 | u32 cmap_idx; |
92 | MAPTYPE node_val; | 88 | |
93 | size_t bitmap_byte; | 89 | /* This function is a much simpler because SELinux's MAPTYPE happens |
94 | unsigned char bitmask; | 90 | * to be the same as NetLabel's NETLBL_CATMAP_MAPTYPE, if MAPTYPE is |
95 | 91 | * changed from a u64 this function will most likely need to be changed | |
96 | if (src->highbit == 0) { | 92 | * as well. It's not ideal but I think the tradeoff in terms of |
97 | *dst = NULL; | 93 | * neatness and speed is worth it. */ |
98 | *dst_len = 0; | 94 | |
95 | if (e_iter == NULL) { | ||
96 | *catmap = NULL; | ||
99 | return 0; | 97 | return 0; |
100 | } | 98 | } |
101 | 99 | ||
102 | bitmap_len = src->highbit / 8; | 100 | c_iter = netlbl_secattr_catmap_alloc(GFP_ATOMIC); |
103 | if (src->highbit % 7) | 101 | if (c_iter == NULL) |
104 | bitmap_len += 1; | ||
105 | |||
106 | bitmap = kzalloc((bitmap_len & ~(sizeof(MAPTYPE) - 1)) + | ||
107 | sizeof(MAPTYPE), | ||
108 | GFP_ATOMIC); | ||
109 | if (bitmap == NULL) | ||
110 | return -ENOMEM; | 102 | return -ENOMEM; |
103 | *catmap = c_iter; | ||
104 | c_iter->startbit = e_iter->startbit & ~(NETLBL_CATMAP_SIZE - 1); | ||
105 | |||
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 | } | ||
111 | 121 | ||
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); | ||
129 | |||
130 | *dst = bitmap; | ||
131 | *dst_len = bitmap_len; | ||
132 | return 0; | 122 | return 0; |
123 | |||
124 | netlbl_export_failure: | ||
125 | netlbl_secattr_catmap_free(*catmap); | ||
126 | return -ENOMEM; | ||
133 | } | 127 | } |
134 | 128 | ||
135 | /** | 129 | /** |
136 | * ebitmap_import - Import an unsigned char bitmap string into an ebitmap | 130 | * ebitmap_netlbl_import - Import a NetLabel category bitmap into an ebitmap |
137 | * @src: the bitmap string | 131 | * @ebmap: the ebitmap to export |
138 | * @src_len: the bitmap length in bytes | 132 | * @catmap: the NetLabel category bitmap |
139 | * @dst: the empty ebitmap | ||
140 | * | 133 | * |
141 | * Description: | 134 | * Description: |
142 | * This function takes a little endian bitmap string in src and imports it into | 135 | * Import a NetLabel category bitmap into a SELinux extensibile bitmap. |
143 | * the ebitmap pointed to by dst. Returns zero on success, negative values on | 136 | * Returns zero on success, negative values on error. |
144 | * failure. | ||
145 | * | 137 | * |
146 | */ | 138 | */ |
147 | int ebitmap_import(const unsigned char *src, | 139 | int ebitmap_netlbl_import(struct ebitmap *ebmap, |
148 | size_t src_len, | 140 | struct netlbl_lsm_secattr_catmap *catmap) |
149 | struct ebitmap *dst) | ||
150 | { | 141 | { |
151 | size_t src_off = 0; | 142 | struct ebitmap_node *e_iter = NULL; |
152 | size_t node_limit; | 143 | struct ebitmap_node *emap_prev = NULL; |
153 | struct ebitmap_node *node_new; | 144 | struct netlbl_lsm_secattr_catmap *c_iter = catmap; |
154 | struct ebitmap_node *node_last = NULL; | 145 | u32 c_idx; |
155 | u32 i_byte; | ||
156 | u32 i_bit; | ||
157 | unsigned char src_byte; | ||
158 | |||
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); | ||
163 | 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 | 146 | ||
176 | node_new = kzalloc(sizeof(*node_new), GFP_ATOMIC); | 147 | /* This function is a much simpler because SELinux's MAPTYPE happens |
177 | if (unlikely(node_new == NULL)) { | 148 | * to be the same as NetLabel's NETLBL_CATMAP_MAPTYPE, if MAPTYPE is |
178 | ebitmap_destroy(dst); | 149 | * changed from a u64 this function will most likely need to be changed |
179 | return -ENOMEM; | 150 | * as well. It's not ideal but I think the tradeoff in terms of |
180 | } | 151 | * neatness and speed is worth it. */ |
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 | } | ||
190 | 152 | ||
191 | if (node_last != NULL) | 153 | do { |
192 | node_last->next = node_new; | 154 | for (c_idx = 0; c_idx < NETLBL_CATMAP_MAPCNT; c_idx++) { |
193 | else | 155 | if (c_iter->bitmap[c_idx] == 0) |
194 | dst->node = node_new; | 156 | continue; |
195 | node_last = node_new; | 157 | |
196 | } | 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; | ||
197 | 166 | ||
198 | if (likely(node_last != NULL)) | 167 | e_iter->startbit = c_iter->startbit + |
199 | dst->highbit = node_last->startbit + MAPSIZE; | 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 | 177 | ||
203 | return 0; | 178 | return 0; |
179 | |||
180 | netlbl_import_failure: | ||
181 | ebitmap_destroy(ebmap); | ||
182 | return -ENOMEM; | ||
204 | } | 183 | } |
184 | #endif /* CONFIG_NETLABEL */ | ||
205 | 185 | ||
206 | int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2) | 186 | int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2) |
207 | { | 187 | { |
diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h index da2d4651b10d..1270e34b61c1 100644 --- a/security/selinux/ss/ebitmap.h +++ b/security/selinux/ss/ebitmap.h | |||
@@ -14,6 +14,8 @@ | |||
14 | #ifndef _SS_EBITMAP_H_ | 14 | #ifndef _SS_EBITMAP_H_ |
15 | #define _SS_EBITMAP_H_ | 15 | #define _SS_EBITMAP_H_ |
16 | 16 | ||
17 | #include <net/netlabel.h> | ||
18 | |||
17 | #define MAPTYPE u64 /* portion of bitmap in each node */ | 19 | #define MAPTYPE u64 /* portion of bitmap in each node */ |
18 | #define MAPSIZE (sizeof(MAPTYPE) * 8) /* number of bits in node bitmap */ | 20 | #define MAPSIZE (sizeof(MAPTYPE) * 8) /* number of bits in node bitmap */ |
19 | #define MAPBIT 1ULL /* a bit in the node bitmap */ | 21 | #define MAPBIT 1ULL /* a bit in the node bitmap */ |
@@ -69,16 +71,28 @@ static inline int ebitmap_node_get_bit(struct ebitmap_node * n, | |||
69 | 71 | ||
70 | int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2); | 72 | int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2); |
71 | int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src); | 73 | int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src); |
72 | int ebitmap_export(const struct ebitmap *src, | ||
73 | unsigned char **dst, | ||
74 | size_t *dst_len); | ||
75 | int ebitmap_import(const unsigned char *src, | ||
76 | size_t src_len, | ||
77 | struct ebitmap *dst); | ||
78 | int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2); | 74 | int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2); |
79 | int ebitmap_get_bit(struct ebitmap *e, unsigned long bit); | 75 | int ebitmap_get_bit(struct ebitmap *e, unsigned long bit); |
80 | int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value); | 76 | int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value); |
81 | void ebitmap_destroy(struct ebitmap *e); | 77 | void ebitmap_destroy(struct ebitmap *e); |
82 | int ebitmap_read(struct ebitmap *e, void *fp); | 78 | int ebitmap_read(struct ebitmap *e, void *fp); |
83 | 79 | ||
80 | #ifdef CONFIG_NETLABEL | ||
81 | int ebitmap_netlbl_export(struct ebitmap *ebmap, | ||
82 | struct netlbl_lsm_secattr_catmap **catmap); | ||
83 | int ebitmap_netlbl_import(struct ebitmap *ebmap, | ||
84 | struct netlbl_lsm_secattr_catmap *catmap); | ||
85 | #else | ||
86 | static inline int ebitmap_netlbl_export(struct ebitmap *ebmap, | ||
87 | struct netlbl_lsm_secattr_catmap **catmap) | ||
88 | { | ||
89 | return -ENOMEM; | ||
90 | } | ||
91 | static inline int ebitmap_netlbl_import(struct ebitmap *ebmap, | ||
92 | struct netlbl_lsm_secattr_catmap *catmap) | ||
93 | { | ||
94 | return -ENOMEM; | ||
95 | } | ||
96 | #endif | ||
97 | |||
84 | #endif /* _SS_EBITMAP_H_ */ | 98 | #endif /* _SS_EBITMAP_H_ */ |
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index 2cca8e251624..b4f682dc13ff 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c | |||
@@ -13,7 +13,7 @@ | |||
13 | /* | 13 | /* |
14 | * Updated: Hewlett-Packard <paul.moore@hp.com> | 14 | * Updated: Hewlett-Packard <paul.moore@hp.com> |
15 | * | 15 | * |
16 | * Added support to import/export the MLS label | 16 | * Added support to import/export the MLS label from NetLabel |
17 | * | 17 | * |
18 | * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 | 18 | * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 |
19 | */ | 19 | */ |
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/string.h> | 23 | #include <linux/string.h> |
24 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
25 | #include <net/netlabel.h> | ||
25 | #include "sidtab.h" | 26 | #include "sidtab.h" |
26 | #include "mls.h" | 27 | #include "mls.h" |
27 | #include "policydb.h" | 28 | #include "policydb.h" |
@@ -571,163 +572,108 @@ int mls_compute_sid(struct context *scontext, | |||
571 | return -EINVAL; | 572 | return -EINVAL; |
572 | } | 573 | } |
573 | 574 | ||
575 | #ifdef CONFIG_NETLABEL | ||
574 | /** | 576 | /** |
575 | * mls_export_lvl - Export the MLS sensitivity levels | 577 | * mls_export_netlbl_lvl - Export the MLS sensitivity levels to NetLabel |
576 | * @context: the security context | 578 | * @context: the security context |
577 | * @low: the low sensitivity level | 579 | * @secattr: the NetLabel security attributes |
578 | * @high: the high sensitivity level | ||
579 | * | 580 | * |
580 | * Description: | 581 | * Description: |
581 | * Given the security context copy the low MLS sensitivity level into lvl_low | 582 | * Given the security context copy the low MLS sensitivity level into the |
582 | * and the high sensitivity level in lvl_high. The MLS levels are only | 583 | * NetLabel MLS sensitivity level field. |
583 | * exported if the pointers are not NULL, if they are NULL then that level is | ||
584 | * not exported. | ||
585 | * | 584 | * |
586 | */ | 585 | */ |
587 | void mls_export_lvl(const struct context *context, u32 *low, u32 *high) | 586 | void mls_export_netlbl_lvl(struct context *context, |
587 | struct netlbl_lsm_secattr *secattr) | ||
588 | { | 588 | { |
589 | if (!selinux_mls_enabled) | 589 | if (!selinux_mls_enabled) |
590 | return; | 590 | return; |
591 | 591 | ||
592 | if (low != NULL) | 592 | secattr->mls_lvl = context->range.level[0].sens - 1; |
593 | *low = context->range.level[0].sens - 1; | 593 | secattr->flags |= NETLBL_SECATTR_MLS_LVL; |
594 | if (high != NULL) | ||
595 | *high = context->range.level[1].sens - 1; | ||
596 | } | 594 | } |
597 | 595 | ||
598 | /** | 596 | /** |
599 | * mls_import_lvl - Import the MLS sensitivity levels | 597 | * mls_import_netlbl_lvl - Import the NetLabel MLS sensitivity levels |
600 | * @context: the security context | 598 | * @context: the security context |
601 | * @low: the low sensitivity level | 599 | * @secattr: the NetLabel security attributes |
602 | * @high: the high sensitivity level | ||
603 | * | 600 | * |
604 | * Description: | 601 | * Description: |
605 | * Given the security context and the two sensitivty levels, set the MLS levels | 602 | * Given the security context and the NetLabel security attributes, copy the |
606 | * in the context according the two given as parameters. Returns zero on | 603 | * NetLabel MLS sensitivity level into the context. |
607 | * success, negative values on failure. | ||
608 | * | 604 | * |
609 | */ | 605 | */ |
610 | void mls_import_lvl(struct context *context, u32 low, u32 high) | 606 | void mls_import_netlbl_lvl(struct context *context, |
607 | struct netlbl_lsm_secattr *secattr) | ||
611 | { | 608 | { |
612 | if (!selinux_mls_enabled) | 609 | if (!selinux_mls_enabled) |
613 | return; | 610 | return; |
614 | 611 | ||
615 | context->range.level[0].sens = low + 1; | 612 | context->range.level[0].sens = secattr->mls_lvl + 1; |
616 | context->range.level[1].sens = high + 1; | 613 | context->range.level[1].sens = context->range.level[0].sens; |
617 | } | 614 | } |
618 | 615 | ||
619 | /** | 616 | /** |
620 | * mls_export_cat - Export the MLS categories | 617 | * mls_export_netlbl_cat - Export the MLS categories to NetLabel |
621 | * @context: the security context | 618 | * @context: the security context |
622 | * @low: the low category | 619 | * @secattr: the NetLabel security attributes |
623 | * @low_len: length of the cat_low bitmap in bytes | ||
624 | * @high: the high category | ||
625 | * @high_len: length of the cat_high bitmap in bytes | ||
626 | * | 620 | * |
627 | * Description: | 621 | * Description: |
628 | * Given the security context export the low MLS category bitmap into cat_low | 622 | * Given the security context copy the low MLS categories into the NetLabel |
629 | * and the high category bitmap into cat_high. The MLS categories are only | 623 | * MLS category field. Returns zero on success, negative values on failure. |
630 | * exported if the pointers are not NULL, if they are NULL then that level is | ||
631 | * not exported. The caller is responsibile for freeing the memory when | ||
632 | * finished. Returns zero on success, negative values on failure. | ||
633 | * | 624 | * |
634 | */ | 625 | */ |
635 | int mls_export_cat(const struct context *context, | 626 | int mls_export_netlbl_cat(struct context *context, |
636 | unsigned char **low, | 627 | struct netlbl_lsm_secattr *secattr) |
637 | size_t *low_len, | ||
638 | unsigned char **high, | ||
639 | size_t *high_len) | ||
640 | { | 628 | { |
641 | int rc = -EPERM; | 629 | int rc; |
642 | 630 | ||
643 | if (!selinux_mls_enabled) { | 631 | if (!selinux_mls_enabled) |
644 | *low = NULL; | ||
645 | *low_len = 0; | ||
646 | *high = NULL; | ||
647 | *high_len = 0; | ||
648 | return 0; | 632 | return 0; |
649 | } | ||
650 | 633 | ||
651 | if (low != NULL) { | 634 | rc = ebitmap_netlbl_export(&context->range.level[0].cat, |
652 | rc = ebitmap_export(&context->range.level[0].cat, | 635 | &secattr->mls_cat); |
653 | low, | 636 | if (rc == 0 && secattr->mls_cat != NULL) |
654 | low_len); | 637 | secattr->flags |= NETLBL_SECATTR_MLS_CAT; |
655 | if (rc != 0) | ||
656 | goto export_cat_failure; | ||
657 | } | ||
658 | if (high != NULL) { | ||
659 | rc = ebitmap_export(&context->range.level[1].cat, | ||
660 | high, | ||
661 | high_len); | ||
662 | if (rc != 0) | ||
663 | goto export_cat_failure; | ||
664 | } | ||
665 | |||
666 | return 0; | ||
667 | 638 | ||
668 | export_cat_failure: | ||
669 | if (low != NULL) { | ||
670 | kfree(*low); | ||
671 | *low = NULL; | ||
672 | *low_len = 0; | ||
673 | } | ||
674 | if (high != NULL) { | ||
675 | kfree(*high); | ||
676 | *high = NULL; | ||
677 | *high_len = 0; | ||
678 | } | ||
679 | return rc; | 639 | return rc; |
680 | } | 640 | } |
681 | 641 | ||
682 | /** | 642 | /** |
683 | * mls_import_cat - Import the MLS categories | 643 | * mls_import_netlbl_cat - Import the MLS categories from NetLabel |
684 | * @context: the security context | 644 | * @context: the security context |
685 | * @low: the low category | 645 | * @secattr: the NetLabel security attributes |
686 | * @low_len: length of the cat_low bitmap in bytes | ||
687 | * @high: the high category | ||
688 | * @high_len: length of the cat_high bitmap in bytes | ||
689 | * | 646 | * |
690 | * Description: | 647 | * Description: |
691 | * Given the security context and the two category bitmap strings import the | 648 | * Copy the NetLabel security attributes into the SELinux context; since the |
692 | * categories into the security context. The MLS categories are only imported | 649 | * NetLabel security attribute only contains a single MLS category use it for |
693 | * if the pointers are not NULL, if they are NULL they are skipped. Returns | 650 | * both the low and high categories of the context. Returns zero on success, |
694 | * zero on success, negative values on failure. | 651 | * negative values on failure. |
695 | * | 652 | * |
696 | */ | 653 | */ |
697 | int mls_import_cat(struct context *context, | 654 | int mls_import_netlbl_cat(struct context *context, |
698 | const unsigned char *low, | 655 | struct netlbl_lsm_secattr *secattr) |
699 | size_t low_len, | ||
700 | const unsigned char *high, | ||
701 | size_t high_len) | ||
702 | { | 656 | { |
703 | int rc = -EPERM; | 657 | int rc; |
704 | 658 | ||
705 | if (!selinux_mls_enabled) | 659 | if (!selinux_mls_enabled) |
706 | return 0; | 660 | return 0; |
707 | 661 | ||
708 | if (low != NULL) { | 662 | rc = ebitmap_netlbl_import(&context->range.level[0].cat, |
709 | rc = ebitmap_import(low, | 663 | secattr->mls_cat); |
710 | low_len, | 664 | if (rc != 0) |
711 | &context->range.level[0].cat); | 665 | goto import_netlbl_cat_failure; |
712 | if (rc != 0) | 666 | |
713 | goto import_cat_failure; | 667 | rc = ebitmap_cpy(&context->range.level[1].cat, |
714 | } | 668 | &context->range.level[0].cat); |
715 | if (high != NULL) { | 669 | if (rc != 0) |
716 | if (high == low) | 670 | goto import_netlbl_cat_failure; |
717 | rc = ebitmap_cpy(&context->range.level[1].cat, | ||
718 | &context->range.level[0].cat); | ||
719 | else | ||
720 | rc = ebitmap_import(high, | ||
721 | high_len, | ||
722 | &context->range.level[1].cat); | ||
723 | if (rc != 0) | ||
724 | goto import_cat_failure; | ||
725 | } | ||
726 | 671 | ||
727 | return 0; | 672 | return 0; |
728 | 673 | ||
729 | import_cat_failure: | 674 | import_netlbl_cat_failure: |
730 | ebitmap_destroy(&context->range.level[0].cat); | 675 | ebitmap_destroy(&context->range.level[0].cat); |
731 | ebitmap_destroy(&context->range.level[1].cat); | 676 | ebitmap_destroy(&context->range.level[1].cat); |
732 | return rc; | 677 | return rc; |
733 | } | 678 | } |
679 | #endif /* CONFIG_NETLABEL */ | ||
diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h index df6032c6d492..661d6fc76966 100644 --- a/security/selinux/ss/mls.h +++ b/security/selinux/ss/mls.h | |||
@@ -13,7 +13,7 @@ | |||
13 | /* | 13 | /* |
14 | * Updated: Hewlett-Packard <paul.moore@hp.com> | 14 | * Updated: Hewlett-Packard <paul.moore@hp.com> |
15 | * | 15 | * |
16 | * Added support to import/export the MLS label | 16 | * Added support to import/export the MLS label from NetLabel |
17 | * | 17 | * |
18 | * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 | 18 | * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 |
19 | */ | 19 | */ |
@@ -69,19 +69,37 @@ int mls_compute_sid(struct context *scontext, | |||
69 | int mls_setup_user_range(struct context *fromcon, struct user_datum *user, | 69 | int mls_setup_user_range(struct context *fromcon, struct user_datum *user, |
70 | struct context *usercon); | 70 | struct context *usercon); |
71 | 71 | ||
72 | void mls_export_lvl(const struct context *context, u32 *low, u32 *high); | 72 | #ifdef CONFIG_NETLABEL |
73 | void mls_import_lvl(struct context *context, u32 low, u32 high); | 73 | void mls_export_netlbl_lvl(struct context *context, |
74 | 74 | struct netlbl_lsm_secattr *secattr); | |
75 | int mls_export_cat(const struct context *context, | 75 | void mls_import_netlbl_lvl(struct context *context, |
76 | unsigned char **low, | 76 | struct netlbl_lsm_secattr *secattr); |
77 | size_t *low_len, | 77 | int mls_export_netlbl_cat(struct context *context, |
78 | unsigned char **high, | 78 | struct netlbl_lsm_secattr *secattr); |
79 | size_t *high_len); | 79 | int mls_import_netlbl_cat(struct context *context, |
80 | int mls_import_cat(struct context *context, | 80 | struct netlbl_lsm_secattr *secattr); |
81 | const unsigned char *low, | 81 | #else |
82 | size_t low_len, | 82 | static inline void mls_export_netlbl_lvl(struct context *context, |
83 | const unsigned char *high, | 83 | struct netlbl_lsm_secattr *secattr) |
84 | size_t high_len); | 84 | { |
85 | return; | ||
86 | } | ||
87 | static inline void mls_import_netlbl_lvl(struct context *context, | ||
88 | struct netlbl_lsm_secattr *secattr) | ||
89 | { | ||
90 | return; | ||
91 | } | ||
92 | static inline int mls_export_netlbl_cat(struct context *context, | ||
93 | struct netlbl_lsm_secattr *secattr) | ||
94 | { | ||
95 | return -ENOMEM; | ||
96 | } | ||
97 | static inline int mls_import_netlbl_cat(struct context *context, | ||
98 | struct netlbl_lsm_secattr *secattr) | ||
99 | { | ||
100 | return -ENOMEM; | ||
101 | } | ||
102 | #endif | ||
85 | 103 | ||
86 | #endif /* _SS_MLS_H */ | 104 | #endif /* _SS_MLS_H */ |
87 | 105 | ||
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index b43dd803fd5e..bdb7070dd3dc 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -55,6 +55,7 @@ | |||
55 | #include "objsec.h" | 55 | #include "objsec.h" |
56 | #include "selinux_netlabel.h" | 56 | #include "selinux_netlabel.h" |
57 | #include "xfrm.h" | 57 | #include "xfrm.h" |
58 | #include "ebitmap.h" | ||
58 | 59 | ||
59 | extern void selnl_notify_policyload(u32 seqno); | 60 | extern void selnl_notify_policyload(u32 seqno); |
60 | unsigned int policydb_loaded_version; | 61 | unsigned int policydb_loaded_version; |
@@ -2384,13 +2385,10 @@ static int selinux_netlbl_secattr_to_sid(struct sk_buff *skb, | |||
2384 | ctx_new.user = ctx->user; | 2385 | ctx_new.user = ctx->user; |
2385 | ctx_new.role = ctx->role; | 2386 | ctx_new.role = ctx->role; |
2386 | ctx_new.type = ctx->type; | 2387 | ctx_new.type = ctx->type; |
2387 | mls_import_lvl(&ctx_new, secattr->mls_lvl, secattr->mls_lvl); | 2388 | mls_import_netlbl_lvl(&ctx_new, secattr); |
2388 | if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { | 2389 | if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { |
2389 | if (mls_import_cat(&ctx_new, | 2390 | if (ebitmap_netlbl_import(&ctx_new.range.level[0].cat, |
2390 | secattr->mls_cat, | 2391 | secattr->mls_cat) != 0) |
2391 | secattr->mls_cat_len, | ||
2392 | NULL, | ||
2393 | 0) != 0) | ||
2394 | goto netlbl_secattr_to_sid_return; | 2392 | goto netlbl_secattr_to_sid_return; |
2395 | ctx_new.range.level[1].cat.highbit = | 2393 | ctx_new.range.level[1].cat.highbit = |
2396 | ctx_new.range.level[0].cat.highbit; | 2394 | ctx_new.range.level[0].cat.highbit; |
@@ -2486,19 +2484,12 @@ static int selinux_netlbl_socket_setsid(struct socket *sock, u32 sid) | |||
2486 | 2484 | ||
2487 | secattr.domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1], | 2485 | secattr.domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1], |
2488 | GFP_ATOMIC); | 2486 | GFP_ATOMIC); |
2489 | mls_export_lvl(ctx, &secattr.mls_lvl, NULL); | 2487 | secattr.flags |= NETLBL_SECATTR_DOMAIN; |
2490 | rc = mls_export_cat(ctx, | 2488 | mls_export_netlbl_lvl(ctx, &secattr); |
2491 | &secattr.mls_cat, | 2489 | rc = mls_export_netlbl_cat(ctx, &secattr); |
2492 | &secattr.mls_cat_len, | ||
2493 | NULL, | ||
2494 | NULL); | ||
2495 | if (rc != 0) | 2490 | if (rc != 0) |
2496 | goto netlbl_socket_setsid_return; | 2491 | goto netlbl_socket_setsid_return; |
2497 | 2492 | ||
2498 | secattr.flags |= NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL; | ||
2499 | if (secattr.mls_cat) | ||
2500 | secattr.flags |= NETLBL_SECATTR_MLS_CAT; | ||
2501 | |||
2502 | rc = netlbl_socket_setattr(sock, &secattr); | 2493 | rc = netlbl_socket_setattr(sock, &secattr); |
2503 | if (rc == 0) { | 2494 | if (rc == 0) { |
2504 | spin_lock(&sksec->nlbl_lock); | 2495 | spin_lock(&sksec->nlbl_lock); |