aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/conditional.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2005-09-06 18:47:31 -0400
committerSteve French <sfrench@us.ibm.com>2005-09-06 18:47:31 -0400
commitc08319a9d50b5c9cb4fdb33728bd16497cf4ddd3 (patch)
tree5fbec9030029da1ec387c18b85f26f19ee50da44 /security/selinux/ss/conditional.c
parentbfa0d75a1eee59f0577e3c1697ff570b77581a35 (diff)
parent4706df3d3c42af802597d82c8b1542c3d52eab23 (diff)
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'security/selinux/ss/conditional.c')
-rw-r--r--security/selinux/ss/conditional.c215
1 files changed, 121 insertions, 94 deletions
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index e2057f5a411a..daf288007460 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -100,18 +100,18 @@ int evaluate_cond_node(struct policydb *p, struct cond_node *node)
100 /* turn the rules on or off */ 100 /* turn the rules on or off */
101 for (cur = node->true_list; cur != NULL; cur = cur->next) { 101 for (cur = node->true_list; cur != NULL; cur = cur->next) {
102 if (new_state <= 0) { 102 if (new_state <= 0) {
103 cur->node->datum.specified &= ~AVTAB_ENABLED; 103 cur->node->key.specified &= ~AVTAB_ENABLED;
104 } else { 104 } else {
105 cur->node->datum.specified |= AVTAB_ENABLED; 105 cur->node->key.specified |= AVTAB_ENABLED;
106 } 106 }
107 } 107 }
108 108
109 for (cur = node->false_list; cur != NULL; cur = cur->next) { 109 for (cur = node->false_list; cur != NULL; cur = cur->next) {
110 /* -1 or 1 */ 110 /* -1 or 1 */
111 if (new_state) { 111 if (new_state) {
112 cur->node->datum.specified &= ~AVTAB_ENABLED; 112 cur->node->key.specified &= ~AVTAB_ENABLED;
113 } else { 113 } else {
114 cur->node->datum.specified |= AVTAB_ENABLED; 114 cur->node->key.specified |= AVTAB_ENABLED;
115 } 115 }
116 } 116 }
117 } 117 }
@@ -216,7 +216,8 @@ int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp)
216{ 216{
217 char *key = NULL; 217 char *key = NULL;
218 struct cond_bool_datum *booldatum; 218 struct cond_bool_datum *booldatum;
219 u32 buf[3], len; 219 __le32 buf[3];
220 u32 len;
220 int rc; 221 int rc;
221 222
222 booldatum = kmalloc(sizeof(struct cond_bool_datum), GFP_KERNEL); 223 booldatum = kmalloc(sizeof(struct cond_bool_datum), GFP_KERNEL);
@@ -252,104 +253,127 @@ err:
252 return -1; 253 return -1;
253} 254}
254 255
255static int cond_read_av_list(struct policydb *p, void *fp, struct cond_av_list **ret_list, 256struct cond_insertf_data
256 struct cond_av_list *other)
257{ 257{
258 struct cond_av_list *list, *last = NULL, *cur; 258 struct policydb *p;
259 struct avtab_key key; 259 struct cond_av_list *other;
260 struct avtab_datum datum; 260 struct cond_av_list *head;
261 struct cond_av_list *tail;
262};
263
264static int cond_insertf(struct avtab *a, struct avtab_key *k, struct avtab_datum *d, void *ptr)
265{
266 struct cond_insertf_data *data = ptr;
267 struct policydb *p = data->p;
268 struct cond_av_list *other = data->other, *list, *cur;
261 struct avtab_node *node_ptr; 269 struct avtab_node *node_ptr;
262 int rc;
263 u32 buf[1], i, len;
264 u8 found; 270 u8 found;
265 271
266 *ret_list = NULL;
267
268 len = 0;
269 rc = next_entry(buf, fp, sizeof buf);
270 if (rc < 0)
271 return -1;
272
273 len = le32_to_cpu(buf[0]);
274 if (len == 0) {
275 return 0;
276 }
277 272
278 for (i = 0; i < len; i++) { 273 /*
279 if (avtab_read_item(fp, &datum, &key)) 274 * For type rules we have to make certain there aren't any
275 * conflicting rules by searching the te_avtab and the
276 * cond_te_avtab.
277 */
278 if (k->specified & AVTAB_TYPE) {
279 if (avtab_search(&p->te_avtab, k)) {
280 printk("security: type rule already exists outside of a conditional.");
280 goto err; 281 goto err;
281 282 }
282 /* 283 /*
283 * For type rules we have to make certain there aren't any 284 * If we are reading the false list other will be a pointer to
284 * conflicting rules by searching the te_avtab and the 285 * the true list. We can have duplicate entries if there is only
285 * cond_te_avtab. 286 * 1 other entry and it is in our true list.
287 *
288 * If we are reading the true list (other == NULL) there shouldn't
289 * be any other entries.
286 */ 290 */
287 if (datum.specified & AVTAB_TYPE) { 291 if (other) {
288 if (avtab_search(&p->te_avtab, &key, AVTAB_TYPE)) { 292 node_ptr = avtab_search_node(&p->te_cond_avtab, k);
289 printk("security: type rule already exists outside of a conditional."); 293 if (node_ptr) {
290 goto err; 294 if (avtab_search_node_next(node_ptr, k->specified)) {
291 } 295 printk("security: too many conflicting type rules.");
292 /* 296 goto err;
293 * If we are reading the false list other will be a pointer to 297 }
294 * the true list. We can have duplicate entries if there is only 298 found = 0;
295 * 1 other entry and it is in our true list. 299 for (cur = other; cur != NULL; cur = cur->next) {
296 * 300 if (cur->node == node_ptr) {
297 * If we are reading the true list (other == NULL) there shouldn't 301 found = 1;
298 * be any other entries. 302 break;
299 */
300 if (other) {
301 node_ptr = avtab_search_node(&p->te_cond_avtab, &key, AVTAB_TYPE);
302 if (node_ptr) {
303 if (avtab_search_node_next(node_ptr, AVTAB_TYPE)) {
304 printk("security: too many conflicting type rules.");
305 goto err;
306 }
307 found = 0;
308 for (cur = other; cur != NULL; cur = cur->next) {
309 if (cur->node == node_ptr) {
310 found = 1;
311 break;
312 }
313 }
314 if (!found) {
315 printk("security: conflicting type rules.");
316 goto err;
317 } 303 }
318 } 304 }
319 } else { 305 if (!found) {
320 if (avtab_search(&p->te_cond_avtab, &key, AVTAB_TYPE)) { 306 printk("security: conflicting type rules.\n");
321 printk("security: conflicting type rules when adding type rule for true.");
322 goto err; 307 goto err;
323 } 308 }
324 } 309 }
310 } else {
311 if (avtab_search(&p->te_cond_avtab, k)) {
312 printk("security: conflicting type rules when adding type rule for true.\n");
313 goto err;
314 }
325 } 315 }
326 node_ptr = avtab_insert_nonunique(&p->te_cond_avtab, &key, &datum); 316 }
327 if (!node_ptr) {
328 printk("security: could not insert rule.");
329 goto err;
330 }
331
332 list = kmalloc(sizeof(struct cond_av_list), GFP_KERNEL);
333 if (!list)
334 goto err;
335 memset(list, 0, sizeof(struct cond_av_list));
336
337 list->node = node_ptr;
338 if (i == 0)
339 *ret_list = list;
340 else
341 last->next = list;
342 last = list;
343 317
318 node_ptr = avtab_insert_nonunique(&p->te_cond_avtab, k, d);
319 if (!node_ptr) {
320 printk("security: could not insert rule.");
321 goto err;
344 } 322 }
345 323
324 list = kmalloc(sizeof(struct cond_av_list), GFP_KERNEL);
325 if (!list)
326 goto err;
327 memset(list, 0, sizeof(*list));
328
329 list->node = node_ptr;
330 if (!data->head)
331 data->head = list;
332 else
333 data->tail->next = list;
334 data->tail = list;
346 return 0; 335 return 0;
336
347err: 337err:
348 cond_av_list_destroy(*ret_list); 338 cond_av_list_destroy(data->head);
349 *ret_list = NULL; 339 data->head = NULL;
350 return -1; 340 return -1;
351} 341}
352 342
343static int cond_read_av_list(struct policydb *p, void *fp, struct cond_av_list **ret_list, struct cond_av_list *other)
344{
345 int i, rc;
346 __le32 buf[1];
347 u32 len;
348 struct cond_insertf_data data;
349
350 *ret_list = NULL;
351
352 len = 0;
353 rc = next_entry(buf, fp, sizeof(u32));
354 if (rc < 0)
355 return -1;
356
357 len = le32_to_cpu(buf[0]);
358 if (len == 0) {
359 return 0;
360 }
361
362 data.p = p;
363 data.other = other;
364 data.head = NULL;
365 data.tail = NULL;
366 for (i = 0; i < len; i++) {
367 rc = avtab_read_item(fp, p->policyvers, &p->te_cond_avtab, cond_insertf, &data);
368 if (rc)
369 return rc;
370
371 }
372
373 *ret_list = data.head;
374 return 0;
375}
376
353static int expr_isvalid(struct policydb *p, struct cond_expr *expr) 377static int expr_isvalid(struct policydb *p, struct cond_expr *expr)
354{ 378{
355 if (expr->expr_type <= 0 || expr->expr_type > COND_LAST) { 379 if (expr->expr_type <= 0 || expr->expr_type > COND_LAST) {
@@ -366,7 +390,8 @@ static int expr_isvalid(struct policydb *p, struct cond_expr *expr)
366 390
367static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp) 391static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp)
368{ 392{
369 u32 buf[2], len, i; 393 __le32 buf[2];
394 u32 len, i;
370 int rc; 395 int rc;
371 struct cond_expr *expr = NULL, *last = NULL; 396 struct cond_expr *expr = NULL, *last = NULL;
372 397
@@ -424,7 +449,8 @@ err:
424int cond_read_list(struct policydb *p, void *fp) 449int cond_read_list(struct policydb *p, void *fp)
425{ 450{
426 struct cond_node *node, *last = NULL; 451 struct cond_node *node, *last = NULL;
427 u32 buf[1], i, len; 452 __le32 buf[1];
453 u32 i, len;
428 int rc; 454 int rc;
429 455
430 rc = next_entry(buf, fp, sizeof buf); 456 rc = next_entry(buf, fp, sizeof buf);
@@ -452,6 +478,7 @@ int cond_read_list(struct policydb *p, void *fp)
452 return 0; 478 return 0;
453err: 479err:
454 cond_list_destroy(p->cond_list); 480 cond_list_destroy(p->cond_list);
481 p->cond_list = NULL;
455 return -1; 482 return -1;
456} 483}
457 484
@@ -465,22 +492,22 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key, struct av_decisi
465 if(!ctab || !key || !avd) 492 if(!ctab || !key || !avd)
466 return; 493 return;
467 494
468 for(node = avtab_search_node(ctab, key, AVTAB_AV); node != NULL; 495 for(node = avtab_search_node(ctab, key); node != NULL;
469 node = avtab_search_node_next(node, AVTAB_AV)) { 496 node = avtab_search_node_next(node, key->specified)) {
470 if ( (__u32) (AVTAB_ALLOWED|AVTAB_ENABLED) == 497 if ( (u16) (AVTAB_ALLOWED|AVTAB_ENABLED) ==
471 (node->datum.specified & (AVTAB_ALLOWED|AVTAB_ENABLED))) 498 (node->key.specified & (AVTAB_ALLOWED|AVTAB_ENABLED)))
472 avd->allowed |= avtab_allowed(&node->datum); 499 avd->allowed |= node->datum.data;
473 if ( (__u32) (AVTAB_AUDITDENY|AVTAB_ENABLED) == 500 if ( (u16) (AVTAB_AUDITDENY|AVTAB_ENABLED) ==
474 (node->datum.specified & (AVTAB_AUDITDENY|AVTAB_ENABLED))) 501 (node->key.specified & (AVTAB_AUDITDENY|AVTAB_ENABLED)))
475 /* Since a '0' in an auditdeny mask represents a 502 /* Since a '0' in an auditdeny mask represents a
476 * permission we do NOT want to audit (dontaudit), we use 503 * permission we do NOT want to audit (dontaudit), we use
477 * the '&' operand to ensure that all '0's in the mask 504 * the '&' operand to ensure that all '0's in the mask
478 * are retained (much unlike the allow and auditallow cases). 505 * are retained (much unlike the allow and auditallow cases).
479 */ 506 */
480 avd->auditdeny &= avtab_auditdeny(&node->datum); 507 avd->auditdeny &= node->datum.data;
481 if ( (__u32) (AVTAB_AUDITALLOW|AVTAB_ENABLED) == 508 if ( (u16) (AVTAB_AUDITALLOW|AVTAB_ENABLED) ==
482 (node->datum.specified & (AVTAB_AUDITALLOW|AVTAB_ENABLED))) 509 (node->key.specified & (AVTAB_AUDITALLOW|AVTAB_ENABLED)))
483 avd->auditallow |= avtab_auditallow(&node->datum); 510 avd->auditallow |= node->datum.data;
484 } 511 }
485 return; 512 return;
486} 513}