aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Moore <paul.moore@hp.com>2006-11-29 13:18:18 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-03 00:31:36 -0500
commit02752760359db6b00a3ffb1acfc13ef8d9eb1e3f (patch)
tree796cd65fd4cd732b295e61dac194efbf36b78842
parentef91fd522ba3c88d9c68261c243567bc4c5a8f55 (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>
-rw-r--r--include/net/netlabel.h102
-rw-r--r--net/ipv4/cipso_ipv4.c168
-rw-r--r--net/netlabel/netlabel_kapi.c201
-rw-r--r--security/selinux/ss/ebitmap.c198
-rw-r--r--security/selinux/ss/ebitmap.h26
-rw-r--r--security/selinux/ss/mls.c156
-rw-r--r--security/selinux/ss/mls.h46
-rw-r--r--security/selinux/ss/services.c23
8 files changed, 568 insertions, 352 deletions
diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index d605d7954013..83da7e1f0d3d 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -111,6 +111,22 @@ struct netlbl_lsm_cache {
111 void (*free) (const void *data); 111 void (*free) (const void *data);
112 void *data; 112 void *data;
113}; 113};
114/* The catmap bitmap field MUST be a power of two in length and large
115 * enough to hold at least 240 bits. Special care (i.e. check the code!)
116 * should be used when changing these values as the LSM implementation
117 * probably has functions which rely on the sizes of these types to speed
118 * processing. */
119#define NETLBL_CATMAP_MAPTYPE u64
120#define NETLBL_CATMAP_MAPCNT 4
121#define NETLBL_CATMAP_MAPSIZE (sizeof(NETLBL_CATMAP_MAPTYPE) * 8)
122#define NETLBL_CATMAP_SIZE (NETLBL_CATMAP_MAPSIZE * \
123 NETLBL_CATMAP_MAPCNT)
124#define NETLBL_CATMAP_BIT (NETLBL_CATMAP_MAPTYPE)0x01
125struct netlbl_lsm_secattr_catmap {
126 u32 startbit;
127 NETLBL_CATMAP_MAPTYPE bitmap[NETLBL_CATMAP_MAPCNT];
128 struct netlbl_lsm_secattr_catmap *next;
129};
114#define NETLBL_SECATTR_NONE 0x00000000 130#define NETLBL_SECATTR_NONE 0x00000000
115#define NETLBL_SECATTR_DOMAIN 0x00000001 131#define NETLBL_SECATTR_DOMAIN 0x00000001
116#define NETLBL_SECATTR_CACHE 0x00000002 132#define NETLBL_SECATTR_CACHE 0x00000002
@@ -122,8 +138,7 @@ struct netlbl_lsm_secattr {
122 char *domain; 138 char *domain;
123 139
124 u32 mls_lvl; 140 u32 mls_lvl;
125 unsigned char *mls_cat; 141 struct netlbl_lsm_secattr_catmap *mls_cat;
126 size_t mls_cat_len;
127 142
128 struct netlbl_lsm_cache *cache; 143 struct netlbl_lsm_cache *cache;
129}; 144};
@@ -171,6 +186,41 @@ static inline void netlbl_secattr_cache_free(struct netlbl_lsm_cache *cache)
171} 186}
172 187
173/** 188/**
189 * netlbl_secattr_catmap_alloc - Allocate a LSM secattr catmap
190 * @flags: memory allocation flags
191 *
192 * Description:
193 * Allocate memory for a LSM secattr catmap, returns a pointer on success, NULL
194 * on failure.
195 *
196 */
197static inline struct netlbl_lsm_secattr_catmap *netlbl_secattr_catmap_alloc(
198 gfp_t flags)
199{
200 return kzalloc(sizeof(struct netlbl_lsm_secattr_catmap), flags);
201}
202
203/**
204 * netlbl_secattr_catmap_free - Free a LSM secattr catmap
205 * @catmap: the category bitmap
206 *
207 * Description:
208 * Free a LSM secattr catmap.
209 *
210 */
211static inline void netlbl_secattr_catmap_free(
212 struct netlbl_lsm_secattr_catmap *catmap)
213{
214 struct netlbl_lsm_secattr_catmap *iter;
215
216 do {
217 iter = catmap;
218 catmap = catmap->next;
219 kfree(iter);
220 } while (catmap);
221}
222
223/**
174 * netlbl_secattr_init - Initialize a netlbl_lsm_secattr struct 224 * netlbl_secattr_init - Initialize a netlbl_lsm_secattr struct
175 * @secattr: the struct to initialize 225 * @secattr: the struct to initialize
176 * 226 *
@@ -200,7 +250,8 @@ static inline void netlbl_secattr_destroy(struct netlbl_lsm_secattr *secattr)
200 if (secattr->cache) 250 if (secattr->cache)
201 netlbl_secattr_cache_free(secattr->cache); 251 netlbl_secattr_cache_free(secattr->cache);
202 kfree(secattr->domain); 252 kfree(secattr->domain);
203 kfree(secattr->mls_cat); 253 if (secattr->mls_cat)
254 netlbl_secattr_catmap_free(secattr->mls_cat);
204} 255}
205 256
206/** 257/**
@@ -231,6 +282,51 @@ static inline void netlbl_secattr_free(struct netlbl_lsm_secattr *secattr)
231 kfree(secattr); 282 kfree(secattr);
232} 283}
233 284
285#ifdef CONFIG_NETLABEL
286int netlbl_secattr_catmap_walk(struct netlbl_lsm_secattr_catmap *catmap,
287 u32 offset);
288int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap,
289 u32 offset);
290int netlbl_secattr_catmap_setbit(struct netlbl_lsm_secattr_catmap *catmap,
291 u32 bit,
292 gfp_t flags);
293int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap,
294 u32 start,
295 u32 end,
296 gfp_t flags);
297#else
298static inline int netlbl_secattr_catmap_walk(
299 struct netlbl_lsm_secattr_catmap *catmap,
300 u32 offset)
301{
302 return -ENOENT;
303}
304
305static inline int netlbl_secattr_catmap_walk_rng(
306 struct netlbl_lsm_secattr_catmap *catmap,
307 u32 offset)
308{
309 return -ENOENT;
310}
311
312static inline int netlbl_secattr_catmap_setbit(
313 struct netlbl_lsm_secattr_catmap *catmap,
314 u32 bit,
315 gfp_t flags)
316{
317 return 0;
318}
319
320static inline int netlbl_secattr_catmap_setrng(
321 struct netlbl_lsm_secattr_catmap *catmap,
322 u32 start,
323 u32 end,
324 gfp_t flags)
325{
326 return 0;
327}
328#endif
329
234/* 330/*
235 * LSM protocol operations 331 * LSM protocol operations
236 */ 332 */
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index f3957cfaed42..08144f8fc911 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -819,8 +819,7 @@ static int cipso_v4_map_cat_rbm_valid(const struct cipso_v4_doi *doi_def,
819/** 819/**
820 * cipso_v4_map_cat_rbm_hton - Perform a category mapping from host to network 820 * cipso_v4_map_cat_rbm_hton - Perform a category mapping from host to network
821 * @doi_def: the DOI definition 821 * @doi_def: the DOI definition
822 * @host_cat: the category bitmap in host format 822 * @secattr: the security attributes
823 * @host_cat_len: the length of the host's category bitmap in bytes
824 * @net_cat: the zero'd out category bitmap in network/CIPSO format 823 * @net_cat: the zero'd out category bitmap in network/CIPSO format
825 * @net_cat_len: the length of the CIPSO bitmap in bytes 824 * @net_cat_len: the length of the CIPSO bitmap in bytes
826 * 825 *
@@ -831,61 +830,51 @@ static int cipso_v4_map_cat_rbm_valid(const struct cipso_v4_doi *doi_def,
831 * 830 *
832 */ 831 */
833static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def, 832static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def,
834 const unsigned char *host_cat, 833 const struct netlbl_lsm_secattr *secattr,
835 u32 host_cat_len,
836 unsigned char *net_cat, 834 unsigned char *net_cat,
837 u32 net_cat_len) 835 u32 net_cat_len)
838{ 836{
839 int host_spot = -1; 837 int host_spot = -1;
840 u32 net_spot; 838 u32 net_spot = CIPSO_V4_INV_CAT;
841 u32 net_spot_max = 0; 839 u32 net_spot_max = 0;
842 u32 host_clen_bits = host_cat_len * 8;
843 u32 net_clen_bits = net_cat_len * 8; 840 u32 net_clen_bits = net_cat_len * 8;
844 u32 host_cat_size; 841 u32 host_cat_size = 0;
845 u32 *host_cat_array; 842 u32 *host_cat_array = NULL;
846 843
847 switch (doi_def->type) { 844 if (doi_def->type == CIPSO_V4_MAP_STD) {
848 case CIPSO_V4_MAP_PASS:
849 net_spot_max = host_cat_len;
850 while (net_spot_max > 0 && host_cat[net_spot_max - 1] == 0)
851 net_spot_max--;
852 if (net_spot_max > net_cat_len)
853 return -EINVAL;
854 memcpy(net_cat, host_cat, net_spot_max);
855 return net_spot_max;
856 case CIPSO_V4_MAP_STD:
857 host_cat_size = doi_def->map.std->cat.local_size; 845 host_cat_size = doi_def->map.std->cat.local_size;
858 host_cat_array = doi_def->map.std->cat.local; 846 host_cat_array = doi_def->map.std->cat.local;
859 for (;;) { 847 }
860 host_spot = cipso_v4_bitmap_walk(host_cat, 848
861 host_clen_bits, 849 for (;;) {
862 host_spot + 1, 850 host_spot = netlbl_secattr_catmap_walk(secattr->mls_cat,
863 1); 851 host_spot + 1);
864 if (host_spot < 0) 852 if (host_spot < 0)
865 break; 853 break;
854
855 switch (doi_def->type) {
856 case CIPSO_V4_MAP_PASS:
857 net_spot = host_spot;
858 break;
859 case CIPSO_V4_MAP_STD:
866 if (host_spot >= host_cat_size) 860 if (host_spot >= host_cat_size)
867 return -EPERM; 861 return -EPERM;
868
869 net_spot = host_cat_array[host_spot]; 862 net_spot = host_cat_array[host_spot];
870 if (net_spot >= CIPSO_V4_INV_CAT) 863 if (net_spot >= CIPSO_V4_INV_CAT)
871 return -EPERM; 864 return -EPERM;
872 if (net_spot >= net_clen_bits) 865 break;
873 return -ENOSPC;
874 cipso_v4_bitmap_setbit(net_cat, net_spot, 1);
875
876 if (net_spot > net_spot_max)
877 net_spot_max = net_spot;
878 } 866 }
867 if (net_spot >= net_clen_bits)
868 return -ENOSPC;
869 cipso_v4_bitmap_setbit(net_cat, net_spot, 1);
879 870
880 if (host_spot == -2) 871 if (net_spot > net_spot_max)
881 return -EFAULT; 872 net_spot_max = net_spot;
882
883 if (++net_spot_max % 8)
884 return net_spot_max / 8 + 1;
885 return net_spot_max / 8;
886 } 873 }
887 874
888 return -EINVAL; 875 if (++net_spot_max % 8)
876 return net_spot_max / 8 + 1;
877 return net_spot_max / 8;
889} 878}
890 879
891/** 880/**
@@ -893,66 +882,59 @@ static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def,
893 * @doi_def: the DOI definition 882 * @doi_def: the DOI definition
894 * @net_cat: the category bitmap in network/CIPSO format 883 * @net_cat: the category bitmap in network/CIPSO format
895 * @net_cat_len: the length of the CIPSO bitmap in bytes 884 * @net_cat_len: the length of the CIPSO bitmap in bytes
896 * @host_cat: the zero'd out category bitmap in host format 885 * @secattr: the security attributes
897 * @host_cat_len: the length of the host's category bitmap in bytes
898 * 886 *
899 * Description: 887 * Description:
900 * Perform a label mapping to translate a CIPSO bitmap to the correct local 888 * Perform a label mapping to translate a CIPSO bitmap to the correct local
901 * MLS category bitmap using the given DOI definition. Returns the minimum 889 * MLS category bitmap using the given DOI definition. Returns zero on
902 * size in bytes of the host bitmap on success, negative values otherwise. 890 * success, negative values on failure.
903 * 891 *
904 */ 892 */
905static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def, 893static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,
906 const unsigned char *net_cat, 894 const unsigned char *net_cat,
907 u32 net_cat_len, 895 u32 net_cat_len,
908 unsigned char *host_cat, 896 struct netlbl_lsm_secattr *secattr)
909 u32 host_cat_len)
910{ 897{
911 u32 host_spot; 898 int ret_val;
912 u32 host_spot_max = 0;
913 int net_spot = -1; 899 int net_spot = -1;
900 u32 host_spot = CIPSO_V4_INV_CAT;
914 u32 net_clen_bits = net_cat_len * 8; 901 u32 net_clen_bits = net_cat_len * 8;
915 u32 host_clen_bits = host_cat_len * 8; 902 u32 net_cat_size = 0;
916 u32 net_cat_size; 903 u32 *net_cat_array = NULL;
917 u32 *net_cat_array;
918 904
919 switch (doi_def->type) { 905 if (doi_def->type == CIPSO_V4_MAP_STD) {
920 case CIPSO_V4_MAP_PASS:
921 if (net_cat_len > host_cat_len)
922 return -EINVAL;
923 memcpy(host_cat, net_cat, net_cat_len);
924 return net_cat_len;
925 case CIPSO_V4_MAP_STD:
926 net_cat_size = doi_def->map.std->cat.cipso_size; 906 net_cat_size = doi_def->map.std->cat.cipso_size;
927 net_cat_array = doi_def->map.std->cat.cipso; 907 net_cat_array = doi_def->map.std->cat.cipso;
928 for (;;) { 908 }
929 net_spot = cipso_v4_bitmap_walk(net_cat,
930 net_clen_bits,
931 net_spot + 1,
932 1);
933 if (net_spot < 0)
934 break;
935 if (net_spot >= net_cat_size ||
936 net_cat_array[net_spot] >= CIPSO_V4_INV_CAT)
937 return -EPERM;
938 909
910 for (;;) {
911 net_spot = cipso_v4_bitmap_walk(net_cat,
912 net_clen_bits,
913 net_spot + 1,
914 1);
915 if (net_spot < 0) {
916 if (net_spot == -2)
917 return -EFAULT;
918 return 0;
919 }
920
921 switch (doi_def->type) {
922 case CIPSO_V4_MAP_PASS:
923 host_spot = net_spot;
924 break;
925 case CIPSO_V4_MAP_STD:
926 if (net_spot >= net_cat_size)
927 return -EPERM;
939 host_spot = net_cat_array[net_spot]; 928 host_spot = net_cat_array[net_spot];
940 if (host_spot >= CIPSO_V4_INV_CAT) 929 if (host_spot >= CIPSO_V4_INV_CAT)
941 return -EPERM; 930 return -EPERM;
942 if (host_spot >= host_clen_bits) 931 break;
943 return -ENOSPC;
944 cipso_v4_bitmap_setbit(host_cat, host_spot, 1);
945
946 if (host_spot > host_spot_max)
947 host_spot_max = host_spot;
948 } 932 }
949 933 ret_val = netlbl_secattr_catmap_setbit(secattr->mls_cat,
950 if (net_spot == -2) 934 host_spot,
951 return -EFAULT; 935 GFP_ATOMIC);
952 936 if (ret_val != 0)
953 if (++host_spot_max % 8) 937 return ret_val;
954 return host_spot_max / 8 + 1;
955 return host_spot_max / 8;
956 } 938 }
957 939
958 return -EINVAL; 940 return -EINVAL;
@@ -1016,8 +998,7 @@ static int cipso_v4_gentag_rbm(const struct cipso_v4_doi *doi_def,
1016 998
1017 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { 999 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
1018 ret_val = cipso_v4_map_cat_rbm_hton(doi_def, 1000 ret_val = cipso_v4_map_cat_rbm_hton(doi_def,
1019 secattr->mls_cat, 1001 secattr,
1020 secattr->mls_cat_len,
1021 &buffer[4], 1002 &buffer[4],
1022 buffer_len - 4); 1003 buffer_len - 4);
1023 if (ret_val < 0) 1004 if (ret_val < 0)
@@ -1067,31 +1048,20 @@ static int cipso_v4_parsetag_rbm(const struct cipso_v4_doi *doi_def,
1067 secattr->flags |= NETLBL_SECATTR_MLS_LVL; 1048 secattr->flags |= NETLBL_SECATTR_MLS_LVL;
1068 1049
1069 if (tag_len > 4) { 1050 if (tag_len > 4) {
1070 switch (doi_def->type) { 1051 secattr->mls_cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
1071 case CIPSO_V4_MAP_PASS:
1072 secattr->mls_cat_len = tag_len - 4;
1073 break;
1074 case CIPSO_V4_MAP_STD:
1075 secattr->mls_cat_len =
1076 doi_def->map.std->cat.local_size;
1077 break;
1078 }
1079 secattr->mls_cat = kzalloc(secattr->mls_cat_len, GFP_ATOMIC);
1080 if (secattr->mls_cat == NULL) 1052 if (secattr->mls_cat == NULL)
1081 return -ENOMEM; 1053 return -ENOMEM;
1082 1054
1083 ret_val = cipso_v4_map_cat_rbm_ntoh(doi_def, 1055 ret_val = cipso_v4_map_cat_rbm_ntoh(doi_def,
1084 &tag[4], 1056 &tag[4],
1085 tag_len - 4, 1057 tag_len - 4,
1086 secattr->mls_cat, 1058 secattr);
1087 secattr->mls_cat_len); 1059 if (ret_val != 0) {
1088 if (ret_val < 0) { 1060 netlbl_secattr_catmap_free(secattr->mls_cat);
1089 kfree(secattr->mls_cat);
1090 return ret_val; 1061 return ret_val;
1091 } else if (ret_val > 0) {
1092 secattr->mls_cat_len = ret_val;
1093 secattr->flags |= NETLBL_SECATTR_MLS_CAT;
1094 } 1062 }
1063
1064 secattr->flags |= NETLBL_SECATTR_MLS_CAT;
1095 } 1065 }
1096 1066
1097 return 0; 1067 return 0;
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index b35ebf94918c..e03a3282c551 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -40,6 +40,207 @@
40#include "netlabel_user.h" 40#include "netlabel_user.h"
41 41
42/* 42/*
43 * Security Attribute Functions
44 */
45
46/**
47 * netlbl_secattr_catmap_walk - Walk a LSM secattr catmap looking for a bit
48 * @catmap: the category bitmap
49 * @offset: the offset to start searching at, in bits
50 *
51 * Description:
52 * This function walks a LSM secattr category bitmap starting at @offset and
53 * returns the spot of the first set bit or -ENOENT if no bits are set.
54 *
55 */
56int netlbl_secattr_catmap_walk(struct netlbl_lsm_secattr_catmap *catmap,
57 u32 offset)
58{
59 struct netlbl_lsm_secattr_catmap *iter = catmap;
60 u32 node_idx;
61 u32 node_bit;
62 NETLBL_CATMAP_MAPTYPE bitmap;
63
64 if (offset > iter->startbit) {
65 while (offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
66 iter = iter->next;
67 if (iter == NULL)
68 return -ENOENT;
69 }
70 node_idx = (offset - iter->startbit) / NETLBL_CATMAP_MAPSIZE;
71 node_bit = offset - iter->startbit -
72 (NETLBL_CATMAP_MAPSIZE * node_idx);
73 } else {
74 node_idx = 0;
75 node_bit = 0;
76 }
77 bitmap = iter->bitmap[node_idx] >> node_bit;
78
79 for (;;) {
80 if (bitmap != 0) {
81 while ((bitmap & NETLBL_CATMAP_BIT) == 0) {
82 bitmap >>= 1;
83 node_bit++;
84 }
85 return iter->startbit +
86 (NETLBL_CATMAP_MAPSIZE * node_idx) + node_bit;
87 }
88 if (++node_idx >= NETLBL_CATMAP_MAPCNT) {
89 if (iter->next != NULL) {
90 iter = iter->next;
91 node_idx = 0;
92 } else
93 return -ENOENT;
94 }
95 bitmap = iter->bitmap[node_idx];
96 node_bit = 0;
97 }
98
99 return -ENOENT;
100}
101
102/**
103 * netlbl_secattr_catmap_walk_rng - Find the end of a string of set bits
104 * @catmap: the category bitmap
105 * @offset: the offset to start searching at, in bits
106 *
107 * Description:
108 * This function walks a LSM secattr category bitmap starting at @offset and
109 * returns the spot of the first cleared bit or -ENOENT if the offset is past
110 * the end of the bitmap.
111 *
112 */
113int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap,
114 u32 offset)
115{
116 struct netlbl_lsm_secattr_catmap *iter = catmap;
117 u32 node_idx;
118 u32 node_bit;
119 NETLBL_CATMAP_MAPTYPE bitmask;
120 NETLBL_CATMAP_MAPTYPE bitmap;
121
122 if (offset > iter->startbit) {
123 while (offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
124 iter = iter->next;
125 if (iter == NULL)
126 return -ENOENT;
127 }
128 node_idx = (offset - iter->startbit) / NETLBL_CATMAP_MAPSIZE;
129 node_bit = offset - iter->startbit -
130 (NETLBL_CATMAP_MAPSIZE * node_idx);
131 } else {
132 node_idx = 0;
133 node_bit = 0;
134 }
135 bitmask = NETLBL_CATMAP_BIT << node_bit;
136
137 for (;;) {
138 bitmap = iter->bitmap[node_idx];
139 while (bitmask != 0 && (bitmap & bitmask) != 0) {
140 bitmask <<= 1;
141 node_bit++;
142 }
143
144 if (bitmask != 0)
145 return iter->startbit +
146 (NETLBL_CATMAP_MAPSIZE * node_idx) +
147 node_bit - 1;
148 else if (++node_idx >= NETLBL_CATMAP_MAPCNT) {
149 if (iter->next == NULL)
150 return iter->startbit + NETLBL_CATMAP_SIZE - 1;
151 iter = iter->next;
152 node_idx = 0;
153 }
154 bitmask = NETLBL_CATMAP_BIT;
155 node_bit = 0;
156 }
157
158 return -ENOENT;
159}
160
161/**
162 * netlbl_secattr_catmap_setbit - Set a bit in a LSM secattr catmap
163 * @catmap: the category bitmap
164 * @bit: the bit to set
165 * @flags: memory allocation flags
166 *
167 * Description:
168 * Set the bit specified by @bit in @catmap. Returns zero on success,
169 * negative values on failure.
170 *
171 */
172int netlbl_secattr_catmap_setbit(struct netlbl_lsm_secattr_catmap *catmap,
173 u32 bit,
174 gfp_t flags)
175{
176 struct netlbl_lsm_secattr_catmap *iter = catmap;
177 u32 node_bit;
178 u32 node_idx;
179
180 while (iter->next != NULL &&
181 bit >= (iter->startbit + NETLBL_CATMAP_SIZE))
182 iter = iter->next;
183 if (bit >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
184 iter->next = netlbl_secattr_catmap_alloc(flags);
185 if (iter->next == NULL)
186 return -ENOMEM;
187 iter = iter->next;
188 iter->startbit = bit & ~(NETLBL_CATMAP_SIZE - 1);
189 }
190
191 /* gcc always rounds to zero when doing integer division */
192 node_idx = (bit - iter->startbit) / NETLBL_CATMAP_MAPSIZE;
193 node_bit = bit - iter->startbit - (NETLBL_CATMAP_MAPSIZE * node_idx);
194 iter->bitmap[node_idx] |= NETLBL_CATMAP_BIT << node_bit;
195
196 return 0;
197}
198
199/**
200 * netlbl_secattr_catmap_setrng - Set a range of bits in a LSM secattr catmap
201 * @catmap: the category bitmap
202 * @start: the starting bit
203 * @end: the last bit in the string
204 * @flags: memory allocation flags
205 *
206 * Description:
207 * Set a range of bits, starting at @start and ending with @end. Returns zero
208 * on success, negative values on failure.
209 *
210 */
211int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap,
212 u32 start,
213 u32 end,
214 gfp_t flags)
215{
216 int ret_val = 0;
217 struct netlbl_lsm_secattr_catmap *iter = catmap;
218 u32 iter_max_spot;
219 u32 spot;
220
221 /* XXX - This could probably be made a bit faster by combining writes
222 * to the catmap instead of setting a single bit each time, but for
223 * right now skipping to the start of the range in the catmap should
224 * be a nice improvement over calling the individual setbit function
225 * repeatedly from a loop. */
226
227 while (iter->next != NULL &&
228 start >= (iter->startbit + NETLBL_CATMAP_SIZE))
229 iter = iter->next;
230 iter_max_spot = iter->startbit + NETLBL_CATMAP_SIZE;
231
232 for (spot = start; spot <= end && ret_val == 0; spot++) {
233 if (spot >= iter_max_spot && iter->next != NULL) {
234 iter = iter->next;
235 iter_max_spot = iter->startbit + NETLBL_CATMAP_SIZE;
236 }
237 ret_val = netlbl_secattr_catmap_setbit(iter, spot, GFP_ATOMIC);
238 }
239
240 return ret_val;
241}
242
243/*
43 * LSM Functions 244 * LSM Functions
44 */ 245 */
45 246
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 */
85int ebitmap_export(const struct ebitmap *src, 82int 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
124netlbl_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 */
147int ebitmap_import(const unsigned char *src, 139int 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
180netlbl_import_failure:
181 ebitmap_destroy(ebmap);
182 return -ENOMEM;
204} 183}
184#endif /* CONFIG_NETLABEL */
205 185
206int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2) 186int 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
70int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2); 72int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2);
71int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src); 73int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src);
72int ebitmap_export(const struct ebitmap *src,
73 unsigned char **dst,
74 size_t *dst_len);
75int ebitmap_import(const unsigned char *src,
76 size_t src_len,
77 struct ebitmap *dst);
78int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2); 74int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2);
79int ebitmap_get_bit(struct ebitmap *e, unsigned long bit); 75int ebitmap_get_bit(struct ebitmap *e, unsigned long bit);
80int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value); 76int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value);
81void ebitmap_destroy(struct ebitmap *e); 77void ebitmap_destroy(struct ebitmap *e);
82int ebitmap_read(struct ebitmap *e, void *fp); 78int ebitmap_read(struct ebitmap *e, void *fp);
83 79
80#ifdef CONFIG_NETLABEL
81int ebitmap_netlbl_export(struct ebitmap *ebmap,
82 struct netlbl_lsm_secattr_catmap **catmap);
83int ebitmap_netlbl_import(struct ebitmap *ebmap,
84 struct netlbl_lsm_secattr_catmap *catmap);
85#else
86static inline int ebitmap_netlbl_export(struct ebitmap *ebmap,
87 struct netlbl_lsm_secattr_catmap **catmap)
88{
89 return -ENOMEM;
90}
91static 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 */
587void mls_export_lvl(const struct context *context, u32 *low, u32 *high) 586void 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 */
610void mls_import_lvl(struct context *context, u32 low, u32 high) 606void 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 */
635int mls_export_cat(const struct context *context, 626int 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
668export_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 */
697int mls_import_cat(struct context *context, 654int 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
729import_cat_failure: 674import_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,
69int mls_setup_user_range(struct context *fromcon, struct user_datum *user, 69int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
70 struct context *usercon); 70 struct context *usercon);
71 71
72void mls_export_lvl(const struct context *context, u32 *low, u32 *high); 72#ifdef CONFIG_NETLABEL
73void mls_import_lvl(struct context *context, u32 low, u32 high); 73void mls_export_netlbl_lvl(struct context *context,
74 74 struct netlbl_lsm_secattr *secattr);
75int mls_export_cat(const struct context *context, 75void mls_import_netlbl_lvl(struct context *context,
76 unsigned char **low, 76 struct netlbl_lsm_secattr *secattr);
77 size_t *low_len, 77int mls_export_netlbl_cat(struct context *context,
78 unsigned char **high, 78 struct netlbl_lsm_secattr *secattr);
79 size_t *high_len); 79int mls_import_netlbl_cat(struct context *context,
80int mls_import_cat(struct context *context, 80 struct netlbl_lsm_secattr *secattr);
81 const unsigned char *low, 81#else
82 size_t low_len, 82static 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}
87static inline void mls_import_netlbl_lvl(struct context *context,
88 struct netlbl_lsm_secattr *secattr)
89{
90 return;
91}
92static inline int mls_export_netlbl_cat(struct context *context,
93 struct netlbl_lsm_secattr *secattr)
94{
95 return -ENOMEM;
96}
97static 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
59extern void selnl_notify_policyload(u32 seqno); 60extern void selnl_notify_policyload(u32 seqno);
60unsigned int policydb_loaded_version; 61unsigned 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);