diff options
Diffstat (limited to 'net/ipv4/cipso_ipv4.c')
-rw-r--r-- | net/ipv4/cipso_ipv4.c | 86 |
1 files changed, 65 insertions, 21 deletions
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index e52799047a5f..6bb2635b5ded 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/spinlock.h> | 38 | #include <linux/spinlock.h> |
39 | #include <linux/string.h> | 39 | #include <linux/string.h> |
40 | #include <linux/jhash.h> | 40 | #include <linux/jhash.h> |
41 | #include <linux/audit.h> | ||
41 | #include <net/ip.h> | 42 | #include <net/ip.h> |
42 | #include <net/icmp.h> | 43 | #include <net/icmp.h> |
43 | #include <net/tcp.h> | 44 | #include <net/tcp.h> |
@@ -449,6 +450,7 @@ static struct cipso_v4_doi *cipso_v4_doi_search(u32 doi) | |||
449 | /** | 450 | /** |
450 | * cipso_v4_doi_add - Add a new DOI to the CIPSO protocol engine | 451 | * cipso_v4_doi_add - Add a new DOI to the CIPSO protocol engine |
451 | * @doi_def: the DOI structure | 452 | * @doi_def: the DOI structure |
453 | * @audit_info: NetLabel audit information | ||
452 | * | 454 | * |
453 | * Description: | 455 | * Description: |
454 | * The caller defines a new DOI for use by the CIPSO engine and calls this | 456 | * The caller defines a new DOI for use by the CIPSO engine and calls this |
@@ -458,50 +460,78 @@ static struct cipso_v4_doi *cipso_v4_doi_search(u32 doi) | |||
458 | * zero on success and non-zero on failure. | 460 | * zero on success and non-zero on failure. |
459 | * | 461 | * |
460 | */ | 462 | */ |
461 | int cipso_v4_doi_add(struct cipso_v4_doi *doi_def) | 463 | int cipso_v4_doi_add(struct cipso_v4_doi *doi_def, |
464 | struct netlbl_audit *audit_info) | ||
462 | { | 465 | { |
466 | int ret_val = -EINVAL; | ||
463 | u32 iter; | 467 | u32 iter; |
468 | u32 doi; | ||
469 | u32 doi_type; | ||
470 | struct audit_buffer *audit_buf; | ||
471 | |||
472 | doi = doi_def->doi; | ||
473 | doi_type = doi_def->type; | ||
464 | 474 | ||
465 | if (doi_def == NULL || doi_def->doi == CIPSO_V4_DOI_UNKNOWN) | 475 | if (doi_def == NULL || doi_def->doi == CIPSO_V4_DOI_UNKNOWN) |
466 | return -EINVAL; | 476 | goto doi_add_return; |
467 | for (iter = 0; iter < CIPSO_V4_TAG_MAXCNT; iter++) { | 477 | for (iter = 0; iter < CIPSO_V4_TAG_MAXCNT; iter++) { |
468 | switch (doi_def->tags[iter]) { | 478 | switch (doi_def->tags[iter]) { |
469 | case CIPSO_V4_TAG_RBITMAP: | 479 | case CIPSO_V4_TAG_RBITMAP: |
470 | break; | 480 | break; |
471 | case CIPSO_V4_TAG_RANGE: | 481 | case CIPSO_V4_TAG_RANGE: |
472 | if (doi_def->type != CIPSO_V4_MAP_PASS) | ||
473 | return -EINVAL; | ||
474 | break; | ||
475 | case CIPSO_V4_TAG_INVALID: | ||
476 | if (iter == 0) | ||
477 | return -EINVAL; | ||
478 | break; | ||
479 | case CIPSO_V4_TAG_ENUM: | 482 | case CIPSO_V4_TAG_ENUM: |
480 | if (doi_def->type != CIPSO_V4_MAP_PASS) | 483 | if (doi_def->type != CIPSO_V4_MAP_PASS) |
481 | return -EINVAL; | 484 | goto doi_add_return; |
482 | break; | 485 | break; |
483 | case CIPSO_V4_TAG_LOCAL: | 486 | case CIPSO_V4_TAG_LOCAL: |
484 | if (doi_def->type != CIPSO_V4_MAP_LOCAL) | 487 | if (doi_def->type != CIPSO_V4_MAP_LOCAL) |
485 | return -EINVAL; | 488 | goto doi_add_return; |
489 | break; | ||
490 | case CIPSO_V4_TAG_INVALID: | ||
491 | if (iter == 0) | ||
492 | goto doi_add_return; | ||
486 | break; | 493 | break; |
487 | default: | 494 | default: |
488 | return -EINVAL; | 495 | goto doi_add_return; |
489 | } | 496 | } |
490 | } | 497 | } |
491 | 498 | ||
492 | atomic_set(&doi_def->refcount, 1); | 499 | atomic_set(&doi_def->refcount, 1); |
493 | 500 | ||
494 | spin_lock(&cipso_v4_doi_list_lock); | 501 | spin_lock(&cipso_v4_doi_list_lock); |
495 | if (cipso_v4_doi_search(doi_def->doi) != NULL) | 502 | if (cipso_v4_doi_search(doi_def->doi) != NULL) { |
496 | goto doi_add_failure; | 503 | spin_unlock(&cipso_v4_doi_list_lock); |
504 | ret_val = -EEXIST; | ||
505 | goto doi_add_return; | ||
506 | } | ||
497 | list_add_tail_rcu(&doi_def->list, &cipso_v4_doi_list); | 507 | list_add_tail_rcu(&doi_def->list, &cipso_v4_doi_list); |
498 | spin_unlock(&cipso_v4_doi_list_lock); | 508 | spin_unlock(&cipso_v4_doi_list_lock); |
509 | ret_val = 0; | ||
499 | 510 | ||
500 | return 0; | 511 | doi_add_return: |
512 | audit_buf = netlbl_audit_start(AUDIT_MAC_CIPSOV4_ADD, audit_info); | ||
513 | if (audit_buf != NULL) { | ||
514 | const char *type_str; | ||
515 | switch (doi_type) { | ||
516 | case CIPSO_V4_MAP_TRANS: | ||
517 | type_str = "trans"; | ||
518 | break; | ||
519 | case CIPSO_V4_MAP_PASS: | ||
520 | type_str = "pass"; | ||
521 | break; | ||
522 | case CIPSO_V4_MAP_LOCAL: | ||
523 | type_str = "local"; | ||
524 | break; | ||
525 | default: | ||
526 | type_str = "(unknown)"; | ||
527 | } | ||
528 | audit_log_format(audit_buf, | ||
529 | " cipso_doi=%u cipso_type=%s res=%u", | ||
530 | doi, type_str, ret_val == 0 ? 1 : 0); | ||
531 | audit_log_end(audit_buf); | ||
532 | } | ||
501 | 533 | ||
502 | doi_add_failure: | 534 | return ret_val; |
503 | spin_unlock(&cipso_v4_doi_list_lock); | ||
504 | return -EEXIST; | ||
505 | } | 535 | } |
506 | 536 | ||
507 | /** | 537 | /** |
@@ -559,25 +589,39 @@ static void cipso_v4_doi_free_rcu(struct rcu_head *entry) | |||
559 | */ | 589 | */ |
560 | int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info) | 590 | int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info) |
561 | { | 591 | { |
592 | int ret_val; | ||
562 | struct cipso_v4_doi *doi_def; | 593 | struct cipso_v4_doi *doi_def; |
594 | struct audit_buffer *audit_buf; | ||
563 | 595 | ||
564 | spin_lock(&cipso_v4_doi_list_lock); | 596 | spin_lock(&cipso_v4_doi_list_lock); |
565 | doi_def = cipso_v4_doi_search(doi); | 597 | doi_def = cipso_v4_doi_search(doi); |
566 | if (doi_def == NULL) { | 598 | if (doi_def == NULL) { |
567 | spin_unlock(&cipso_v4_doi_list_lock); | 599 | spin_unlock(&cipso_v4_doi_list_lock); |
568 | return -ENOENT; | 600 | ret_val = -ENOENT; |
601 | goto doi_remove_return; | ||
569 | } | 602 | } |
570 | if (!atomic_dec_and_test(&doi_def->refcount)) { | 603 | if (!atomic_dec_and_test(&doi_def->refcount)) { |
571 | spin_unlock(&cipso_v4_doi_list_lock); | 604 | spin_unlock(&cipso_v4_doi_list_lock); |
572 | return -EBUSY; | 605 | ret_val = -EBUSY; |
606 | goto doi_remove_return; | ||
573 | } | 607 | } |
574 | list_del_rcu(&doi_def->list); | 608 | list_del_rcu(&doi_def->list); |
575 | spin_unlock(&cipso_v4_doi_list_lock); | 609 | spin_unlock(&cipso_v4_doi_list_lock); |
576 | 610 | ||
577 | cipso_v4_cache_invalidate(); | 611 | cipso_v4_cache_invalidate(); |
578 | call_rcu(&doi_def->rcu, cipso_v4_doi_free_rcu); | 612 | call_rcu(&doi_def->rcu, cipso_v4_doi_free_rcu); |
613 | ret_val = 0; | ||
614 | |||
615 | doi_remove_return: | ||
616 | audit_buf = netlbl_audit_start(AUDIT_MAC_CIPSOV4_DEL, audit_info); | ||
617 | if (audit_buf != NULL) { | ||
618 | audit_log_format(audit_buf, | ||
619 | " cipso_doi=%u res=%u", | ||
620 | doi, ret_val == 0 ? 1 : 0); | ||
621 | audit_log_end(audit_buf); | ||
622 | } | ||
579 | 623 | ||
580 | return 0; | 624 | return ret_val; |
581 | } | 625 | } |
582 | 626 | ||
583 | /** | 627 | /** |