netlabel_unlabeled.c (561967010edef40f539dacf2aa125e20773ab40b) | netlabel_unlabeled.c (61e1068219950c672ce979719ad2be3aadb00d7d) |
---|---|
1/* 2 * NetLabel Unlabeled Support 3 * 4 * This file defines functions for dealing with unlabeled packets for the 5 * NetLabel system. The NetLabel system manages static and dynamic label 6 * mappings for network protocols such as CIPSO and RIPSO. 7 * 8 * Author: Paul Moore <paul.moore@hp.com> 9 * 10 */ 11 12/* | 1/* 2 * NetLabel Unlabeled Support 3 * 4 * This file defines functions for dealing with unlabeled packets for the 5 * NetLabel system. The NetLabel system manages static and dynamic label 6 * mappings for network protocols such as CIPSO and RIPSO. 7 * 8 * Author: Paul Moore <paul.moore@hp.com> 9 * 10 */ 11 12/* |
13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 - 2007 | 13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 - 2008 |
14 * 15 * This program is free software; you can redistribute it and/or modify 16 * it under the terms of the GNU General Public License as published by 17 * the Free Software Foundation; either version 2 of the License, or 18 * (at your option) any later version. 19 * 20 * This program is distributed in the hope that it will be useful, 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of --- 27 unchanged lines hidden (view full) --- 49#include <net/ip.h> 50#include <net/ipv6.h> 51#include <net/net_namespace.h> 52#include <net/netlabel.h> 53#include <asm/bug.h> 54#include <asm/atomic.h> 55 56#include "netlabel_user.h" | 14 * 15 * This program is free software; you can redistribute it and/or modify 16 * it under the terms of the GNU General Public License as published by 17 * the Free Software Foundation; either version 2 of the License, or 18 * (at your option) any later version. 19 * 20 * This program is distributed in the hope that it will be useful, 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of --- 27 unchanged lines hidden (view full) --- 49#include <net/ip.h> 50#include <net/ipv6.h> 51#include <net/net_namespace.h> 52#include <net/netlabel.h> 53#include <asm/bug.h> 54#include <asm/atomic.h> 55 56#include "netlabel_user.h" |
57#include "netlabel_addrlist.h" |
|
57#include "netlabel_domainhash.h" 58#include "netlabel_unlabeled.h" 59#include "netlabel_mgmt.h" 60 61/* NOTE: at present we always use init's network namespace since we don't 62 * presently support different namespaces even though the majority of 63 * the functions in this file are "namespace safe" */ 64 --- 6 unchanged lines hidden (view full) --- 71 * (netlbl_unlhsh_def) is used. The IP address entry list 72 * (struct netlbl_unlhsh_addr) is ordered such that the entries with a 73 * larger netmask come first. 74 */ 75struct netlbl_unlhsh_tbl { 76 struct list_head *tbl; 77 u32 size; 78}; | 58#include "netlabel_domainhash.h" 59#include "netlabel_unlabeled.h" 60#include "netlabel_mgmt.h" 61 62/* NOTE: at present we always use init's network namespace since we don't 63 * presently support different namespaces even though the majority of 64 * the functions in this file are "namespace safe" */ 65 --- 6 unchanged lines hidden (view full) --- 72 * (netlbl_unlhsh_def) is used. The IP address entry list 73 * (struct netlbl_unlhsh_addr) is ordered such that the entries with a 74 * larger netmask come first. 75 */ 76struct netlbl_unlhsh_tbl { 77 struct list_head *tbl; 78 u32 size; 79}; |
80#define netlbl_unlhsh_addr4_entry(iter) \ 81 container_of(iter, struct netlbl_unlhsh_addr4, list) |
|
79struct netlbl_unlhsh_addr4 { | 82struct netlbl_unlhsh_addr4 { |
80 __be32 addr; 81 __be32 mask; | |
82 u32 secid; 83 | 83 u32 secid; 84 |
84 u32 valid; 85 struct list_head list; | 85 struct netlbl_af4list list; |
86 struct rcu_head rcu; 87}; | 86 struct rcu_head rcu; 87}; |
88#define netlbl_unlhsh_addr6_entry(iter) \ 89 container_of(iter, struct netlbl_unlhsh_addr6, list) |
|
88struct netlbl_unlhsh_addr6 { | 90struct netlbl_unlhsh_addr6 { |
89 struct in6_addr addr; 90 struct in6_addr mask; | |
91 u32 secid; 92 | 91 u32 secid; 92 |
93 u32 valid; 94 struct list_head list; | 93 struct netlbl_af6list list; |
95 struct rcu_head rcu; 96}; 97struct netlbl_unlhsh_iface { 98 int ifindex; 99 struct list_head addr4_list; 100 struct list_head addr6_list; 101 102 u32 valid; --- 166 unchanged lines hidden (view full) --- 269 * the IPv4 and IPv6 address lists contained as part of an interface entry. It 270 * is up to the rest of the code to make sure an interface entry is only freed 271 * once it's address lists are empty. 272 * 273 */ 274static void netlbl_unlhsh_free_iface(struct rcu_head *entry) 275{ 276 struct netlbl_unlhsh_iface *iface; | 94 struct rcu_head rcu; 95}; 96struct netlbl_unlhsh_iface { 97 int ifindex; 98 struct list_head addr4_list; 99 struct list_head addr6_list; 100 101 u32 valid; --- 166 unchanged lines hidden (view full) --- 268 * the IPv4 and IPv6 address lists contained as part of an interface entry. It 269 * is up to the rest of the code to make sure an interface entry is only freed 270 * once it's address lists are empty. 271 * 272 */ 273static void netlbl_unlhsh_free_iface(struct rcu_head *entry) 274{ 275 struct netlbl_unlhsh_iface *iface; |
277 struct netlbl_unlhsh_addr4 *iter4; 278 struct netlbl_unlhsh_addr4 *tmp4; 279 struct netlbl_unlhsh_addr6 *iter6; 280 struct netlbl_unlhsh_addr6 *tmp6; | 276 struct netlbl_af4list *iter4; 277 struct netlbl_af4list *tmp4; 278#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 279 struct netlbl_af6list *iter6; 280 struct netlbl_af6list *tmp6; 281#endif /* IPv6 */ |
281 282 iface = container_of(entry, struct netlbl_unlhsh_iface, rcu); 283 284 /* no need for locks here since we are the only one with access to this 285 * structure */ 286 | 282 283 iface = container_of(entry, struct netlbl_unlhsh_iface, rcu); 284 285 /* no need for locks here since we are the only one with access to this 286 * structure */ 287 |
287 list_for_each_entry_safe(iter4, tmp4, &iface->addr4_list, list) 288 if (iter4->valid) { 289 list_del_rcu(&iter4->list); 290 kfree(iter4); 291 } 292 list_for_each_entry_safe(iter6, tmp6, &iface->addr6_list, list) 293 if (iter6->valid) { 294 list_del_rcu(&iter6->list); 295 kfree(iter6); 296 } | 288 netlbl_af4list_foreach_safe(iter4, tmp4, &iface->addr4_list) { 289 netlbl_af4list_remove_entry(iter4); 290 kfree(netlbl_unlhsh_addr4_entry(iter4)); 291 } 292#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 293 netlbl_af6list_foreach_safe(iter6, tmp6, &iface->addr6_list) { 294 netlbl_af6list_remove_entry(iter6); 295 kfree(netlbl_unlhsh_addr6_entry(iter6)); 296 } 297#endif /* IPv6 */ |
297 kfree(iface); 298} 299 300/** 301 * netlbl_unlhsh_hash - Hashing function for the hash table 302 * @ifindex: the network interface/device to hash 303 * 304 * Description: --- 6 unchanged lines hidden (view full) --- 311{ 312 /* this is taken _almost_ directly from 313 * security/selinux/netif.c:sel_netif_hasfn() as they do pretty much 314 * the same thing */ 315 return ifindex & (rcu_dereference(netlbl_unlhsh)->size - 1); 316} 317 318/** | 298 kfree(iface); 299} 300 301/** 302 * netlbl_unlhsh_hash - Hashing function for the hash table 303 * @ifindex: the network interface/device to hash 304 * 305 * Description: --- 6 unchanged lines hidden (view full) --- 312{ 313 /* this is taken _almost_ directly from 314 * security/selinux/netif.c:sel_netif_hasfn() as they do pretty much 315 * the same thing */ 316 return ifindex & (rcu_dereference(netlbl_unlhsh)->size - 1); 317} 318 319/** |
319 * netlbl_unlhsh_search_addr4 - Search for a matching IPv4 address entry 320 * @addr: IPv4 address 321 * @iface: the network interface entry 322 * 323 * Description: 324 * Searches the IPv4 address list of the network interface specified by @iface. 325 * If a matching address entry is found it is returned, otherwise NULL is 326 * returned. The caller is responsible for calling the rcu_read_[un]lock() 327 * functions. 328 * 329 */ 330static struct netlbl_unlhsh_addr4 *netlbl_unlhsh_search_addr4( 331 __be32 addr, 332 const struct netlbl_unlhsh_iface *iface) 333{ 334 struct netlbl_unlhsh_addr4 *iter; 335 336 list_for_each_entry_rcu(iter, &iface->addr4_list, list) 337 if (iter->valid && (addr & iter->mask) == iter->addr) 338 return iter; 339 340 return NULL; 341} 342 343#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 344/** 345 * netlbl_unlhsh_search_addr6 - Search for a matching IPv6 address entry 346 * @addr: IPv6 address 347 * @iface: the network interface entry 348 * 349 * Description: 350 * Searches the IPv6 address list of the network interface specified by @iface. 351 * If a matching address entry is found it is returned, otherwise NULL is 352 * returned. The caller is responsible for calling the rcu_read_[un]lock() 353 * functions. 354 * 355 */ 356static struct netlbl_unlhsh_addr6 *netlbl_unlhsh_search_addr6( 357 const struct in6_addr *addr, 358 const struct netlbl_unlhsh_iface *iface) 359{ 360 struct netlbl_unlhsh_addr6 *iter; 361 362 list_for_each_entry_rcu(iter, &iface->addr6_list, list) 363 if (iter->valid && 364 ipv6_masked_addr_cmp(&iter->addr, &iter->mask, addr) == 0) 365 return iter; 366 367 return NULL; 368} 369#endif /* IPv6 */ 370 371/** | |
372 * netlbl_unlhsh_search_iface - Search for a matching interface entry 373 * @ifindex: the network interface 374 * 375 * Description: 376 * Searches the unlabeled connection hash table and returns a pointer to the 377 * interface entry which matches @ifindex, otherwise NULL is returned. The 378 * caller is responsible for calling the rcu_read_[un]lock() functions. 379 * --- 54 unchanged lines hidden (view full) --- 434 * rcu_read_[un]lock() functions. 435 * 436 */ 437static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, 438 const struct in_addr *addr, 439 const struct in_addr *mask, 440 u32 secid) 441{ | 320 * netlbl_unlhsh_search_iface - Search for a matching interface entry 321 * @ifindex: the network interface 322 * 323 * Description: 324 * Searches the unlabeled connection hash table and returns a pointer to the 325 * interface entry which matches @ifindex, otherwise NULL is returned. The 326 * caller is responsible for calling the rcu_read_[un]lock() functions. 327 * --- 54 unchanged lines hidden (view full) --- 382 * rcu_read_[un]lock() functions. 383 * 384 */ 385static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, 386 const struct in_addr *addr, 387 const struct in_addr *mask, 388 u32 secid) 389{ |
390 int ret_val; |
|
442 struct netlbl_unlhsh_addr4 *entry; | 391 struct netlbl_unlhsh_addr4 *entry; |
443 struct netlbl_unlhsh_addr4 *iter; | |
444 445 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 446 if (entry == NULL) 447 return -ENOMEM; 448 | 392 393 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 394 if (entry == NULL) 395 return -ENOMEM; 396 |
449 entry->addr = addr->s_addr & mask->s_addr; 450 entry->mask = mask->s_addr; 451 entry->secid = secid; 452 entry->valid = 1; | 397 entry->list.addr = addr->s_addr & mask->s_addr; 398 entry->list.mask = mask->s_addr; 399 entry->list.valid = 1; |
453 INIT_RCU_HEAD(&entry->rcu); | 400 INIT_RCU_HEAD(&entry->rcu); |
401 entry->secid = secid; |
|
454 455 spin_lock(&netlbl_unlhsh_lock); | 402 403 spin_lock(&netlbl_unlhsh_lock); |
456 iter = netlbl_unlhsh_search_addr4(entry->addr, iface); 457 if (iter != NULL && 458 iter->addr == addr->s_addr && iter->mask == mask->s_addr) { 459 spin_unlock(&netlbl_unlhsh_lock); 460 kfree(entry); 461 return -EEXIST; 462 } 463 /* in order to speed up address searches through the list (the common 464 * case) we need to keep the list in order based on the size of the 465 * address mask such that the entry with the widest mask (smallest 466 * numerical value) appears first in the list */ 467 list_for_each_entry_rcu(iter, &iface->addr4_list, list) 468 if (iter->valid && 469 ntohl(entry->mask) > ntohl(iter->mask)) { 470 __list_add_rcu(&entry->list, 471 iter->list.prev, 472 &iter->list); 473 spin_unlock(&netlbl_unlhsh_lock); 474 return 0; 475 } 476 list_add_tail_rcu(&entry->list, &iface->addr4_list); | 404 ret_val = netlbl_af4list_add(&entry->list, &iface->addr4_list); |
477 spin_unlock(&netlbl_unlhsh_lock); | 405 spin_unlock(&netlbl_unlhsh_lock); |
478 return 0; | 406 407 if (ret_val != 0) 408 kfree(entry); 409 return ret_val; |
479} 480 481#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 482/** 483 * netlbl_unlhsh_add_addr6 - Add a new IPv6 address entry to the hash table 484 * @iface: the associated interface entry 485 * @addr: IPv6 address in network byte order 486 * @mask: IPv6 address mask in network byte order --- 6 unchanged lines hidden (view full) --- 493 * rcu_read_[un]lock() functions. 494 * 495 */ 496static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, 497 const struct in6_addr *addr, 498 const struct in6_addr *mask, 499 u32 secid) 500{ | 410} 411 412#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 413/** 414 * netlbl_unlhsh_add_addr6 - Add a new IPv6 address entry to the hash table 415 * @iface: the associated interface entry 416 * @addr: IPv6 address in network byte order 417 * @mask: IPv6 address mask in network byte order --- 6 unchanged lines hidden (view full) --- 424 * rcu_read_[un]lock() functions. 425 * 426 */ 427static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, 428 const struct in6_addr *addr, 429 const struct in6_addr *mask, 430 u32 secid) 431{ |
432 int ret_val; |
|
501 struct netlbl_unlhsh_addr6 *entry; | 433 struct netlbl_unlhsh_addr6 *entry; |
502 struct netlbl_unlhsh_addr6 *iter; | |
503 504 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 505 if (entry == NULL) 506 return -ENOMEM; 507 | 434 435 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 436 if (entry == NULL) 437 return -ENOMEM; 438 |
508 ipv6_addr_copy(&entry->addr, addr); 509 entry->addr.s6_addr32[0] &= mask->s6_addr32[0]; 510 entry->addr.s6_addr32[1] &= mask->s6_addr32[1]; 511 entry->addr.s6_addr32[2] &= mask->s6_addr32[2]; 512 entry->addr.s6_addr32[3] &= mask->s6_addr32[3]; 513 ipv6_addr_copy(&entry->mask, mask); 514 entry->secid = secid; 515 entry->valid = 1; | 439 ipv6_addr_copy(&entry->list.addr, addr); 440 entry->list.addr.s6_addr32[0] &= mask->s6_addr32[0]; 441 entry->list.addr.s6_addr32[1] &= mask->s6_addr32[1]; 442 entry->list.addr.s6_addr32[2] &= mask->s6_addr32[2]; 443 entry->list.addr.s6_addr32[3] &= mask->s6_addr32[3]; 444 ipv6_addr_copy(&entry->list.mask, mask); 445 entry->list.valid = 1; |
516 INIT_RCU_HEAD(&entry->rcu); | 446 INIT_RCU_HEAD(&entry->rcu); |
447 entry->secid = secid; |
|
517 518 spin_lock(&netlbl_unlhsh_lock); | 448 449 spin_lock(&netlbl_unlhsh_lock); |
519 iter = netlbl_unlhsh_search_addr6(&entry->addr, iface); 520 if (iter != NULL && 521 (ipv6_addr_equal(&iter->addr, addr) && 522 ipv6_addr_equal(&iter->mask, mask))) { 523 spin_unlock(&netlbl_unlhsh_lock); 524 kfree(entry); 525 return -EEXIST; 526 } 527 /* in order to speed up address searches through the list (the common 528 * case) we need to keep the list in order based on the size of the 529 * address mask such that the entry with the widest mask (smallest 530 * numerical value) appears first in the list */ 531 list_for_each_entry_rcu(iter, &iface->addr6_list, list) 532 if (iter->valid && 533 ipv6_addr_cmp(&entry->mask, &iter->mask) > 0) { 534 __list_add_rcu(&entry->list, 535 iter->list.prev, 536 &iter->list); 537 spin_unlock(&netlbl_unlhsh_lock); 538 return 0; 539 } 540 list_add_tail_rcu(&entry->list, &iface->addr6_list); | 450 ret_val = netlbl_af6list_add(&entry->list, &iface->addr6_list); |
541 spin_unlock(&netlbl_unlhsh_lock); | 451 spin_unlock(&netlbl_unlhsh_lock); |
452 453 if (ret_val != 0) 454 kfree(entry); |
|
542 return 0; 543} 544#endif /* IPv6 */ 545 546/** 547 * netlbl_unlhsh_add_iface - Adds a new interface entry to the hash table 548 * @ifindex: network interface 549 * --- 164 unchanged lines hidden (view full) --- 714 * 715 */ 716static int netlbl_unlhsh_remove_addr4(struct net *net, 717 struct netlbl_unlhsh_iface *iface, 718 const struct in_addr *addr, 719 const struct in_addr *mask, 720 struct netlbl_audit *audit_info) 721{ | 455 return 0; 456} 457#endif /* IPv6 */ 458 459/** 460 * netlbl_unlhsh_add_iface - Adds a new interface entry to the hash table 461 * @ifindex: network interface 462 * --- 164 unchanged lines hidden (view full) --- 627 * 628 */ 629static int netlbl_unlhsh_remove_addr4(struct net *net, 630 struct netlbl_unlhsh_iface *iface, 631 const struct in_addr *addr, 632 const struct in_addr *mask, 633 struct netlbl_audit *audit_info) 634{ |
722 int ret_val = -ENOENT; | 635 int ret_val = 0; 636 struct netlbl_af4list *list_entry; |
723 struct netlbl_unlhsh_addr4 *entry; | 637 struct netlbl_unlhsh_addr4 *entry; |
724 struct audit_buffer *audit_buf = NULL; | 638 struct audit_buffer *audit_buf; |
725 struct net_device *dev; | 639 struct net_device *dev; |
726 char *secctx = NULL; | 640 char *secctx; |
727 u32 secctx_len; 728 729 spin_lock(&netlbl_unlhsh_lock); | 641 u32 secctx_len; 642 643 spin_lock(&netlbl_unlhsh_lock); |
730 entry = netlbl_unlhsh_search_addr4(addr->s_addr, iface); 731 if (entry != NULL && 732 entry->addr == addr->s_addr && entry->mask == mask->s_addr) { 733 entry->valid = 0; 734 list_del_rcu(&entry->list); 735 ret_val = 0; 736 } | 644 list_entry = netlbl_af4list_remove(addr->s_addr, mask->s_addr, 645 &iface->addr4_list); |
737 spin_unlock(&netlbl_unlhsh_lock); | 646 spin_unlock(&netlbl_unlhsh_lock); |
647 if (list_entry == NULL) 648 ret_val = -ENOENT; 649 entry = netlbl_unlhsh_addr4_entry(list_entry); |
|
738 739 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL, 740 audit_info); 741 if (audit_buf != NULL) { 742 dev = dev_get_by_index(net, iface->ifindex); 743 netlbl_unlabel_audit_addr4(audit_buf, 744 (dev != NULL ? dev->name : NULL), | 650 651 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL, 652 audit_info); 653 if (audit_buf != NULL) { 654 dev = dev_get_by_index(net, iface->ifindex); 655 netlbl_unlabel_audit_addr4(audit_buf, 656 (dev != NULL ? dev->name : NULL), |
745 entry->addr, entry->mask); | 657 addr->s_addr, mask->s_addr); |
746 if (dev != NULL) 747 dev_put(dev); | 658 if (dev != NULL) 659 dev_put(dev); |
748 if (security_secid_to_secctx(entry->secid, 749 &secctx, 750 &secctx_len) == 0) { | 660 if (entry && security_secid_to_secctx(entry->secid, 661 &secctx, 662 &secctx_len) == 0) { |
751 audit_log_format(audit_buf, " sec_obj=%s", secctx); 752 security_release_secctx(secctx, secctx_len); 753 } 754 audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); 755 audit_log_end(audit_buf); 756 } 757 758 if (ret_val == 0) --- 17 unchanged lines hidden (view full) --- 776 * 777 */ 778static int netlbl_unlhsh_remove_addr6(struct net *net, 779 struct netlbl_unlhsh_iface *iface, 780 const struct in6_addr *addr, 781 const struct in6_addr *mask, 782 struct netlbl_audit *audit_info) 783{ | 663 audit_log_format(audit_buf, " sec_obj=%s", secctx); 664 security_release_secctx(secctx, secctx_len); 665 } 666 audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); 667 audit_log_end(audit_buf); 668 } 669 670 if (ret_val == 0) --- 17 unchanged lines hidden (view full) --- 688 * 689 */ 690static int netlbl_unlhsh_remove_addr6(struct net *net, 691 struct netlbl_unlhsh_iface *iface, 692 const struct in6_addr *addr, 693 const struct in6_addr *mask, 694 struct netlbl_audit *audit_info) 695{ |
784 int ret_val = -ENOENT; | 696 int ret_val = 0; 697 struct netlbl_af6list *list_entry; |
785 struct netlbl_unlhsh_addr6 *entry; | 698 struct netlbl_unlhsh_addr6 *entry; |
786 struct audit_buffer *audit_buf = NULL; | 699 struct audit_buffer *audit_buf; |
787 struct net_device *dev; | 700 struct net_device *dev; |
788 char *secctx = NULL; | 701 char *secctx; |
789 u32 secctx_len; 790 791 spin_lock(&netlbl_unlhsh_lock); | 702 u32 secctx_len; 703 704 spin_lock(&netlbl_unlhsh_lock); |
792 entry = netlbl_unlhsh_search_addr6(addr, iface); 793 if (entry != NULL && 794 (ipv6_addr_equal(&entry->addr, addr) && 795 ipv6_addr_equal(&entry->mask, mask))) { 796 entry->valid = 0; 797 list_del_rcu(&entry->list); 798 ret_val = 0; 799 } | 705 list_entry = netlbl_af6list_remove(addr, mask, &iface->addr6_list); |
800 spin_unlock(&netlbl_unlhsh_lock); | 706 spin_unlock(&netlbl_unlhsh_lock); |
707 if (list_entry == NULL) 708 ret_val = -ENOENT; 709 entry = netlbl_unlhsh_addr6_entry(list_entry); |
|
801 802 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL, 803 audit_info); 804 if (audit_buf != NULL) { 805 dev = dev_get_by_index(net, iface->ifindex); 806 netlbl_unlabel_audit_addr6(audit_buf, 807 (dev != NULL ? dev->name : NULL), 808 addr, mask); 809 if (dev != NULL) 810 dev_put(dev); | 710 711 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL, 712 audit_info); 713 if (audit_buf != NULL) { 714 dev = dev_get_by_index(net, iface->ifindex); 715 netlbl_unlabel_audit_addr6(audit_buf, 716 (dev != NULL ? dev->name : NULL), 717 addr, mask); 718 if (dev != NULL) 719 dev_put(dev); |
811 if (security_secid_to_secctx(entry->secid, 812 &secctx, 813 &secctx_len) == 0) { | 720 if (entry && security_secid_to_secctx(entry->secid, 721 &secctx, 722 &secctx_len) == 0) { |
814 audit_log_format(audit_buf, " sec_obj=%s", secctx); 815 security_release_secctx(secctx, secctx_len); 816 } 817 audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); 818 audit_log_end(audit_buf); 819 } 820 821 if (ret_val == 0) --- 9 unchanged lines hidden (view full) --- 831 * Description: 832 * Remove an interface entry from the unlabeled connection hash table if it is 833 * empty. An interface entry is considered to be empty if there are no 834 * address entries assigned to it. 835 * 836 */ 837static void netlbl_unlhsh_condremove_iface(struct netlbl_unlhsh_iface *iface) 838{ | 723 audit_log_format(audit_buf, " sec_obj=%s", secctx); 724 security_release_secctx(secctx, secctx_len); 725 } 726 audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); 727 audit_log_end(audit_buf); 728 } 729 730 if (ret_val == 0) --- 9 unchanged lines hidden (view full) --- 740 * Description: 741 * Remove an interface entry from the unlabeled connection hash table if it is 742 * empty. An interface entry is considered to be empty if there are no 743 * address entries assigned to it. 744 * 745 */ 746static void netlbl_unlhsh_condremove_iface(struct netlbl_unlhsh_iface *iface) 747{ |
839 struct netlbl_unlhsh_addr4 *iter4; 840 struct netlbl_unlhsh_addr6 *iter6; | 748 struct netlbl_af4list *iter4; 749#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 750 struct netlbl_af6list *iter6; 751#endif /* IPv6 */ |
841 842 spin_lock(&netlbl_unlhsh_lock); | 752 753 spin_lock(&netlbl_unlhsh_lock); |
843 list_for_each_entry_rcu(iter4, &iface->addr4_list, list) 844 if (iter4->valid) 845 goto unlhsh_condremove_failure; 846 list_for_each_entry_rcu(iter6, &iface->addr6_list, list) 847 if (iter6->valid) 848 goto unlhsh_condremove_failure; | 754 netlbl_af4list_foreach_rcu(iter4, &iface->addr4_list) 755 goto unlhsh_condremove_failure; 756#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 757 netlbl_af6list_foreach_rcu(iter6, &iface->addr6_list) 758 goto unlhsh_condremove_failure; 759#endif /* IPv6 */ |
849 iface->valid = 0; 850 if (iface->ifindex > 0) 851 list_del_rcu(&iface->list); 852 else 853 rcu_assign_pointer(netlbl_unlhsh_def, NULL); 854 spin_unlock(&netlbl_unlhsh_lock); 855 856 call_rcu(&iface->rcu, netlbl_unlhsh_free_iface); --- 487 unchanged lines hidden (view full) --- 1344 dev_put(dev); 1345 if (ret_val != 0) 1346 goto list_cb_failure; 1347 } 1348 1349 if (addr4) { 1350 struct in_addr addr_struct; 1351 | 760 iface->valid = 0; 761 if (iface->ifindex > 0) 762 list_del_rcu(&iface->list); 763 else 764 rcu_assign_pointer(netlbl_unlhsh_def, NULL); 765 spin_unlock(&netlbl_unlhsh_lock); 766 767 call_rcu(&iface->rcu, netlbl_unlhsh_free_iface); --- 487 unchanged lines hidden (view full) --- 1255 dev_put(dev); 1256 if (ret_val != 0) 1257 goto list_cb_failure; 1258 } 1259 1260 if (addr4) { 1261 struct in_addr addr_struct; 1262 |
1352 addr_struct.s_addr = addr4->addr; | 1263 addr_struct.s_addr = addr4->list.addr; |
1353 ret_val = nla_put(cb_arg->skb, 1354 NLBL_UNLABEL_A_IPV4ADDR, 1355 sizeof(struct in_addr), 1356 &addr_struct); 1357 if (ret_val != 0) 1358 goto list_cb_failure; 1359 | 1264 ret_val = nla_put(cb_arg->skb, 1265 NLBL_UNLABEL_A_IPV4ADDR, 1266 sizeof(struct in_addr), 1267 &addr_struct); 1268 if (ret_val != 0) 1269 goto list_cb_failure; 1270 |
1360 addr_struct.s_addr = addr4->mask; | 1271 addr_struct.s_addr = addr4->list.mask; |
1361 ret_val = nla_put(cb_arg->skb, 1362 NLBL_UNLABEL_A_IPV4MASK, 1363 sizeof(struct in_addr), 1364 &addr_struct); 1365 if (ret_val != 0) 1366 goto list_cb_failure; 1367 1368 secid = addr4->secid; 1369 } else { 1370 ret_val = nla_put(cb_arg->skb, 1371 NLBL_UNLABEL_A_IPV6ADDR, 1372 sizeof(struct in6_addr), | 1272 ret_val = nla_put(cb_arg->skb, 1273 NLBL_UNLABEL_A_IPV4MASK, 1274 sizeof(struct in_addr), 1275 &addr_struct); 1276 if (ret_val != 0) 1277 goto list_cb_failure; 1278 1279 secid = addr4->secid; 1280 } else { 1281 ret_val = nla_put(cb_arg->skb, 1282 NLBL_UNLABEL_A_IPV6ADDR, 1283 sizeof(struct in6_addr), |
1373 &addr6->addr); | 1284 &addr6->list.addr); |
1374 if (ret_val != 0) 1375 goto list_cb_failure; 1376 1377 ret_val = nla_put(cb_arg->skb, 1378 NLBL_UNLABEL_A_IPV6MASK, 1379 sizeof(struct in6_addr), | 1285 if (ret_val != 0) 1286 goto list_cb_failure; 1287 1288 ret_val = nla_put(cb_arg->skb, 1289 NLBL_UNLABEL_A_IPV6MASK, 1290 sizeof(struct in6_addr), |
1380 &addr6->mask); | 1291 &addr6->list.mask); |
1381 if (ret_val != 0) 1382 goto list_cb_failure; 1383 1384 secid = addr6->secid; 1385 } 1386 1387 ret_val = security_secid_to_secctx(secid, &secctx, &secctx_len); 1388 if (ret_val != 0) --- 31 unchanged lines hidden (view full) --- 1420 struct netlbl_unlhsh_walk_arg cb_arg; 1421 u32 skip_bkt = cb->args[0]; 1422 u32 skip_chain = cb->args[1]; 1423 u32 skip_addr4 = cb->args[2]; 1424 u32 skip_addr6 = cb->args[3]; 1425 u32 iter_bkt; 1426 u32 iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0; 1427 struct netlbl_unlhsh_iface *iface; | 1292 if (ret_val != 0) 1293 goto list_cb_failure; 1294 1295 secid = addr6->secid; 1296 } 1297 1298 ret_val = security_secid_to_secctx(secid, &secctx, &secctx_len); 1299 if (ret_val != 0) --- 31 unchanged lines hidden (view full) --- 1331 struct netlbl_unlhsh_walk_arg cb_arg; 1332 u32 skip_bkt = cb->args[0]; 1333 u32 skip_chain = cb->args[1]; 1334 u32 skip_addr4 = cb->args[2]; 1335 u32 skip_addr6 = cb->args[3]; 1336 u32 iter_bkt; 1337 u32 iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0; 1338 struct netlbl_unlhsh_iface *iface; |
1428 struct netlbl_unlhsh_addr4 *addr4; 1429 struct netlbl_unlhsh_addr6 *addr6; | |
1430 struct list_head *iter_list; | 1339 struct list_head *iter_list; |
1340 struct netlbl_af4list *addr4; 1341#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1342 struct netlbl_af6list *addr6; 1343#endif |
|
1431 1432 cb_arg.nl_cb = cb; 1433 cb_arg.skb = skb; 1434 cb_arg.seq = cb->nlh->nlmsg_seq; 1435 1436 rcu_read_lock(); 1437 for (iter_bkt = skip_bkt; 1438 iter_bkt < rcu_dereference(netlbl_unlhsh)->size; 1439 iter_bkt++, iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0) { 1440 iter_list = &rcu_dereference(netlbl_unlhsh)->tbl[iter_bkt]; 1441 list_for_each_entry_rcu(iface, iter_list, list) { 1442 if (!iface->valid || 1443 iter_chain++ < skip_chain) 1444 continue; | 1344 1345 cb_arg.nl_cb = cb; 1346 cb_arg.skb = skb; 1347 cb_arg.seq = cb->nlh->nlmsg_seq; 1348 1349 rcu_read_lock(); 1350 for (iter_bkt = skip_bkt; 1351 iter_bkt < rcu_dereference(netlbl_unlhsh)->size; 1352 iter_bkt++, iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0) { 1353 iter_list = &rcu_dereference(netlbl_unlhsh)->tbl[iter_bkt]; 1354 list_for_each_entry_rcu(iface, iter_list, list) { 1355 if (!iface->valid || 1356 iter_chain++ < skip_chain) 1357 continue; |
1445 list_for_each_entry_rcu(addr4, 1446 &iface->addr4_list, 1447 list) { 1448 if (!addr4->valid || iter_addr4++ < skip_addr4) | 1358 netlbl_af4list_foreach_rcu(addr4, 1359 &iface->addr4_list) { 1360 if (iter_addr4++ < skip_addr4) |
1449 continue; 1450 if (netlbl_unlabel_staticlist_gen( | 1361 continue; 1362 if (netlbl_unlabel_staticlist_gen( |
1451 NLBL_UNLABEL_C_STATICLIST, 1452 iface, 1453 addr4, 1454 NULL, 1455 &cb_arg) < 0) { | 1363 NLBL_UNLABEL_C_STATICLIST, 1364 iface, 1365 netlbl_unlhsh_addr4_entry(addr4), 1366 NULL, 1367 &cb_arg) < 0) { |
1456 iter_addr4--; 1457 iter_chain--; 1458 goto unlabel_staticlist_return; 1459 } 1460 } | 1368 iter_addr4--; 1369 iter_chain--; 1370 goto unlabel_staticlist_return; 1371 } 1372 } |
1461 list_for_each_entry_rcu(addr6, 1462 &iface->addr6_list, 1463 list) { 1464 if (!addr6->valid || iter_addr6++ < skip_addr6) | 1373#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1374 netlbl_af6list_foreach_rcu(addr6, 1375 &iface->addr6_list) { 1376 if (iter_addr6++ < skip_addr6) |
1465 continue; 1466 if (netlbl_unlabel_staticlist_gen( | 1377 continue; 1378 if (netlbl_unlabel_staticlist_gen( |
1467 NLBL_UNLABEL_C_STATICLIST, 1468 iface, 1469 NULL, 1470 addr6, 1471 &cb_arg) < 0) { | 1379 NLBL_UNLABEL_C_STATICLIST, 1380 iface, 1381 NULL, 1382 netlbl_unlhsh_addr6_entry(addr6), 1383 &cb_arg) < 0) { |
1472 iter_addr6--; 1473 iter_chain--; 1474 goto unlabel_staticlist_return; 1475 } 1476 } | 1384 iter_addr6--; 1385 iter_chain--; 1386 goto unlabel_staticlist_return; 1387 } 1388 } |
1389#endif /* IPv6 */ |
|
1477 } 1478 } 1479 1480unlabel_staticlist_return: 1481 rcu_read_unlock(); 1482 cb->args[0] = skip_bkt; 1483 cb->args[1] = skip_chain; 1484 cb->args[2] = skip_addr4; --- 14 unchanged lines hidden (view full) --- 1499 */ 1500static int netlbl_unlabel_staticlistdef(struct sk_buff *skb, 1501 struct netlink_callback *cb) 1502{ 1503 struct netlbl_unlhsh_walk_arg cb_arg; 1504 struct netlbl_unlhsh_iface *iface; 1505 u32 skip_addr4 = cb->args[0]; 1506 u32 skip_addr6 = cb->args[1]; | 1390 } 1391 } 1392 1393unlabel_staticlist_return: 1394 rcu_read_unlock(); 1395 cb->args[0] = skip_bkt; 1396 cb->args[1] = skip_chain; 1397 cb->args[2] = skip_addr4; --- 14 unchanged lines hidden (view full) --- 1412 */ 1413static int netlbl_unlabel_staticlistdef(struct sk_buff *skb, 1414 struct netlink_callback *cb) 1415{ 1416 struct netlbl_unlhsh_walk_arg cb_arg; 1417 struct netlbl_unlhsh_iface *iface; 1418 u32 skip_addr4 = cb->args[0]; 1419 u32 skip_addr6 = cb->args[1]; |
1507 u32 iter_addr4 = 0, iter_addr6 = 0; 1508 struct netlbl_unlhsh_addr4 *addr4; 1509 struct netlbl_unlhsh_addr6 *addr6; | 1420 u32 iter_addr4 = 0; 1421 struct netlbl_af4list *addr4; 1422#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1423 u32 iter_addr6 = 0; 1424 struct netlbl_af6list *addr6; 1425#endif |
1510 1511 cb_arg.nl_cb = cb; 1512 cb_arg.skb = skb; 1513 cb_arg.seq = cb->nlh->nlmsg_seq; 1514 1515 rcu_read_lock(); 1516 iface = rcu_dereference(netlbl_unlhsh_def); 1517 if (iface == NULL || !iface->valid) 1518 goto unlabel_staticlistdef_return; 1519 | 1426 1427 cb_arg.nl_cb = cb; 1428 cb_arg.skb = skb; 1429 cb_arg.seq = cb->nlh->nlmsg_seq; 1430 1431 rcu_read_lock(); 1432 iface = rcu_dereference(netlbl_unlhsh_def); 1433 if (iface == NULL || !iface->valid) 1434 goto unlabel_staticlistdef_return; 1435 |
1520 list_for_each_entry_rcu(addr4, &iface->addr4_list, list) { 1521 if (!addr4->valid || iter_addr4++ < skip_addr4) | 1436 netlbl_af4list_foreach_rcu(addr4, &iface->addr4_list) { 1437 if (iter_addr4++ < skip_addr4) |
1522 continue; 1523 if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF, | 1438 continue; 1439 if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF, |
1524 iface, 1525 addr4, 1526 NULL, 1527 &cb_arg) < 0) { | 1440 iface, 1441 netlbl_unlhsh_addr4_entry(addr4), 1442 NULL, 1443 &cb_arg) < 0) { |
1528 iter_addr4--; 1529 goto unlabel_staticlistdef_return; 1530 } 1531 } | 1444 iter_addr4--; 1445 goto unlabel_staticlistdef_return; 1446 } 1447 } |
1532 list_for_each_entry_rcu(addr6, &iface->addr6_list, list) { 1533 if (!addr6->valid || iter_addr6++ < skip_addr6) | 1448#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1449 netlbl_af6list_foreach_rcu(addr6, &iface->addr6_list) { 1450 if (iter_addr6++ < skip_addr6) |
1534 continue; 1535 if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF, | 1451 continue; 1452 if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF, |
1536 iface, 1537 NULL, 1538 addr6, 1539 &cb_arg) < 0) { | 1453 iface, 1454 NULL, 1455 netlbl_unlhsh_addr6_entry(addr6), 1456 &cb_arg) < 0) { |
1540 iter_addr6--; 1541 goto unlabel_staticlistdef_return; 1542 } 1543 } | 1457 iter_addr6--; 1458 goto unlabel_staticlistdef_return; 1459 } 1460 } |
1461#endif /* IPv6 */ |
|
1544 1545unlabel_staticlistdef_return: 1546 rcu_read_unlock(); 1547 cb->args[0] = skip_addr4; 1548 cb->args[1] = skip_addr6; 1549 return skb->len; 1550} 1551 --- 161 unchanged lines hidden (view full) --- 1713 1714 rcu_read_lock(); 1715 iface = netlbl_unlhsh_search_iface_def(skb->iif); 1716 if (iface == NULL) 1717 goto unlabel_getattr_nolabel; 1718 switch (family) { 1719 case PF_INET: { 1720 struct iphdr *hdr4; | 1462 1463unlabel_staticlistdef_return: 1464 rcu_read_unlock(); 1465 cb->args[0] = skip_addr4; 1466 cb->args[1] = skip_addr6; 1467 return skb->len; 1468} 1469 --- 161 unchanged lines hidden (view full) --- 1631 1632 rcu_read_lock(); 1633 iface = netlbl_unlhsh_search_iface_def(skb->iif); 1634 if (iface == NULL) 1635 goto unlabel_getattr_nolabel; 1636 switch (family) { 1637 case PF_INET: { 1638 struct iphdr *hdr4; |
1721 struct netlbl_unlhsh_addr4 *addr4; | 1639 struct netlbl_af4list *addr4; |
1722 1723 hdr4 = ip_hdr(skb); | 1640 1641 hdr4 = ip_hdr(skb); |
1724 addr4 = netlbl_unlhsh_search_addr4(hdr4->saddr, iface); | 1642 addr4 = netlbl_af4list_search(hdr4->saddr, 1643 &iface->addr4_list); |
1725 if (addr4 == NULL) 1726 goto unlabel_getattr_nolabel; | 1644 if (addr4 == NULL) 1645 goto unlabel_getattr_nolabel; |
1727 secattr->attr.secid = addr4->secid; | 1646 secattr->attr.secid = netlbl_unlhsh_addr4_entry(addr4)->secid; |
1728 break; 1729 } 1730#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1731 case PF_INET6: { 1732 struct ipv6hdr *hdr6; | 1647 break; 1648 } 1649#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1650 case PF_INET6: { 1651 struct ipv6hdr *hdr6; |
1733 struct netlbl_unlhsh_addr6 *addr6; | 1652 struct netlbl_af6list *addr6; |
1734 1735 hdr6 = ipv6_hdr(skb); | 1653 1654 hdr6 = ipv6_hdr(skb); |
1736 addr6 = netlbl_unlhsh_search_addr6(&hdr6->saddr, iface); | 1655 addr6 = netlbl_af6list_search(&hdr6->saddr, 1656 &iface->addr6_list); |
1737 if (addr6 == NULL) 1738 goto unlabel_getattr_nolabel; | 1657 if (addr6 == NULL) 1658 goto unlabel_getattr_nolabel; |
1739 secattr->attr.secid = addr6->secid; | 1659 secattr->attr.secid = netlbl_unlhsh_addr6_entry(addr6)->secid; |
1740 break; 1741 } 1742#endif /* IPv6 */ 1743 default: 1744 goto unlabel_getattr_nolabel; 1745 } 1746 rcu_read_unlock(); 1747 --- 45 unchanged lines hidden --- | 1660 break; 1661 } 1662#endif /* IPv6 */ 1663 default: 1664 goto unlabel_getattr_nolabel; 1665 } 1666 rcu_read_unlock(); 1667 --- 45 unchanged lines hidden --- |