diff options
Diffstat (limited to 'security/smack/smackfs.c')
| -rw-r--r-- | security/smack/smackfs.c | 115 |
1 files changed, 39 insertions, 76 deletions
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 6aceef518a41..5c32f36ff706 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c | |||
| @@ -102,9 +102,6 @@ static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT; | |||
| 102 | 102 | ||
| 103 | const char *smack_cipso_option = SMACK_CIPSO_OPTION; | 103 | const char *smack_cipso_option = SMACK_CIPSO_OPTION; |
| 104 | 104 | ||
| 105 | |||
| 106 | #define SEQ_READ_FINISHED ((loff_t)-1) | ||
| 107 | |||
| 108 | /* | 105 | /* |
| 109 | * Values for parsing cipso rules | 106 | * Values for parsing cipso rules |
| 110 | * SMK_DIGITLEN: Length of a digit field in a rule. | 107 | * SMK_DIGITLEN: Length of a digit field in a rule. |
| @@ -357,10 +354,12 @@ static ssize_t smk_write_load_list(struct file *file, const char __user *buf, | |||
| 357 | 354 | ||
| 358 | rc = count; | 355 | rc = count; |
| 359 | /* | 356 | /* |
| 357 | * If this is "load" as opposed to "load-self" and a new rule | ||
| 358 | * it needs to get added for reporting. | ||
| 360 | * smk_set_access returns true if there was already a rule | 359 | * smk_set_access returns true if there was already a rule |
| 361 | * for the subject/object pair, and false if it was new. | 360 | * for the subject/object pair, and false if it was new. |
| 362 | */ | 361 | */ |
| 363 | if (!smk_set_access(rule, rule_list, rule_lock)) { | 362 | if (load && !smk_set_access(rule, rule_list, rule_lock)) { |
| 364 | smlp = kzalloc(sizeof(*smlp), GFP_KERNEL); | 363 | smlp = kzalloc(sizeof(*smlp), GFP_KERNEL); |
| 365 | if (smlp != NULL) { | 364 | if (smlp != NULL) { |
| 366 | smlp->smk_rule = rule; | 365 | smlp->smk_rule = rule; |
| @@ -377,12 +376,12 @@ out: | |||
| 377 | return rc; | 376 | return rc; |
| 378 | } | 377 | } |
| 379 | 378 | ||
| 380 | |||
| 381 | /* | 379 | /* |
| 382 | * Seq_file read operations for /smack/load | 380 | * Core logic for smackfs seq list operations. |
| 383 | */ | 381 | */ |
| 384 | 382 | ||
| 385 | static void *load_seq_start(struct seq_file *s, loff_t *pos) | 383 | static void *smk_seq_start(struct seq_file *s, loff_t *pos, |
| 384 | struct list_head *head) | ||
| 386 | { | 385 | { |
| 387 | struct list_head *list; | 386 | struct list_head *list; |
| 388 | 387 | ||
| @@ -390,7 +389,7 @@ static void *load_seq_start(struct seq_file *s, loff_t *pos) | |||
| 390 | * This is 0 the first time through. | 389 | * This is 0 the first time through. |
| 391 | */ | 390 | */ |
| 392 | if (s->index == 0) | 391 | if (s->index == 0) |
| 393 | s->private = &smack_rule_list; | 392 | s->private = head; |
| 394 | 393 | ||
| 395 | if (s->private == NULL) | 394 | if (s->private == NULL) |
| 396 | return NULL; | 395 | return NULL; |
| @@ -404,11 +403,12 @@ static void *load_seq_start(struct seq_file *s, loff_t *pos) | |||
| 404 | return list; | 403 | return list; |
| 405 | } | 404 | } |
| 406 | 405 | ||
| 407 | static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos) | 406 | static void *smk_seq_next(struct seq_file *s, void *v, loff_t *pos, |
| 407 | struct list_head *head) | ||
| 408 | { | 408 | { |
| 409 | struct list_head *list = v; | 409 | struct list_head *list = v; |
| 410 | 410 | ||
| 411 | if (list_is_last(list, &smack_rule_list)) { | 411 | if (list_is_last(list, head)) { |
| 412 | s->private = NULL; | 412 | s->private = NULL; |
| 413 | return NULL; | 413 | return NULL; |
| 414 | } | 414 | } |
| @@ -416,6 +416,25 @@ static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos) | |||
| 416 | return list->next; | 416 | return list->next; |
| 417 | } | 417 | } |
| 418 | 418 | ||
| 419 | static void smk_seq_stop(struct seq_file *s, void *v) | ||
| 420 | { | ||
| 421 | /* No-op */ | ||
| 422 | } | ||
| 423 | |||
| 424 | /* | ||
| 425 | * Seq_file read operations for /smack/load | ||
| 426 | */ | ||
| 427 | |||
| 428 | static void *load_seq_start(struct seq_file *s, loff_t *pos) | ||
| 429 | { | ||
| 430 | return smk_seq_start(s, pos, &smack_rule_list); | ||
| 431 | } | ||
| 432 | |||
| 433 | static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos) | ||
| 434 | { | ||
| 435 | return smk_seq_next(s, v, pos, &smack_rule_list); | ||
| 436 | } | ||
| 437 | |||
| 419 | static int load_seq_show(struct seq_file *s, void *v) | 438 | static int load_seq_show(struct seq_file *s, void *v) |
| 420 | { | 439 | { |
| 421 | struct list_head *list = v; | 440 | struct list_head *list = v; |
| @@ -446,16 +465,11 @@ static int load_seq_show(struct seq_file *s, void *v) | |||
| 446 | return 0; | 465 | return 0; |
| 447 | } | 466 | } |
| 448 | 467 | ||
| 449 | static void load_seq_stop(struct seq_file *s, void *v) | ||
| 450 | { | ||
| 451 | /* No-op */ | ||
| 452 | } | ||
| 453 | |||
| 454 | static const struct seq_operations load_seq_ops = { | 468 | static const struct seq_operations load_seq_ops = { |
| 455 | .start = load_seq_start, | 469 | .start = load_seq_start, |
| 456 | .next = load_seq_next, | 470 | .next = load_seq_next, |
| 457 | .show = load_seq_show, | 471 | .show = load_seq_show, |
| 458 | .stop = load_seq_stop, | 472 | .stop = smk_seq_stop, |
| 459 | }; | 473 | }; |
| 460 | 474 | ||
| 461 | /** | 475 | /** |
| @@ -574,28 +588,12 @@ static void smk_unlbl_ambient(char *oldambient) | |||
| 574 | 588 | ||
| 575 | static void *cipso_seq_start(struct seq_file *s, loff_t *pos) | 589 | static void *cipso_seq_start(struct seq_file *s, loff_t *pos) |
| 576 | { | 590 | { |
| 577 | if (*pos == SEQ_READ_FINISHED) | 591 | return smk_seq_start(s, pos, &smack_known_list); |
| 578 | return NULL; | ||
| 579 | if (list_empty(&smack_known_list)) | ||
| 580 | return NULL; | ||
| 581 | |||
| 582 | return smack_known_list.next; | ||
| 583 | } | 592 | } |
| 584 | 593 | ||
| 585 | static void *cipso_seq_next(struct seq_file *s, void *v, loff_t *pos) | 594 | static void *cipso_seq_next(struct seq_file *s, void *v, loff_t *pos) |
| 586 | { | 595 | { |
| 587 | struct list_head *list = v; | 596 | return smk_seq_next(s, v, pos, &smack_known_list); |
| 588 | |||
| 589 | /* | ||
| 590 | * labels with no associated cipso value wont be printed | ||
| 591 | * in cipso_seq_show | ||
| 592 | */ | ||
| 593 | if (list_is_last(list, &smack_known_list)) { | ||
| 594 | *pos = SEQ_READ_FINISHED; | ||
| 595 | return NULL; | ||
| 596 | } | ||
| 597 | |||
| 598 | return list->next; | ||
| 599 | } | 597 | } |
| 600 | 598 | ||
| 601 | /* | 599 | /* |
| @@ -634,16 +632,11 @@ static int cipso_seq_show(struct seq_file *s, void *v) | |||
| 634 | return 0; | 632 | return 0; |
| 635 | } | 633 | } |
| 636 | 634 | ||
| 637 | static void cipso_seq_stop(struct seq_file *s, void *v) | ||
| 638 | { | ||
| 639 | /* No-op */ | ||
| 640 | } | ||
| 641 | |||
| 642 | static const struct seq_operations cipso_seq_ops = { | 635 | static const struct seq_operations cipso_seq_ops = { |
| 643 | .start = cipso_seq_start, | 636 | .start = cipso_seq_start, |
| 644 | .stop = cipso_seq_stop, | ||
| 645 | .next = cipso_seq_next, | 637 | .next = cipso_seq_next, |
| 646 | .show = cipso_seq_show, | 638 | .show = cipso_seq_show, |
| 639 | .stop = smk_seq_stop, | ||
| 647 | }; | 640 | }; |
| 648 | 641 | ||
| 649 | /** | 642 | /** |
| @@ -788,23 +781,12 @@ static const struct file_operations smk_cipso_ops = { | |||
| 788 | 781 | ||
| 789 | static void *netlbladdr_seq_start(struct seq_file *s, loff_t *pos) | 782 | static void *netlbladdr_seq_start(struct seq_file *s, loff_t *pos) |
| 790 | { | 783 | { |
| 791 | if (*pos == SEQ_READ_FINISHED) | 784 | return smk_seq_start(s, pos, &smk_netlbladdr_list); |
| 792 | return NULL; | ||
| 793 | if (list_empty(&smk_netlbladdr_list)) | ||
| 794 | return NULL; | ||
| 795 | return smk_netlbladdr_list.next; | ||
| 796 | } | 785 | } |
| 797 | 786 | ||
| 798 | static void *netlbladdr_seq_next(struct seq_file *s, void *v, loff_t *pos) | 787 | static void *netlbladdr_seq_next(struct seq_file *s, void *v, loff_t *pos) |
| 799 | { | 788 | { |
| 800 | struct list_head *list = v; | 789 | return smk_seq_next(s, v, pos, &smk_netlbladdr_list); |
| 801 | |||
| 802 | if (list_is_last(list, &smk_netlbladdr_list)) { | ||
| 803 | *pos = SEQ_READ_FINISHED; | ||
| 804 | return NULL; | ||
| 805 | } | ||
| 806 | |||
| 807 | return list->next; | ||
| 808 | } | 790 | } |
| 809 | #define BEBITS (sizeof(__be32) * 8) | 791 | #define BEBITS (sizeof(__be32) * 8) |
| 810 | 792 | ||
| @@ -828,16 +810,11 @@ static int netlbladdr_seq_show(struct seq_file *s, void *v) | |||
| 828 | return 0; | 810 | return 0; |
| 829 | } | 811 | } |
| 830 | 812 | ||
| 831 | static void netlbladdr_seq_stop(struct seq_file *s, void *v) | ||
| 832 | { | ||
| 833 | /* No-op */ | ||
| 834 | } | ||
| 835 | |||
| 836 | static const struct seq_operations netlbladdr_seq_ops = { | 813 | static const struct seq_operations netlbladdr_seq_ops = { |
| 837 | .start = netlbladdr_seq_start, | 814 | .start = netlbladdr_seq_start, |
| 838 | .stop = netlbladdr_seq_stop, | ||
| 839 | .next = netlbladdr_seq_next, | 815 | .next = netlbladdr_seq_next, |
| 840 | .show = netlbladdr_seq_show, | 816 | .show = netlbladdr_seq_show, |
| 817 | .stop = smk_seq_stop, | ||
| 841 | }; | 818 | }; |
| 842 | 819 | ||
| 843 | /** | 820 | /** |
| @@ -1405,23 +1382,14 @@ static void *load_self_seq_start(struct seq_file *s, loff_t *pos) | |||
| 1405 | { | 1382 | { |
| 1406 | struct task_smack *tsp = current_security(); | 1383 | struct task_smack *tsp = current_security(); |
| 1407 | 1384 | ||
| 1408 | if (*pos == SEQ_READ_FINISHED) | 1385 | return smk_seq_start(s, pos, &tsp->smk_rules); |
| 1409 | return NULL; | ||
| 1410 | if (list_empty(&tsp->smk_rules)) | ||
| 1411 | return NULL; | ||
| 1412 | return tsp->smk_rules.next; | ||
| 1413 | } | 1386 | } |
| 1414 | 1387 | ||
| 1415 | static void *load_self_seq_next(struct seq_file *s, void *v, loff_t *pos) | 1388 | static void *load_self_seq_next(struct seq_file *s, void *v, loff_t *pos) |
| 1416 | { | 1389 | { |
| 1417 | struct task_smack *tsp = current_security(); | 1390 | struct task_smack *tsp = current_security(); |
| 1418 | struct list_head *list = v; | ||
| 1419 | 1391 | ||
| 1420 | if (list_is_last(list, &tsp->smk_rules)) { | 1392 | return smk_seq_next(s, v, pos, &tsp->smk_rules); |
| 1421 | *pos = SEQ_READ_FINISHED; | ||
| 1422 | return NULL; | ||
| 1423 | } | ||
| 1424 | return list->next; | ||
| 1425 | } | 1393 | } |
| 1426 | 1394 | ||
| 1427 | static int load_self_seq_show(struct seq_file *s, void *v) | 1395 | static int load_self_seq_show(struct seq_file *s, void *v) |
| @@ -1453,16 +1421,11 @@ static int load_self_seq_show(struct seq_file *s, void *v) | |||
| 1453 | return 0; | 1421 | return 0; |
| 1454 | } | 1422 | } |
| 1455 | 1423 | ||
| 1456 | static void load_self_seq_stop(struct seq_file *s, void *v) | ||
| 1457 | { | ||
| 1458 | /* No-op */ | ||
| 1459 | } | ||
| 1460 | |||
| 1461 | static const struct seq_operations load_self_seq_ops = { | 1424 | static const struct seq_operations load_self_seq_ops = { |
| 1462 | .start = load_self_seq_start, | 1425 | .start = load_self_seq_start, |
| 1463 | .next = load_self_seq_next, | 1426 | .next = load_self_seq_next, |
| 1464 | .show = load_self_seq_show, | 1427 | .show = load_self_seq_show, |
| 1465 | .stop = load_self_seq_stop, | 1428 | .stop = smk_seq_stop, |
| 1466 | }; | 1429 | }; |
| 1467 | 1430 | ||
| 1468 | 1431 | ||
