aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/cipso_ipv4.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/cipso_ipv4.c')
-rw-r--r--net/ipv4/cipso_ipv4.c86
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 */
461int cipso_v4_doi_add(struct cipso_v4_doi *doi_def) 463int 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; 511doi_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
502doi_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 */
560int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info) 590int 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
615doi_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/**