aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorJames Morris <james.l.morris@oracle.com>2014-08-02 08:58:02 -0400
committerJames Morris <james.l.morris@oracle.com>2014-08-02 08:58:02 -0400
commit103ae675b12dee75ec099abf3d22857d1384b3bc (patch)
treea6b4f71bc911e7283b6573ee5833cd36a3ac2469 /security
parenta3d64df849bcb84220bf6db5773a10eee1fad4dc (diff)
parent4fbe63d1c773cceef3fe1f6ed0c9c268f4f24760 (diff)
Merge branch 'next' of git://git.infradead.org/users/pcmoore/selinux into next
Diffstat (limited to 'security')
-rw-r--r--security/selinux/ss/ebitmap.c133
-rw-r--r--security/selinux/ss/ebitmap.h8
-rw-r--r--security/smack/smack_access.c11
-rw-r--r--security/smack/smack_lsm.c6
-rw-r--r--security/smack/smackfs.c14
5 files changed, 70 insertions, 102 deletions
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index 820313a04d49..afe6a269ec17 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -86,51 +86,36 @@ int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src)
86 * 86 *
87 */ 87 */
88int ebitmap_netlbl_export(struct ebitmap *ebmap, 88int ebitmap_netlbl_export(struct ebitmap *ebmap,
89 struct netlbl_lsm_secattr_catmap **catmap) 89 struct netlbl_lsm_catmap **catmap)
90{ 90{
91 struct ebitmap_node *e_iter = ebmap->node; 91 struct ebitmap_node *e_iter = ebmap->node;
92 struct netlbl_lsm_secattr_catmap *c_iter; 92 unsigned long e_map;
93 u32 cmap_idx, cmap_sft; 93 u32 offset;
94 int i; 94 unsigned int iter;
95 95 int rc;
96 /* NetLabel's NETLBL_CATMAP_MAPTYPE is defined as an array of u64,
97 * however, it is not always compatible with an array of unsigned long
98 * in ebitmap_node.
99 * In addition, you should pay attention the following implementation
100 * assumes unsigned long has a width equal with or less than 64-bit.
101 */
102 96
103 if (e_iter == NULL) { 97 if (e_iter == NULL) {
104 *catmap = NULL; 98 *catmap = NULL;
105 return 0; 99 return 0;
106 } 100 }
107 101
108 c_iter = netlbl_secattr_catmap_alloc(GFP_ATOMIC); 102 if (*catmap != NULL)
109 if (c_iter == NULL) 103 netlbl_catmap_free(*catmap);
110 return -ENOMEM; 104 *catmap = NULL;
111 *catmap = c_iter;
112 c_iter->startbit = e_iter->startbit & ~(NETLBL_CATMAP_SIZE - 1);
113 105
114 while (e_iter) { 106 while (e_iter) {
115 for (i = 0; i < EBITMAP_UNIT_NUMS; i++) { 107 offset = e_iter->startbit;
116 unsigned int delta, e_startbit, c_endbit; 108 for (iter = 0; iter < EBITMAP_UNIT_NUMS; iter++) {
117 109 e_map = e_iter->maps[iter];
118 e_startbit = e_iter->startbit + i * EBITMAP_UNIT_SIZE; 110 if (e_map != 0) {
119 c_endbit = c_iter->startbit + NETLBL_CATMAP_SIZE; 111 rc = netlbl_catmap_setlong(catmap,
120 if (e_startbit >= c_endbit) { 112 offset,
121 c_iter->next 113 e_map,
122 = netlbl_secattr_catmap_alloc(GFP_ATOMIC); 114 GFP_ATOMIC);
123 if (c_iter->next == NULL) 115 if (rc != 0)
124 goto netlbl_export_failure; 116 goto netlbl_export_failure;
125 c_iter = c_iter->next;
126 c_iter->startbit
127 = e_startbit & ~(NETLBL_CATMAP_SIZE - 1);
128 } 117 }
129 delta = e_startbit - c_iter->startbit; 118 offset += EBITMAP_UNIT_SIZE;
130 cmap_idx = delta / NETLBL_CATMAP_MAPSIZE;
131 cmap_sft = delta % NETLBL_CATMAP_MAPSIZE;
132 c_iter->bitmap[cmap_idx]
133 |= e_iter->maps[i] << cmap_sft;
134 } 119 }
135 e_iter = e_iter->next; 120 e_iter = e_iter->next;
136 } 121 }
@@ -138,7 +123,7 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap,
138 return 0; 123 return 0;
139 124
140netlbl_export_failure: 125netlbl_export_failure:
141 netlbl_secattr_catmap_free(*catmap); 126 netlbl_catmap_free(*catmap);
142 return -ENOMEM; 127 return -ENOMEM;
143} 128}
144 129
@@ -153,58 +138,44 @@ netlbl_export_failure:
153 * 138 *
154 */ 139 */
155int ebitmap_netlbl_import(struct ebitmap *ebmap, 140int ebitmap_netlbl_import(struct ebitmap *ebmap,
156 struct netlbl_lsm_secattr_catmap *catmap) 141 struct netlbl_lsm_catmap *catmap)
157{ 142{
143 int rc;
158 struct ebitmap_node *e_iter = NULL; 144 struct ebitmap_node *e_iter = NULL;
159 struct ebitmap_node *emap_prev = NULL; 145 struct ebitmap_node *e_prev = NULL;
160 struct netlbl_lsm_secattr_catmap *c_iter = catmap; 146 u32 offset = 0, idx;
161 u32 c_idx, c_pos, e_idx, e_sft; 147 unsigned long bitmap;
162 148
163 /* NetLabel's NETLBL_CATMAP_MAPTYPE is defined as an array of u64, 149 for (;;) {
164 * however, it is not always compatible with an array of unsigned long 150 rc = netlbl_catmap_getlong(catmap, &offset, &bitmap);
165 * in ebitmap_node. 151 if (rc < 0)
166 * In addition, you should pay attention the following implementation 152 goto netlbl_import_failure;
167 * assumes unsigned long has a width equal with or less than 64-bit. 153 if (offset == (u32)-1)
168 */ 154 return 0;
169
170 do {
171 for (c_idx = 0; c_idx < NETLBL_CATMAP_MAPCNT; c_idx++) {
172 unsigned int delta;
173 u64 map = c_iter->bitmap[c_idx];
174
175 if (!map)
176 continue;
177 155
178 c_pos = c_iter->startbit 156 if (e_iter == NULL ||
179 + c_idx * NETLBL_CATMAP_MAPSIZE; 157 offset >= e_iter->startbit + EBITMAP_SIZE) {
180 if (!e_iter 158 e_prev = e_iter;
181 || c_pos >= e_iter->startbit + EBITMAP_SIZE) { 159 e_iter = kzalloc(sizeof(*e_iter), GFP_ATOMIC);
182 e_iter = kzalloc(sizeof(*e_iter), GFP_ATOMIC); 160 if (e_iter == NULL)
183 if (!e_iter) 161 goto netlbl_import_failure;
184 goto netlbl_import_failure; 162 e_iter->startbit = offset & ~(EBITMAP_SIZE - 1);
185 e_iter->startbit 163 if (e_prev == NULL)
186 = c_pos - (c_pos % EBITMAP_SIZE); 164 ebmap->node = e_iter;
187 if (emap_prev == NULL) 165 else
188 ebmap->node = e_iter; 166 e_prev->next = e_iter;
189 else 167 ebmap->highbit = e_iter->startbit + EBITMAP_SIZE;
190 emap_prev->next = e_iter;
191 emap_prev = e_iter;
192 }
193 delta = c_pos - e_iter->startbit;
194 e_idx = delta / EBITMAP_UNIT_SIZE;
195 e_sft = delta % EBITMAP_UNIT_SIZE;
196 while (map) {
197 e_iter->maps[e_idx++] |= map & (-1UL);
198 map = EBITMAP_SHIFT_UNIT_SIZE(map);
199 }
200 } 168 }
201 c_iter = c_iter->next;
202 } while (c_iter);
203 if (e_iter != NULL)
204 ebmap->highbit = e_iter->startbit + EBITMAP_SIZE;
205 else
206 ebitmap_destroy(ebmap);
207 169
170 /* offset will always be aligned to an unsigned long */
171 idx = EBITMAP_NODE_INDEX(e_iter, offset);
172 e_iter->maps[idx] = bitmap;
173
174 /* next */
175 offset += EBITMAP_UNIT_SIZE;
176 }
177
178 /* NOTE: we should never reach this return */
208 return 0; 179 return 0;
209 180
210netlbl_import_failure: 181netlbl_import_failure:
diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h
index 712c8a7b8e8b..9637b8c71085 100644
--- a/security/selinux/ss/ebitmap.h
+++ b/security/selinux/ss/ebitmap.h
@@ -132,17 +132,17 @@ int ebitmap_write(struct ebitmap *e, void *fp);
132 132
133#ifdef CONFIG_NETLABEL 133#ifdef CONFIG_NETLABEL
134int ebitmap_netlbl_export(struct ebitmap *ebmap, 134int ebitmap_netlbl_export(struct ebitmap *ebmap,
135 struct netlbl_lsm_secattr_catmap **catmap); 135 struct netlbl_lsm_catmap **catmap);
136int ebitmap_netlbl_import(struct ebitmap *ebmap, 136int ebitmap_netlbl_import(struct ebitmap *ebmap,
137 struct netlbl_lsm_secattr_catmap *catmap); 137 struct netlbl_lsm_catmap *catmap);
138#else 138#else
139static inline int ebitmap_netlbl_export(struct ebitmap *ebmap, 139static inline int ebitmap_netlbl_export(struct ebitmap *ebmap,
140 struct netlbl_lsm_secattr_catmap **catmap) 140 struct netlbl_lsm_catmap **catmap)
141{ 141{
142 return -ENOMEM; 142 return -ENOMEM;
143} 143}
144static inline int ebitmap_netlbl_import(struct ebitmap *ebmap, 144static inline int ebitmap_netlbl_import(struct ebitmap *ebmap,
145 struct netlbl_lsm_secattr_catmap *catmap) 145 struct netlbl_lsm_catmap *catmap)
146{ 146{
147 return -ENOMEM; 147 return -ENOMEM;
148} 148}
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index c062e9467b62..f97d0842e621 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -457,19 +457,16 @@ int smk_netlbl_mls(int level, char *catset, struct netlbl_lsm_secattr *sap,
457 457
458 sap->flags |= NETLBL_SECATTR_MLS_CAT; 458 sap->flags |= NETLBL_SECATTR_MLS_CAT;
459 sap->attr.mls.lvl = level; 459 sap->attr.mls.lvl = level;
460 sap->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC); 460 sap->attr.mls.cat = NULL;
461 if (!sap->attr.mls.cat)
462 return -ENOMEM;
463 sap->attr.mls.cat->startbit = 0;
464 461
465 for (cat = 1, cp = catset, byte = 0; byte < len; cp++, byte++) 462 for (cat = 1, cp = catset, byte = 0; byte < len; cp++, byte++)
466 for (m = 0x80; m != 0; m >>= 1, cat++) { 463 for (m = 0x80; m != 0; m >>= 1, cat++) {
467 if ((m & *cp) == 0) 464 if ((m & *cp) == 0)
468 continue; 465 continue;
469 rc = netlbl_secattr_catmap_setbit(sap->attr.mls.cat, 466 rc = netlbl_catmap_setbit(&sap->attr.mls.cat,
470 cat, GFP_ATOMIC); 467 cat, GFP_ATOMIC);
471 if (rc < 0) { 468 if (rc < 0) {
472 netlbl_secattr_catmap_free(sap->attr.mls.cat); 469 netlbl_catmap_free(sap->attr.mls.cat);
473 return rc; 470 return rc;
474 } 471 }
475 } 472 }
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index f2c30801ce41..e6ab307ce86e 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -3209,9 +3209,9 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap,
3209 break; 3209 break;
3210 } 3210 }
3211 for (acat = -1, kcat = -1; acat == kcat; ) { 3211 for (acat = -1, kcat = -1; acat == kcat; ) {
3212 acat = netlbl_secattr_catmap_walk( 3212 acat = netlbl_catmap_walk(sap->attr.mls.cat,
3213 sap->attr.mls.cat, acat + 1); 3213 acat + 1);
3214 kcat = netlbl_secattr_catmap_walk( 3214 kcat = netlbl_catmap_walk(
3215 skp->smk_netlabel.attr.mls.cat, 3215 skp->smk_netlabel.attr.mls.cat,
3216 kcat + 1); 3216 kcat + 1);
3217 if (acat < 0 || kcat < 0) 3217 if (acat < 0 || kcat < 0)
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 32b248820840..3c720ff10591 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -787,7 +787,7 @@ static int cipso_seq_show(struct seq_file *s, void *v)
787 struct list_head *list = v; 787 struct list_head *list = v;
788 struct smack_known *skp = 788 struct smack_known *skp =
789 list_entry(list, struct smack_known, list); 789 list_entry(list, struct smack_known, list);
790 struct netlbl_lsm_secattr_catmap *cmp = skp->smk_netlabel.attr.mls.cat; 790 struct netlbl_lsm_catmap *cmp = skp->smk_netlabel.attr.mls.cat;
791 char sep = '/'; 791 char sep = '/';
792 int i; 792 int i;
793 793
@@ -804,8 +804,8 @@ static int cipso_seq_show(struct seq_file *s, void *v)
804 804
805 seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl); 805 seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl);
806 806
807 for (i = netlbl_secattr_catmap_walk(cmp, 0); i >= 0; 807 for (i = netlbl_catmap_walk(cmp, 0); i >= 0;
808 i = netlbl_secattr_catmap_walk(cmp, i + 1)) { 808 i = netlbl_catmap_walk(cmp, i + 1)) {
809 seq_printf(s, "%c%d", sep, i); 809 seq_printf(s, "%c%d", sep, i);
810 sep = ','; 810 sep = ',';
811 } 811 }
@@ -926,7 +926,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
926 926
927 rc = smk_netlbl_mls(maplevel, mapcatset, &ncats, SMK_CIPSOLEN); 927 rc = smk_netlbl_mls(maplevel, mapcatset, &ncats, SMK_CIPSOLEN);
928 if (rc >= 0) { 928 if (rc >= 0) {
929 netlbl_secattr_catmap_free(skp->smk_netlabel.attr.mls.cat); 929 netlbl_catmap_free(skp->smk_netlabel.attr.mls.cat);
930 skp->smk_netlabel.attr.mls.cat = ncats.attr.mls.cat; 930 skp->smk_netlabel.attr.mls.cat = ncats.attr.mls.cat;
931 skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl; 931 skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl;
932 rc = count; 932 rc = count;
@@ -976,14 +976,14 @@ static int cipso2_seq_show(struct seq_file *s, void *v)
976 struct list_head *list = v; 976 struct list_head *list = v;
977 struct smack_known *skp = 977 struct smack_known *skp =
978 list_entry(list, struct smack_known, list); 978 list_entry(list, struct smack_known, list);
979 struct netlbl_lsm_secattr_catmap *cmp = skp->smk_netlabel.attr.mls.cat; 979 struct netlbl_lsm_catmap *cmp = skp->smk_netlabel.attr.mls.cat;
980 char sep = '/'; 980 char sep = '/';
981 int i; 981 int i;
982 982
983 seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl); 983 seq_printf(s, "%s %3d", skp->smk_known, skp->smk_netlabel.attr.mls.lvl);
984 984
985 for (i = netlbl_secattr_catmap_walk(cmp, 0); i >= 0; 985 for (i = netlbl_catmap_walk(cmp, 0); i >= 0;
986 i = netlbl_secattr_catmap_walk(cmp, i + 1)) { 986 i = netlbl_catmap_walk(cmp, i + 1)) {
987 seq_printf(s, "%c%d", sep, i); 987 seq_printf(s, "%c%d", sep, i);
988 sep = ','; 988 sep = ',';
989 } 989 }