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 ---