aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPaul Moore <paul.moore@hp.com>2008-12-31 12:54:11 -0500
committerPaul Moore <paul.moore@hp.com>2008-12-31 12:54:11 -0500
commit6c2e8ac0953fccdd24dc6c4b9e08e8f1cd68cf07 (patch)
treec52e242ec5e5c2d131af2d9dbb038f78f724a74c /net
parent6a94cb73064c952255336cc57731904174b2c58f (diff)
netlabel: Update kernel configuration API
Update the NetLabel kernel API to expose the new features added in kernel releases 2.6.25 and 2.6.28: the static/fallback label functionality and network address based selectors. Signed-off-by: Paul Moore <paul.moore@hp.com>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/cipso_ipv4.c86
-rw-r--r--net/netlabel/netlabel_cipso_v4.c61
-rw-r--r--net/netlabel/netlabel_domainhash.c67
-rw-r--r--net/netlabel/netlabel_domainhash.h4
-rw-r--r--net/netlabel/netlabel_kapi.c347
-rw-r--r--net/netlabel/netlabel_unlabeled.c26
-rw-r--r--net/netlabel/netlabel_unlabeled.h15
7 files changed, 469 insertions, 137 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/**
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index fff32b70efa9..bf1ab1a6790d 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -130,6 +130,7 @@ static int netlbl_cipsov4_add_common(struct genl_info *info,
130/** 130/**
131 * netlbl_cipsov4_add_std - Adds a CIPSO V4 DOI definition 131 * netlbl_cipsov4_add_std - Adds a CIPSO V4 DOI definition
132 * @info: the Generic NETLINK info block 132 * @info: the Generic NETLINK info block
133 * @audit_info: NetLabel audit information
133 * 134 *
134 * Description: 135 * Description:
135 * Create a new CIPSO_V4_MAP_TRANS DOI definition based on the given ADD 136 * Create a new CIPSO_V4_MAP_TRANS DOI definition based on the given ADD
@@ -137,7 +138,8 @@ static int netlbl_cipsov4_add_common(struct genl_info *info,
137 * non-zero on error. 138 * non-zero on error.
138 * 139 *
139 */ 140 */
140static int netlbl_cipsov4_add_std(struct genl_info *info) 141static int netlbl_cipsov4_add_std(struct genl_info *info,
142 struct netlbl_audit *audit_info)
141{ 143{
142 int ret_val = -EINVAL; 144 int ret_val = -EINVAL;
143 struct cipso_v4_doi *doi_def = NULL; 145 struct cipso_v4_doi *doi_def = NULL;
@@ -316,7 +318,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
316 } 318 }
317 } 319 }
318 320
319 ret_val = cipso_v4_doi_add(doi_def); 321 ret_val = cipso_v4_doi_add(doi_def, audit_info);
320 if (ret_val != 0) 322 if (ret_val != 0)
321 goto add_std_failure; 323 goto add_std_failure;
322 return 0; 324 return 0;
@@ -330,6 +332,7 @@ add_std_failure:
330/** 332/**
331 * netlbl_cipsov4_add_pass - Adds a CIPSO V4 DOI definition 333 * netlbl_cipsov4_add_pass - Adds a CIPSO V4 DOI definition
332 * @info: the Generic NETLINK info block 334 * @info: the Generic NETLINK info block
335 * @audit_info: NetLabel audit information
333 * 336 *
334 * Description: 337 * Description:
335 * Create a new CIPSO_V4_MAP_PASS DOI definition based on the given ADD message 338 * Create a new CIPSO_V4_MAP_PASS DOI definition based on the given ADD message
@@ -337,7 +340,8 @@ add_std_failure:
337 * error. 340 * error.
338 * 341 *
339 */ 342 */
340static int netlbl_cipsov4_add_pass(struct genl_info *info) 343static int netlbl_cipsov4_add_pass(struct genl_info *info,
344 struct netlbl_audit *audit_info)
341{ 345{
342 int ret_val; 346 int ret_val;
343 struct cipso_v4_doi *doi_def = NULL; 347 struct cipso_v4_doi *doi_def = NULL;
@@ -354,7 +358,7 @@ static int netlbl_cipsov4_add_pass(struct genl_info *info)
354 if (ret_val != 0) 358 if (ret_val != 0)
355 goto add_pass_failure; 359 goto add_pass_failure;
356 360
357 ret_val = cipso_v4_doi_add(doi_def); 361 ret_val = cipso_v4_doi_add(doi_def, audit_info);
358 if (ret_val != 0) 362 if (ret_val != 0)
359 goto add_pass_failure; 363 goto add_pass_failure;
360 return 0; 364 return 0;
@@ -367,6 +371,7 @@ add_pass_failure:
367/** 371/**
368 * netlbl_cipsov4_add_local - Adds a CIPSO V4 DOI definition 372 * netlbl_cipsov4_add_local - Adds a CIPSO V4 DOI definition
369 * @info: the Generic NETLINK info block 373 * @info: the Generic NETLINK info block
374 * @audit_info: NetLabel audit information
370 * 375 *
371 * Description: 376 * Description:
372 * Create a new CIPSO_V4_MAP_LOCAL DOI definition based on the given ADD 377 * Create a new CIPSO_V4_MAP_LOCAL DOI definition based on the given ADD
@@ -374,7 +379,8 @@ add_pass_failure:
374 * non-zero on error. 379 * non-zero on error.
375 * 380 *
376 */ 381 */
377static int netlbl_cipsov4_add_local(struct genl_info *info) 382static int netlbl_cipsov4_add_local(struct genl_info *info,
383 struct netlbl_audit *audit_info)
378{ 384{
379 int ret_val; 385 int ret_val;
380 struct cipso_v4_doi *doi_def = NULL; 386 struct cipso_v4_doi *doi_def = NULL;
@@ -391,7 +397,7 @@ static int netlbl_cipsov4_add_local(struct genl_info *info)
391 if (ret_val != 0) 397 if (ret_val != 0)
392 goto add_local_failure; 398 goto add_local_failure;
393 399
394 ret_val = cipso_v4_doi_add(doi_def); 400 ret_val = cipso_v4_doi_add(doi_def, audit_info);
395 if (ret_val != 0) 401 if (ret_val != 0)
396 goto add_local_failure; 402 goto add_local_failure;
397 return 0; 403 return 0;
@@ -415,48 +421,31 @@ static int netlbl_cipsov4_add(struct sk_buff *skb, struct genl_info *info)
415 421
416{ 422{
417 int ret_val = -EINVAL; 423 int ret_val = -EINVAL;
418 u32 type;
419 u32 doi;
420 const char *type_str = "(unknown)"; 424 const char *type_str = "(unknown)";
421 struct audit_buffer *audit_buf;
422 struct netlbl_audit audit_info; 425 struct netlbl_audit audit_info;
423 426
424 if (!info->attrs[NLBL_CIPSOV4_A_DOI] || 427 if (!info->attrs[NLBL_CIPSOV4_A_DOI] ||
425 !info->attrs[NLBL_CIPSOV4_A_MTYPE]) 428 !info->attrs[NLBL_CIPSOV4_A_MTYPE])
426 return -EINVAL; 429 return -EINVAL;
427 430
428 doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
429 netlbl_netlink_auditinfo(skb, &audit_info); 431 netlbl_netlink_auditinfo(skb, &audit_info);
430 432 switch (nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE])) {
431 type = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE]);
432 switch (type) {
433 case CIPSO_V4_MAP_TRANS: 433 case CIPSO_V4_MAP_TRANS:
434 type_str = "trans"; 434 type_str = "trans";
435 ret_val = netlbl_cipsov4_add_std(info); 435 ret_val = netlbl_cipsov4_add_std(info, &audit_info);
436 break; 436 break;
437 case CIPSO_V4_MAP_PASS: 437 case CIPSO_V4_MAP_PASS:
438 type_str = "pass"; 438 type_str = "pass";
439 ret_val = netlbl_cipsov4_add_pass(info); 439 ret_val = netlbl_cipsov4_add_pass(info, &audit_info);
440 break; 440 break;
441 case CIPSO_V4_MAP_LOCAL: 441 case CIPSO_V4_MAP_LOCAL:
442 type_str = "local"; 442 type_str = "local";
443 ret_val = netlbl_cipsov4_add_local(info); 443 ret_val = netlbl_cipsov4_add_local(info, &audit_info);
444 break; 444 break;
445 } 445 }
446 if (ret_val == 0) 446 if (ret_val == 0)
447 atomic_inc(&netlabel_mgmt_protocount); 447 atomic_inc(&netlabel_mgmt_protocount);
448 448
449 audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD,
450 &audit_info);
451 if (audit_buf != NULL) {
452 audit_log_format(audit_buf,
453 " cipso_doi=%u cipso_type=%s res=%u",
454 doi,
455 type_str,
456 ret_val == 0 ? 1 : 0);
457 audit_log_end(audit_buf);
458 }
459
460 return ret_val; 449 return ret_val;
461} 450}
462 451
@@ -725,9 +714,7 @@ static int netlbl_cipsov4_remove_cb(struct netlbl_dom_map *entry, void *arg)
725static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info) 714static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
726{ 715{
727 int ret_val = -EINVAL; 716 int ret_val = -EINVAL;
728 u32 doi = 0;
729 struct netlbl_domhsh_walk_arg cb_arg; 717 struct netlbl_domhsh_walk_arg cb_arg;
730 struct audit_buffer *audit_buf;
731 struct netlbl_audit audit_info; 718 struct netlbl_audit audit_info;
732 u32 skip_bkt = 0; 719 u32 skip_bkt = 0;
733 u32 skip_chain = 0; 720 u32 skip_chain = 0;
@@ -735,29 +722,17 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
735 if (!info->attrs[NLBL_CIPSOV4_A_DOI]) 722 if (!info->attrs[NLBL_CIPSOV4_A_DOI])
736 return -EINVAL; 723 return -EINVAL;
737 724
738 doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
739 netlbl_netlink_auditinfo(skb, &audit_info); 725 netlbl_netlink_auditinfo(skb, &audit_info);
740 726 cb_arg.doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
741 cb_arg.doi = doi;
742 cb_arg.audit_info = &audit_info; 727 cb_arg.audit_info = &audit_info;
743 ret_val = netlbl_domhsh_walk(&skip_bkt, &skip_chain, 728 ret_val = netlbl_domhsh_walk(&skip_bkt, &skip_chain,
744 netlbl_cipsov4_remove_cb, &cb_arg); 729 netlbl_cipsov4_remove_cb, &cb_arg);
745 if (ret_val == 0 || ret_val == -ENOENT) { 730 if (ret_val == 0 || ret_val == -ENOENT) {
746 ret_val = cipso_v4_doi_remove(doi, &audit_info); 731 ret_val = cipso_v4_doi_remove(cb_arg.doi, &audit_info);
747 if (ret_val == 0) 732 if (ret_val == 0)
748 atomic_dec(&netlabel_mgmt_protocount); 733 atomic_dec(&netlabel_mgmt_protocount);
749 } 734 }
750 735
751 audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL,
752 &audit_info);
753 if (audit_buf != NULL) {
754 audit_log_format(audit_buf,
755 " cipso_doi=%u res=%u",
756 doi,
757 ret_val == 0 ? 1 : 0);
758 audit_log_end(audit_buf);
759 }
760
761 return ret_val; 736 return ret_val;
762} 737}
763 738
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c
index 5fadf10e5ddf..7a10bbe02c13 100644
--- a/net/netlabel/netlabel_domainhash.c
+++ b/net/netlabel/netlabel_domainhash.c
@@ -483,6 +483,73 @@ int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry,
483} 483}
484 484
485/** 485/**
486 * netlbl_domhsh_remove_af4 - Removes an address selector entry
487 * @domain: the domain
488 * @addr: IPv4 address
489 * @mask: IPv4 address mask
490 * @audit_info: NetLabel audit information
491 *
492 * Description:
493 * Removes an individual address selector from a domain mapping and potentially
494 * the entire mapping if it is empty. Returns zero on success, negative values
495 * on failure.
496 *
497 */
498int netlbl_domhsh_remove_af4(const char *domain,
499 const struct in_addr *addr,
500 const struct in_addr *mask,
501 struct netlbl_audit *audit_info)
502{
503 struct netlbl_dom_map *entry_map;
504 struct netlbl_af4list *entry_addr;
505 struct netlbl_af4list *iter4;
506#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
507 struct netlbl_af6list *iter6;
508#endif /* IPv6 */
509 struct netlbl_domaddr4_map *entry;
510
511 rcu_read_lock();
512
513 if (domain)
514 entry_map = netlbl_domhsh_search(domain);
515 else
516 entry_map = netlbl_domhsh_search_def(domain);
517 if (entry_map == NULL || entry_map->type != NETLBL_NLTYPE_ADDRSELECT)
518 goto remove_af4_failure;
519
520 spin_lock(&netlbl_domhsh_lock);
521 entry_addr = netlbl_af4list_remove(addr->s_addr, mask->s_addr,
522 &entry_map->type_def.addrsel->list4);
523 spin_unlock(&netlbl_domhsh_lock);
524
525 if (entry_addr == NULL)
526 goto remove_af4_failure;
527 netlbl_af4list_foreach_rcu(iter4, &entry_map->type_def.addrsel->list4)
528 goto remove_af4_single_addr;
529#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
530 netlbl_af6list_foreach_rcu(iter6, &entry_map->type_def.addrsel->list6)
531 goto remove_af4_single_addr;
532#endif /* IPv6 */
533 /* the domain mapping is empty so remove it from the mapping table */
534 netlbl_domhsh_remove_entry(entry_map, audit_info);
535
536remove_af4_single_addr:
537 rcu_read_unlock();
538 /* yick, we can't use call_rcu here because we don't have a rcu head
539 * pointer but hopefully this should be a rare case so the pause
540 * shouldn't be a problem */
541 synchronize_rcu();
542 entry = netlbl_domhsh_addr4_entry(entry_addr);
543 cipso_v4_doi_putdef(entry->type_def.cipsov4);
544 kfree(entry);
545 return 0;
546
547remove_af4_failure:
548 rcu_read_unlock();
549 return -ENOENT;
550}
551
552/**
486 * netlbl_domhsh_remove - Removes an entry from the domain hash table 553 * netlbl_domhsh_remove - Removes an entry from the domain hash table
487 * @domain: the domain to remove 554 * @domain: the domain to remove
488 * @audit_info: NetLabel audit information 555 * @audit_info: NetLabel audit information
diff --git a/net/netlabel/netlabel_domainhash.h b/net/netlabel/netlabel_domainhash.h
index bfcb6763a1a1..0261dda3f2d2 100644
--- a/net/netlabel/netlabel_domainhash.h
+++ b/net/netlabel/netlabel_domainhash.h
@@ -90,6 +90,10 @@ int netlbl_domhsh_add_default(struct netlbl_dom_map *entry,
90 struct netlbl_audit *audit_info); 90 struct netlbl_audit *audit_info);
91int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry, 91int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry,
92 struct netlbl_audit *audit_info); 92 struct netlbl_audit *audit_info);
93int netlbl_domhsh_remove_af4(const char *domain,
94 const struct in_addr *addr,
95 const struct in_addr *mask,
96 struct netlbl_audit *audit_info);
93int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info); 97int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info);
94int netlbl_domhsh_remove_default(struct netlbl_audit *audit_info); 98int netlbl_domhsh_remove_default(struct netlbl_audit *audit_info);
95struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain); 99struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain);
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index b32eceb3ab0d..fd9229db075c 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -31,7 +31,10 @@
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/types.h> 32#include <linux/types.h>
33#include <linux/audit.h> 33#include <linux/audit.h>
34#include <linux/in.h>
35#include <linux/in6.h>
34#include <net/ip.h> 36#include <net/ip.h>
37#include <net/ipv6.h>
35#include <net/netlabel.h> 38#include <net/netlabel.h>
36#include <net/cipso_ipv4.h> 39#include <net/cipso_ipv4.h>
37#include <asm/bug.h> 40#include <asm/bug.h>
@@ -42,6 +45,7 @@
42#include "netlabel_cipso_v4.h" 45#include "netlabel_cipso_v4.h"
43#include "netlabel_user.h" 46#include "netlabel_user.h"
44#include "netlabel_mgmt.h" 47#include "netlabel_mgmt.h"
48#include "netlabel_addrlist.h"
45 49
46/* 50/*
47 * Configuration Functions 51 * Configuration Functions
@@ -50,6 +54,9 @@
50/** 54/**
51 * netlbl_cfg_map_del - Remove a NetLabel/LSM domain mapping 55 * netlbl_cfg_map_del - Remove a NetLabel/LSM domain mapping
52 * @domain: the domain mapping to remove 56 * @domain: the domain mapping to remove
57 * @family: address family
58 * @addr: IP address
59 * @mask: IP address mask
53 * @audit_info: NetLabel audit information 60 * @audit_info: NetLabel audit information
54 * 61 *
55 * Description: 62 * Description:
@@ -58,14 +65,32 @@
58 * values on failure. 65 * values on failure.
59 * 66 *
60 */ 67 */
61int netlbl_cfg_map_del(const char *domain, struct netlbl_audit *audit_info) 68int netlbl_cfg_map_del(const char *domain,
69 u16 family,
70 const void *addr,
71 const void *mask,
72 struct netlbl_audit *audit_info)
62{ 73{
63 return netlbl_domhsh_remove(domain, audit_info); 74 if (addr == NULL && mask == NULL) {
75 return netlbl_domhsh_remove(domain, audit_info);
76 } else if (addr != NULL && mask != NULL) {
77 switch (family) {
78 case AF_INET:
79 return netlbl_domhsh_remove_af4(domain, addr, mask,
80 audit_info);
81 default:
82 return -EPFNOSUPPORT;
83 }
84 } else
85 return -EINVAL;
64} 86}
65 87
66/** 88/**
67 * netlbl_cfg_unlbl_add_map - Add an unlabeled NetLabel/LSM domain mapping 89 * netlbl_cfg_unlbl_map_add - Add a new unlabeled mapping
68 * @domain: the domain mapping to add 90 * @domain: the domain mapping to add
91 * @family: address family
92 * @addr: IP address
93 * @mask: IP address mask
69 * @audit_info: NetLabel audit information 94 * @audit_info: NetLabel audit information
70 * 95 *
71 * Description: 96 * Description:
@@ -74,11 +99,19 @@ int netlbl_cfg_map_del(const char *domain, struct netlbl_audit *audit_info)
74 * negative values on failure. 99 * negative values on failure.
75 * 100 *
76 */ 101 */
77int netlbl_cfg_unlbl_add_map(const char *domain, 102int netlbl_cfg_unlbl_map_add(const char *domain,
103 u16 family,
104 const void *addr,
105 const void *mask,
78 struct netlbl_audit *audit_info) 106 struct netlbl_audit *audit_info)
79{ 107{
80 int ret_val = -ENOMEM; 108 int ret_val = -ENOMEM;
81 struct netlbl_dom_map *entry; 109 struct netlbl_dom_map *entry;
110 struct netlbl_domaddr_map *addrmap = NULL;
111 struct netlbl_domaddr4_map *map4 = NULL;
112 struct netlbl_domaddr6_map *map6 = NULL;
113 const struct in_addr *addr4, *mask4;
114 const struct in6_addr *addr6, *mask6;
82 115
83 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 116 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
84 if (entry == NULL) 117 if (entry == NULL)
@@ -86,49 +119,225 @@ int netlbl_cfg_unlbl_add_map(const char *domain,
86 if (domain != NULL) { 119 if (domain != NULL) {
87 entry->domain = kstrdup(domain, GFP_ATOMIC); 120 entry->domain = kstrdup(domain, GFP_ATOMIC);
88 if (entry->domain == NULL) 121 if (entry->domain == NULL)
89 goto cfg_unlbl_add_map_failure; 122 goto cfg_unlbl_map_add_failure;
123 }
124
125 if (addr == NULL && mask == NULL)
126 entry->type = NETLBL_NLTYPE_UNLABELED;
127 else if (addr != NULL && mask != NULL) {
128 addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC);
129 if (addrmap == NULL)
130 goto cfg_unlbl_map_add_failure;
131 INIT_LIST_HEAD(&addrmap->list4);
132 INIT_LIST_HEAD(&addrmap->list6);
133
134 switch (family) {
135 case AF_INET:
136 addr4 = addr;
137 mask4 = mask;
138 map4 = kzalloc(sizeof(*map4), GFP_ATOMIC);
139 if (map4 == NULL)
140 goto cfg_unlbl_map_add_failure;
141 map4->type = NETLBL_NLTYPE_UNLABELED;
142 map4->list.addr = addr4->s_addr & mask4->s_addr;
143 map4->list.mask = mask4->s_addr;
144 map4->list.valid = 1;
145 ret_val = netlbl_af4list_add(&map4->list,
146 &addrmap->list4);
147 if (ret_val != 0)
148 goto cfg_unlbl_map_add_failure;
149 break;
150 case AF_INET6:
151 addr6 = addr;
152 mask6 = mask;
153 map6 = kzalloc(sizeof(*map6), GFP_ATOMIC);
154 if (map4 == NULL)
155 goto cfg_unlbl_map_add_failure;
156 map6->type = NETLBL_NLTYPE_UNLABELED;
157 ipv6_addr_copy(&map6->list.addr, addr6);
158 map6->list.addr.s6_addr32[0] &= mask6->s6_addr32[0];
159 map6->list.addr.s6_addr32[1] &= mask6->s6_addr32[1];
160 map6->list.addr.s6_addr32[2] &= mask6->s6_addr32[2];
161 map6->list.addr.s6_addr32[3] &= mask6->s6_addr32[3];
162 ipv6_addr_copy(&map6->list.mask, mask6);
163 map6->list.valid = 1;
164 ret_val = netlbl_af4list_add(&map4->list,
165 &addrmap->list4);
166 if (ret_val != 0)
167 goto cfg_unlbl_map_add_failure;
168 break;
169 default:
170 goto cfg_unlbl_map_add_failure;
171 break;
172 }
173
174 entry->type_def.addrsel = addrmap;
175 entry->type = NETLBL_NLTYPE_ADDRSELECT;
176 } else {
177 ret_val = -EINVAL;
178 goto cfg_unlbl_map_add_failure;
90 } 179 }
91 entry->type = NETLBL_NLTYPE_UNLABELED;
92 180
93 ret_val = netlbl_domhsh_add(entry, audit_info); 181 ret_val = netlbl_domhsh_add(entry, audit_info);
94 if (ret_val != 0) 182 if (ret_val != 0)
95 goto cfg_unlbl_add_map_failure; 183 goto cfg_unlbl_map_add_failure;
96 184
97 return 0; 185 return 0;
98 186
99cfg_unlbl_add_map_failure: 187cfg_unlbl_map_add_failure:
100 if (entry != NULL) 188 if (entry != NULL)
101 kfree(entry->domain); 189 kfree(entry->domain);
102 kfree(entry); 190 kfree(entry);
191 kfree(addrmap);
192 kfree(map4);
193 kfree(map6);
103 return ret_val; 194 return ret_val;
104} 195}
105 196
197
198/**
199 * netlbl_cfg_unlbl_static_add - Adds a new static label
200 * @net: network namespace
201 * @dev_name: interface name
202 * @addr: IP address in network byte order (struct in[6]_addr)
203 * @mask: address mask in network byte order (struct in[6]_addr)
204 * @family: address family
205 * @secid: LSM secid value for the entry
206 * @audit_info: NetLabel audit information
207 *
208 * Description:
209 * Adds a new NetLabel static label to be used when protocol provided labels
210 * are not present on incoming traffic. If @dev_name is NULL then the default
211 * interface will be used. Returns zero on success, negative values on failure.
212 *
213 */
214int netlbl_cfg_unlbl_static_add(struct net *net,
215 const char *dev_name,
216 const void *addr,
217 const void *mask,
218 u16 family,
219 u32 secid,
220 struct netlbl_audit *audit_info)
221{
222 u32 addr_len;
223
224 switch (family) {
225 case AF_INET:
226 addr_len = sizeof(struct in_addr);
227 break;
228 case AF_INET6:
229 addr_len = sizeof(struct in6_addr);
230 break;
231 default:
232 return -EPFNOSUPPORT;
233 }
234
235 return netlbl_unlhsh_add(net,
236 dev_name, addr, mask, addr_len,
237 secid, audit_info);
238}
239
240/**
241 * netlbl_cfg_unlbl_static_del - Removes an existing static label
242 * @net: network namespace
243 * @dev_name: interface name
244 * @addr: IP address in network byte order (struct in[6]_addr)
245 * @mask: address mask in network byte order (struct in[6]_addr)
246 * @family: address family
247 * @secid: LSM secid value for the entry
248 * @audit_info: NetLabel audit information
249 *
250 * Description:
251 * Removes an existing NetLabel static label used when protocol provided labels
252 * are not present on incoming traffic. If @dev_name is NULL then the default
253 * interface will be used. Returns zero on success, negative values on failure.
254 *
255 */
256int netlbl_cfg_unlbl_static_del(struct net *net,
257 const char *dev_name,
258 const void *addr,
259 const void *mask,
260 u16 family,
261 struct netlbl_audit *audit_info)
262{
263 u32 addr_len;
264
265 switch (family) {
266 case AF_INET:
267 addr_len = sizeof(struct in_addr);
268 break;
269 case AF_INET6:
270 addr_len = sizeof(struct in6_addr);
271 break;
272 default:
273 return -EPFNOSUPPORT;
274 }
275
276 return netlbl_unlhsh_remove(net,
277 dev_name, addr, mask, addr_len,
278 audit_info);
279}
280
281/**
282 * netlbl_cfg_cipsov4_add - Add a new CIPSOv4 DOI definition
283 * @doi_def: CIPSO DOI definition
284 * @audit_info: NetLabel audit information
285 *
286 * Description:
287 * Add a new CIPSO DOI definition as defined by @doi_def. Returns zero on
288 * success and negative values on failure.
289 *
290 */
291int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def,
292 struct netlbl_audit *audit_info)
293{
294 return cipso_v4_doi_add(doi_def, audit_info);
295}
296
297/**
298 * netlbl_cfg_cipsov4_del - Remove an existing CIPSOv4 DOI definition
299 * @doi: CIPSO DOI
300 * @audit_info: NetLabel audit information
301 *
302 * Description:
303 * Remove an existing CIPSO DOI definition matching @doi. Returns zero on
304 * success and negative values on failure.
305 *
306 */
307void netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info)
308{
309 cipso_v4_doi_remove(doi, audit_info);
310}
311
106/** 312/**
107 * netlbl_cfg_cipsov4_add_map - Add a new CIPSOv4 DOI definition and mapping 313 * netlbl_cfg_cipsov4_map_add - Add a new CIPSOv4 DOI mapping
108 * @doi_def: the DOI definition 314 * @doi: the CIPSO DOI
109 * @domain: the domain mapping to add 315 * @domain: the domain mapping to add
316 * @addr: IP address
317 * @mask: IP address mask
110 * @audit_info: NetLabel audit information 318 * @audit_info: NetLabel audit information
111 * 319 *
112 * Description: 320 * Description:
113 * Add a new CIPSOv4 DOI definition and NetLabel/LSM domain mapping for this 321 * Add a new NetLabel/LSM domain mapping for the given CIPSO DOI to the NetLabel
114 * new DOI definition to the NetLabel subsystem. A @domain value of NULL adds 322 * subsystem. A @domain value of NULL adds a new default domain mapping.
115 * a new default domain mapping. Returns zero on success, negative values on 323 * Returns zero on success, negative values on failure.
116 * failure.
117 * 324 *
118 */ 325 */
119int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def, 326int netlbl_cfg_cipsov4_map_add(u32 doi,
120 const char *domain, 327 const char *domain,
328 const struct in_addr *addr,
329 const struct in_addr *mask,
121 struct netlbl_audit *audit_info) 330 struct netlbl_audit *audit_info)
122{ 331{
123 int ret_val = -ENOMEM; 332 int ret_val = -ENOMEM;
124 u32 doi; 333 struct cipso_v4_doi *doi_def;
125 u32 doi_type;
126 struct netlbl_dom_map *entry; 334 struct netlbl_dom_map *entry;
127 const char *type_str; 335 struct netlbl_domaddr_map *addrmap = NULL;
128 struct audit_buffer *audit_buf; 336 struct netlbl_domaddr4_map *addrinfo = NULL;
129 337
130 doi = doi_def->doi; 338 doi_def = cipso_v4_doi_getdef(doi);
131 doi_type = doi_def->type; 339 if (doi_def == NULL)
340 return -ENOENT;
132 341
133 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 342 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
134 if (entry == NULL) 343 if (entry == NULL)
@@ -136,56 +345,52 @@ int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def,
136 if (domain != NULL) { 345 if (domain != NULL) {
137 entry->domain = kstrdup(domain, GFP_ATOMIC); 346 entry->domain = kstrdup(domain, GFP_ATOMIC);
138 if (entry->domain == NULL) 347 if (entry->domain == NULL)
139 goto cfg_cipsov4_add_map_failure; 348 goto cfg_cipsov4_map_add_failure;
140 } 349 }
141 350
142 ret_val = cipso_v4_doi_add(doi_def); 351 if (addr == NULL && mask == NULL) {
143 if (ret_val != 0) 352 entry->type_def.cipsov4 = doi_def;
144 goto cfg_cipsov4_add_map_failure_remove_doi; 353 entry->type = NETLBL_NLTYPE_CIPSOV4;
145 entry->type = NETLBL_NLTYPE_CIPSOV4; 354 } else if (addr != NULL && mask != NULL) {
146 entry->type_def.cipsov4 = cipso_v4_doi_getdef(doi); 355 addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC);
147 if (entry->type_def.cipsov4 == NULL) { 356 if (addrmap == NULL)
148 ret_val = -ENOENT; 357 goto cfg_cipsov4_map_add_failure;
149 goto cfg_cipsov4_add_map_failure_remove_doi; 358 INIT_LIST_HEAD(&addrmap->list4);
359 INIT_LIST_HEAD(&addrmap->list6);
360
361 addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC);
362 if (addrinfo == NULL)
363 goto cfg_cipsov4_map_add_failure;
364 addrinfo->type_def.cipsov4 = doi_def;
365 addrinfo->type = NETLBL_NLTYPE_CIPSOV4;
366 addrinfo->list.addr = addr->s_addr & mask->s_addr;
367 addrinfo->list.mask = mask->s_addr;
368 addrinfo->list.valid = 1;
369 ret_val = netlbl_af4list_add(&addrinfo->list, &addrmap->list4);
370 if (ret_val != 0)
371 goto cfg_cipsov4_map_add_failure;
372
373 entry->type_def.addrsel = addrmap;
374 entry->type = NETLBL_NLTYPE_ADDRSELECT;
375 } else {
376 ret_val = -EINVAL;
377 goto cfg_cipsov4_map_add_failure;
150 } 378 }
379
151 ret_val = netlbl_domhsh_add(entry, audit_info); 380 ret_val = netlbl_domhsh_add(entry, audit_info);
152 if (ret_val != 0) 381 if (ret_val != 0)
153 goto cfg_cipsov4_add_map_failure_release_doi; 382 goto cfg_cipsov4_map_add_failure;
154
155cfg_cipsov4_add_map_return:
156 audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD,
157 audit_info);
158 if (audit_buf != NULL) {
159 switch (doi_type) {
160 case CIPSO_V4_MAP_TRANS:
161 type_str = "trans";
162 break;
163 case CIPSO_V4_MAP_PASS:
164 type_str = "pass";
165 break;
166 case CIPSO_V4_MAP_LOCAL:
167 type_str = "local";
168 break;
169 default:
170 type_str = "(unknown)";
171 }
172 audit_log_format(audit_buf,
173 " cipso_doi=%u cipso_type=%s res=%u",
174 doi, type_str, ret_val == 0 ? 1 : 0);
175 audit_log_end(audit_buf);
176 }
177 383
178 return ret_val; 384 return 0;
179 385
180cfg_cipsov4_add_map_failure_release_doi: 386cfg_cipsov4_map_add_failure:
181 cipso_v4_doi_putdef(doi_def); 387 cipso_v4_doi_putdef(doi_def);
182cfg_cipsov4_add_map_failure_remove_doi:
183 cipso_v4_doi_remove(doi, audit_info);
184cfg_cipsov4_add_map_failure:
185 if (entry != NULL) 388 if (entry != NULL)
186 kfree(entry->domain); 389 kfree(entry->domain);
187 kfree(entry); 390 kfree(entry);
188 goto cfg_cipsov4_add_map_return; 391 kfree(addrmap);
392 kfree(addrinfo);
393 return ret_val;
189} 394}
190 395
191/* 396/*
@@ -691,6 +896,28 @@ int netlbl_cache_add(const struct sk_buff *skb,
691} 896}
692 897
693/* 898/*
899 * Protocol Engine Functions
900 */
901
902/**
903 * netlbl_audit_start - Start an audit message
904 * @type: audit message type
905 * @audit_info: NetLabel audit information
906 *
907 * Description:
908 * Start an audit message using the type specified in @type and fill the audit
909 * message with some fields common to all NetLabel audit messages. This
910 * function should only be used by protocol engines, not LSMs. Returns a
911 * pointer to the audit buffer on success, NULL on failure.
912 *
913 */
914struct audit_buffer *netlbl_audit_start(int type,
915 struct netlbl_audit *audit_info)
916{
917 return netlbl_audit_start_common(type, audit_info);
918}
919
920/*
694 * Setup Functions 921 * Setup Functions
695 */ 922 */
696 923
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 8c0308032178..f3c5c68c6848 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -450,13 +450,13 @@ add_iface_failure:
450 * success, negative values on failure. 450 * success, negative values on failure.
451 * 451 *
452 */ 452 */
453static int netlbl_unlhsh_add(struct net *net, 453int netlbl_unlhsh_add(struct net *net,
454 const char *dev_name, 454 const char *dev_name,
455 const void *addr, 455 const void *addr,
456 const void *mask, 456 const void *mask,
457 u32 addr_len, 457 u32 addr_len,
458 u32 secid, 458 u32 secid,
459 struct netlbl_audit *audit_info) 459 struct netlbl_audit *audit_info)
460{ 460{
461 int ret_val; 461 int ret_val;
462 int ifindex; 462 int ifindex;
@@ -720,12 +720,12 @@ unlhsh_condremove_failure:
720 * Returns zero on success, negative values on failure. 720 * Returns zero on success, negative values on failure.
721 * 721 *
722 */ 722 */
723static int netlbl_unlhsh_remove(struct net *net, 723int netlbl_unlhsh_remove(struct net *net,
724 const char *dev_name, 724 const char *dev_name,
725 const void *addr, 725 const void *addr,
726 const void *mask, 726 const void *mask,
727 u32 addr_len, 727 u32 addr_len,
728 struct netlbl_audit *audit_info) 728 struct netlbl_audit *audit_info)
729{ 729{
730 int ret_val; 730 int ret_val;
731 struct net_device *dev; 731 struct net_device *dev;
diff --git a/net/netlabel/netlabel_unlabeled.h b/net/netlabel/netlabel_unlabeled.h
index 06b1301ac072..7aba63595137 100644
--- a/net/netlabel/netlabel_unlabeled.h
+++ b/net/netlabel/netlabel_unlabeled.h
@@ -221,6 +221,21 @@ int netlbl_unlabel_genl_init(void);
221/* General Unlabeled init function */ 221/* General Unlabeled init function */
222int netlbl_unlabel_init(u32 size); 222int netlbl_unlabel_init(u32 size);
223 223
224/* Static/Fallback label management functions */
225int netlbl_unlhsh_add(struct net *net,
226 const char *dev_name,
227 const void *addr,
228 const void *mask,
229 u32 addr_len,
230 u32 secid,
231 struct netlbl_audit *audit_info);
232int netlbl_unlhsh_remove(struct net *net,
233 const char *dev_name,
234 const void *addr,
235 const void *mask,
236 u32 addr_len,
237 struct netlbl_audit *audit_info);
238
224/* Process Unlabeled incoming network packets */ 239/* Process Unlabeled incoming network packets */
225int netlbl_unlabel_getattr(const struct sk_buff *skb, 240int netlbl_unlabel_getattr(const struct sk_buff *skb,
226 u16 family, 241 u16 family,