aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/avtab.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss/avtab.c')
-rw-r--r--security/selinux/ss/avtab.c196
1 files changed, 126 insertions, 70 deletions
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
index f238c034c44..dde094feb20 100644
--- a/security/selinux/ss/avtab.c
+++ b/security/selinux/ss/avtab.c
@@ -58,6 +58,7 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat
58{ 58{
59 int hvalue; 59 int hvalue;
60 struct avtab_node *prev, *cur, *newnode; 60 struct avtab_node *prev, *cur, *newnode;
61 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
61 62
62 if (!h) 63 if (!h)
63 return -EINVAL; 64 return -EINVAL;
@@ -69,7 +70,7 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat
69 if (key->source_type == cur->key.source_type && 70 if (key->source_type == cur->key.source_type &&
70 key->target_type == cur->key.target_type && 71 key->target_type == cur->key.target_type &&
71 key->target_class == cur->key.target_class && 72 key->target_class == cur->key.target_class &&
72 (datum->specified & cur->datum.specified)) 73 (specified & cur->key.specified))
73 return -EEXIST; 74 return -EEXIST;
74 if (key->source_type < cur->key.source_type) 75 if (key->source_type < cur->key.source_type)
75 break; 76 break;
@@ -98,6 +99,7 @@ avtab_insert_nonunique(struct avtab * h, struct avtab_key * key, struct avtab_da
98{ 99{
99 int hvalue; 100 int hvalue;
100 struct avtab_node *prev, *cur, *newnode; 101 struct avtab_node *prev, *cur, *newnode;
102 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
101 103
102 if (!h) 104 if (!h)
103 return NULL; 105 return NULL;
@@ -108,7 +110,7 @@ avtab_insert_nonunique(struct avtab * h, struct avtab_key * key, struct avtab_da
108 if (key->source_type == cur->key.source_type && 110 if (key->source_type == cur->key.source_type &&
109 key->target_type == cur->key.target_type && 111 key->target_type == cur->key.target_type &&
110 key->target_class == cur->key.target_class && 112 key->target_class == cur->key.target_class &&
111 (datum->specified & cur->datum.specified)) 113 (specified & cur->key.specified))
112 break; 114 break;
113 if (key->source_type < cur->key.source_type) 115 if (key->source_type < cur->key.source_type)
114 break; 116 break;
@@ -125,10 +127,11 @@ avtab_insert_nonunique(struct avtab * h, struct avtab_key * key, struct avtab_da
125 return newnode; 127 return newnode;
126} 128}
127 129
128struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key, int specified) 130struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key)
129{ 131{
130 int hvalue; 132 int hvalue;
131 struct avtab_node *cur; 133 struct avtab_node *cur;
134 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
132 135
133 if (!h) 136 if (!h)
134 return NULL; 137 return NULL;
@@ -138,7 +141,7 @@ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key, int spe
138 if (key->source_type == cur->key.source_type && 141 if (key->source_type == cur->key.source_type &&
139 key->target_type == cur->key.target_type && 142 key->target_type == cur->key.target_type &&
140 key->target_class == cur->key.target_class && 143 key->target_class == cur->key.target_class &&
141 (specified & cur->datum.specified)) 144 (specified & cur->key.specified))
142 return &cur->datum; 145 return &cur->datum;
143 146
144 if (key->source_type < cur->key.source_type) 147 if (key->source_type < cur->key.source_type)
@@ -159,10 +162,11 @@ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key, int spe
159 * conjunction with avtab_search_next_node() 162 * conjunction with avtab_search_next_node()
160 */ 163 */
161struct avtab_node* 164struct avtab_node*
162avtab_search_node(struct avtab *h, struct avtab_key *key, int specified) 165avtab_search_node(struct avtab *h, struct avtab_key *key)
163{ 166{
164 int hvalue; 167 int hvalue;
165 struct avtab_node *cur; 168 struct avtab_node *cur;
169 u16 specified = key->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
166 170
167 if (!h) 171 if (!h)
168 return NULL; 172 return NULL;
@@ -172,7 +176,7 @@ avtab_search_node(struct avtab *h, struct avtab_key *key, int specified)
172 if (key->source_type == cur->key.source_type && 176 if (key->source_type == cur->key.source_type &&
173 key->target_type == cur->key.target_type && 177 key->target_type == cur->key.target_type &&
174 key->target_class == cur->key.target_class && 178 key->target_class == cur->key.target_class &&
175 (specified & cur->datum.specified)) 179 (specified & cur->key.specified))
176 return cur; 180 return cur;
177 181
178 if (key->source_type < cur->key.source_type) 182 if (key->source_type < cur->key.source_type)
@@ -196,11 +200,12 @@ avtab_search_node_next(struct avtab_node *node, int specified)
196 if (!node) 200 if (!node)
197 return NULL; 201 return NULL;
198 202
203 specified &= ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
199 for (cur = node->next; cur; cur = cur->next) { 204 for (cur = node->next; cur; cur = cur->next) {
200 if (node->key.source_type == cur->key.source_type && 205 if (node->key.source_type == cur->key.source_type &&
201 node->key.target_type == cur->key.target_type && 206 node->key.target_type == cur->key.target_type &&
202 node->key.target_class == cur->key.target_class && 207 node->key.target_class == cur->key.target_class &&
203 (specified & cur->datum.specified)) 208 (specified & cur->key.specified))
204 return cur; 209 return cur;
205 210
206 if (node->key.source_type < cur->key.source_type) 211 if (node->key.source_type < cur->key.source_type)
@@ -278,76 +283,129 @@ void avtab_hash_eval(struct avtab *h, char *tag)
278 max_chain_len); 283 max_chain_len);
279} 284}
280 285
281int avtab_read_item(void *fp, struct avtab_datum *avdatum, struct avtab_key *avkey) 286static uint16_t spec_order[] = {
287 AVTAB_ALLOWED,
288 AVTAB_AUDITDENY,
289 AVTAB_AUDITALLOW,
290 AVTAB_TRANSITION,
291 AVTAB_CHANGE,
292 AVTAB_MEMBER
293};
294
295int avtab_read_item(void *fp, u32 vers, struct avtab *a,
296 int (*insertf)(struct avtab *a, struct avtab_key *k,
297 struct avtab_datum *d, void *p),
298 void *p)
282{ 299{
283 u32 buf[7]; 300 __le16 buf16[4];
284 u32 items, items2; 301 u16 enabled;
285 int rc; 302 __le32 buf32[7];
303 u32 items, items2, val;
304 struct avtab_key key;
305 struct avtab_datum datum;
306 int i, rc;
307
308 memset(&key, 0, sizeof(struct avtab_key));
309 memset(&datum, 0, sizeof(struct avtab_datum));
310
311 if (vers < POLICYDB_VERSION_AVTAB) {
312 rc = next_entry(buf32, fp, sizeof(u32));
313 if (rc < 0) {
314 printk(KERN_ERR "security: avtab: truncated entry\n");
315 return -1;
316 }
317 items2 = le32_to_cpu(buf32[0]);
318 if (items2 > ARRAY_SIZE(buf32)) {
319 printk(KERN_ERR "security: avtab: entry overflow\n");
320 return -1;
286 321
287 memset(avkey, 0, sizeof(struct avtab_key)); 322 }
288 memset(avdatum, 0, sizeof(struct avtab_datum)); 323 rc = next_entry(buf32, fp, sizeof(u32)*items2);
324 if (rc < 0) {
325 printk(KERN_ERR "security: avtab: truncated entry\n");
326 return -1;
327 }
328 items = 0;
289 329
290 rc = next_entry(buf, fp, sizeof(u32)); 330 val = le32_to_cpu(buf32[items++]);
291 if (rc < 0) { 331 key.source_type = (u16)val;
292 printk(KERN_ERR "security: avtab: truncated entry\n"); 332 if (key.source_type != val) {
293 goto bad; 333 printk("security: avtab: truncated source type\n");
294 } 334 return -1;
295 items2 = le32_to_cpu(buf[0]); 335 }
296 if (items2 > ARRAY_SIZE(buf)) { 336 val = le32_to_cpu(buf32[items++]);
297 printk(KERN_ERR "security: avtab: entry overflow\n"); 337 key.target_type = (u16)val;
298 goto bad; 338 if (key.target_type != val) {
339 printk("security: avtab: truncated target type\n");
340 return -1;
341 }
342 val = le32_to_cpu(buf32[items++]);
343 key.target_class = (u16)val;
344 if (key.target_class != val) {
345 printk("security: avtab: truncated target class\n");
346 return -1;
347 }
348
349 val = le32_to_cpu(buf32[items++]);
350 enabled = (val & AVTAB_ENABLED_OLD) ? AVTAB_ENABLED : 0;
351
352 if (!(val & (AVTAB_AV | AVTAB_TYPE))) {
353 printk("security: avtab: null entry\n");
354 return -1;
355 }
356 if ((val & AVTAB_AV) &&
357 (val & AVTAB_TYPE)) {
358 printk("security: avtab: entry has both access vectors and types\n");
359 return -1;
360 }
361
362 for (i = 0; i < sizeof(spec_order)/sizeof(u16); i++) {
363 if (val & spec_order[i]) {
364 key.specified = spec_order[i] | enabled;
365 datum.data = le32_to_cpu(buf32[items++]);
366 rc = insertf(a, &key, &datum, p);
367 if (rc) return rc;
368 }
369 }
370
371 if (items != items2) {
372 printk("security: avtab: entry only had %d items, expected %d\n", items2, items);
373 return -1;
374 }
375 return 0;
299 } 376 }
300 rc = next_entry(buf, fp, sizeof(u32)*items2); 377
378 rc = next_entry(buf16, fp, sizeof(u16)*4);
301 if (rc < 0) { 379 if (rc < 0) {
302 printk(KERN_ERR "security: avtab: truncated entry\n"); 380 printk("security: avtab: truncated entry\n");
303 goto bad; 381 return -1;
304 } 382 }
383
305 items = 0; 384 items = 0;
306 avkey->source_type = le32_to_cpu(buf[items++]); 385 key.source_type = le16_to_cpu(buf16[items++]);
307 avkey->target_type = le32_to_cpu(buf[items++]); 386 key.target_type = le16_to_cpu(buf16[items++]);
308 avkey->target_class = le32_to_cpu(buf[items++]); 387 key.target_class = le16_to_cpu(buf16[items++]);
309 avdatum->specified = le32_to_cpu(buf[items++]); 388 key.specified = le16_to_cpu(buf16[items++]);
310 if (!(avdatum->specified & (AVTAB_AV | AVTAB_TYPE))) { 389
311 printk(KERN_ERR "security: avtab: null entry\n"); 390 rc = next_entry(buf32, fp, sizeof(u32));
312 goto bad; 391 if (rc < 0) {
313 } 392 printk("security: avtab: truncated entry\n");
314 if ((avdatum->specified & AVTAB_AV) && 393 return -1;
315 (avdatum->specified & AVTAB_TYPE)) {
316 printk(KERN_ERR "security: avtab: entry has both access vectors and types\n");
317 goto bad;
318 }
319 if (avdatum->specified & AVTAB_AV) {
320 if (avdatum->specified & AVTAB_ALLOWED)
321 avtab_allowed(avdatum) = le32_to_cpu(buf[items++]);
322 if (avdatum->specified & AVTAB_AUDITDENY)
323 avtab_auditdeny(avdatum) = le32_to_cpu(buf[items++]);
324 if (avdatum->specified & AVTAB_AUDITALLOW)
325 avtab_auditallow(avdatum) = le32_to_cpu(buf[items++]);
326 } else {
327 if (avdatum->specified & AVTAB_TRANSITION)
328 avtab_transition(avdatum) = le32_to_cpu(buf[items++]);
329 if (avdatum->specified & AVTAB_CHANGE)
330 avtab_change(avdatum) = le32_to_cpu(buf[items++]);
331 if (avdatum->specified & AVTAB_MEMBER)
332 avtab_member(avdatum) = le32_to_cpu(buf[items++]);
333 }
334 if (items != items2) {
335 printk(KERN_ERR "security: avtab: entry only had %d items, expected %d\n",
336 items2, items);
337 goto bad;
338 } 394 }
395 datum.data = le32_to_cpu(*buf32);
396 return insertf(a, &key, &datum, p);
397}
339 398
340 return 0; 399static int avtab_insertf(struct avtab *a, struct avtab_key *k,
341bad: 400 struct avtab_datum *d, void *p)
342 return -1; 401{
402 return avtab_insert(a, k, d);
343} 403}
344 404
345int avtab_read(struct avtab *a, void *fp, u32 config) 405int avtab_read(struct avtab *a, void *fp, u32 vers)
346{ 406{
347 int rc; 407 int rc;
348 struct avtab_key avkey; 408 __le32 buf[1];
349 struct avtab_datum avdatum;
350 u32 buf[1];
351 u32 nel, i; 409 u32 nel, i;
352 410
353 411
@@ -363,16 +421,14 @@ int avtab_read(struct avtab *a, void *fp, u32 config)
363 goto bad; 421 goto bad;
364 } 422 }
365 for (i = 0; i < nel; i++) { 423 for (i = 0; i < nel; i++) {
366 if (avtab_read_item(fp, &avdatum, &avkey)) { 424 rc = avtab_read_item(fp,vers, a, avtab_insertf, NULL);
367 rc = -EINVAL;
368 goto bad;
369 }
370 rc = avtab_insert(a, &avkey, &avdatum);
371 if (rc) { 425 if (rc) {
372 if (rc == -ENOMEM) 426 if (rc == -ENOMEM)
373 printk(KERN_ERR "security: avtab: out of memory\n"); 427 printk(KERN_ERR "security: avtab: out of memory\n");
374 if (rc == -EEXIST) 428 else if (rc == -EEXIST)
375 printk(KERN_ERR "security: avtab: duplicate entry\n"); 429 printk(KERN_ERR "security: avtab: duplicate entry\n");
430 else
431 rc = -EINVAL;
376 goto bad; 432 goto bad;
377 } 433 }
378 } 434 }