diff options
Diffstat (limited to 'net/netlabel')
-rw-r--r-- | net/netlabel/netlabel_kapi.c | 152 |
1 files changed, 132 insertions, 20 deletions
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index fd9229db075c..cae2f5f4cac0 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c | |||
@@ -619,8 +619,9 @@ int netlbl_enabled(void) | |||
619 | } | 619 | } |
620 | 620 | ||
621 | /** | 621 | /** |
622 | * netlbl_socket_setattr - Label a socket using the correct protocol | 622 | * netlbl_sock_setattr - Label a socket using the correct protocol |
623 | * @sk: the socket to label | 623 | * @sk: the socket to label |
624 | * @family: protocol family | ||
624 | * @secattr: the security attributes | 625 | * @secattr: the security attributes |
625 | * | 626 | * |
626 | * Description: | 627 | * Description: |
@@ -633,29 +634,45 @@ int netlbl_enabled(void) | |||
633 | * | 634 | * |
634 | */ | 635 | */ |
635 | int netlbl_sock_setattr(struct sock *sk, | 636 | int netlbl_sock_setattr(struct sock *sk, |
637 | u16 family, | ||
636 | const struct netlbl_lsm_secattr *secattr) | 638 | const struct netlbl_lsm_secattr *secattr) |
637 | { | 639 | { |
638 | int ret_val = -ENOENT; | 640 | int ret_val; |
639 | struct netlbl_dom_map *dom_entry; | 641 | struct netlbl_dom_map *dom_entry; |
640 | 642 | ||
641 | rcu_read_lock(); | 643 | rcu_read_lock(); |
642 | dom_entry = netlbl_domhsh_getentry(secattr->domain); | 644 | dom_entry = netlbl_domhsh_getentry(secattr->domain); |
643 | if (dom_entry == NULL) | 645 | if (dom_entry == NULL) { |
646 | ret_val = -ENOENT; | ||
644 | goto socket_setattr_return; | 647 | goto socket_setattr_return; |
645 | switch (dom_entry->type) { | 648 | } |
646 | case NETLBL_NLTYPE_ADDRSELECT: | 649 | switch (family) { |
647 | ret_val = -EDESTADDRREQ; | 650 | case AF_INET: |
648 | break; | 651 | switch (dom_entry->type) { |
649 | case NETLBL_NLTYPE_CIPSOV4: | 652 | case NETLBL_NLTYPE_ADDRSELECT: |
650 | ret_val = cipso_v4_sock_setattr(sk, | 653 | ret_val = -EDESTADDRREQ; |
651 | dom_entry->type_def.cipsov4, | 654 | break; |
652 | secattr); | 655 | case NETLBL_NLTYPE_CIPSOV4: |
656 | ret_val = cipso_v4_sock_setattr(sk, | ||
657 | dom_entry->type_def.cipsov4, | ||
658 | secattr); | ||
659 | break; | ||
660 | case NETLBL_NLTYPE_UNLABELED: | ||
661 | ret_val = 0; | ||
662 | break; | ||
663 | default: | ||
664 | ret_val = -ENOENT; | ||
665 | } | ||
653 | break; | 666 | break; |
654 | case NETLBL_NLTYPE_UNLABELED: | 667 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
668 | case AF_INET6: | ||
669 | /* since we don't support any IPv6 labeling protocols right | ||
670 | * now we can optimize everything away until we do */ | ||
655 | ret_val = 0; | 671 | ret_val = 0; |
656 | break; | 672 | break; |
673 | #endif /* IPv6 */ | ||
657 | default: | 674 | default: |
658 | ret_val = -ENOENT; | 675 | ret_val = -EPROTONOSUPPORT; |
659 | } | 676 | } |
660 | 677 | ||
661 | socket_setattr_return: | 678 | socket_setattr_return: |
@@ -689,9 +706,25 @@ void netlbl_sock_delattr(struct sock *sk) | |||
689 | * on failure. | 706 | * on failure. |
690 | * | 707 | * |
691 | */ | 708 | */ |
692 | int netlbl_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr) | 709 | int netlbl_sock_getattr(struct sock *sk, |
710 | struct netlbl_lsm_secattr *secattr) | ||
693 | { | 711 | { |
694 | return cipso_v4_sock_getattr(sk, secattr); | 712 | int ret_val; |
713 | |||
714 | switch (sk->sk_family) { | ||
715 | case AF_INET: | ||
716 | ret_val = cipso_v4_sock_getattr(sk, secattr); | ||
717 | break; | ||
718 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
719 | case AF_INET6: | ||
720 | ret_val = -ENOMSG; | ||
721 | break; | ||
722 | #endif /* IPv6 */ | ||
723 | default: | ||
724 | ret_val = -EPROTONOSUPPORT; | ||
725 | } | ||
726 | |||
727 | return ret_val; | ||
695 | } | 728 | } |
696 | 729 | ||
697 | /** | 730 | /** |
@@ -748,7 +781,7 @@ int netlbl_conn_setattr(struct sock *sk, | |||
748 | break; | 781 | break; |
749 | #endif /* IPv6 */ | 782 | #endif /* IPv6 */ |
750 | default: | 783 | default: |
751 | ret_val = 0; | 784 | ret_val = -EPROTONOSUPPORT; |
752 | } | 785 | } |
753 | 786 | ||
754 | conn_setattr_return: | 787 | conn_setattr_return: |
@@ -757,6 +790,77 @@ conn_setattr_return: | |||
757 | } | 790 | } |
758 | 791 | ||
759 | /** | 792 | /** |
793 | * netlbl_req_setattr - Label a request socket using the correct protocol | ||
794 | * @req: the request socket to label | ||
795 | * @secattr: the security attributes | ||
796 | * | ||
797 | * Description: | ||
798 | * Attach the correct label to the given socket using the security attributes | ||
799 | * specified in @secattr. Returns zero on success, negative values on failure. | ||
800 | * | ||
801 | */ | ||
802 | int netlbl_req_setattr(struct request_sock *req, | ||
803 | const struct netlbl_lsm_secattr *secattr) | ||
804 | { | ||
805 | int ret_val; | ||
806 | struct netlbl_dom_map *dom_entry; | ||
807 | struct netlbl_domaddr4_map *af4_entry; | ||
808 | u32 proto_type; | ||
809 | struct cipso_v4_doi *proto_cv4; | ||
810 | |||
811 | rcu_read_lock(); | ||
812 | dom_entry = netlbl_domhsh_getentry(secattr->domain); | ||
813 | if (dom_entry == NULL) { | ||
814 | ret_val = -ENOENT; | ||
815 | goto req_setattr_return; | ||
816 | } | ||
817 | switch (req->rsk_ops->family) { | ||
818 | case AF_INET: | ||
819 | if (dom_entry->type == NETLBL_NLTYPE_ADDRSELECT) { | ||
820 | struct inet_request_sock *req_inet = inet_rsk(req); | ||
821 | af4_entry = netlbl_domhsh_getentry_af4(secattr->domain, | ||
822 | req_inet->rmt_addr); | ||
823 | if (af4_entry == NULL) { | ||
824 | ret_val = -ENOENT; | ||
825 | goto req_setattr_return; | ||
826 | } | ||
827 | proto_type = af4_entry->type; | ||
828 | proto_cv4 = af4_entry->type_def.cipsov4; | ||
829 | } else { | ||
830 | proto_type = dom_entry->type; | ||
831 | proto_cv4 = dom_entry->type_def.cipsov4; | ||
832 | } | ||
833 | switch (proto_type) { | ||
834 | case NETLBL_NLTYPE_CIPSOV4: | ||
835 | ret_val = cipso_v4_req_setattr(req, proto_cv4, secattr); | ||
836 | break; | ||
837 | case NETLBL_NLTYPE_UNLABELED: | ||
838 | /* just delete the protocols we support for right now | ||
839 | * but we could remove other protocols if needed */ | ||
840 | cipso_v4_req_delattr(req); | ||
841 | ret_val = 0; | ||
842 | break; | ||
843 | default: | ||
844 | ret_val = -ENOENT; | ||
845 | } | ||
846 | break; | ||
847 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
848 | case AF_INET6: | ||
849 | /* since we don't support any IPv6 labeling protocols right | ||
850 | * now we can optimize everything away until we do */ | ||
851 | ret_val = 0; | ||
852 | break; | ||
853 | #endif /* IPv6 */ | ||
854 | default: | ||
855 | ret_val = -EPROTONOSUPPORT; | ||
856 | } | ||
857 | |||
858 | req_setattr_return: | ||
859 | rcu_read_unlock(); | ||
860 | return ret_val; | ||
861 | } | ||
862 | |||
863 | /** | ||
760 | * netlbl_skbuff_setattr - Label a packet using the correct protocol | 864 | * netlbl_skbuff_setattr - Label a packet using the correct protocol |
761 | * @skb: the packet | 865 | * @skb: the packet |
762 | * @family: protocol family | 866 | * @family: protocol family |
@@ -808,7 +912,7 @@ int netlbl_skbuff_setattr(struct sk_buff *skb, | |||
808 | break; | 912 | break; |
809 | #endif /* IPv6 */ | 913 | #endif /* IPv6 */ |
810 | default: | 914 | default: |
811 | ret_val = 0; | 915 | ret_val = -EPROTONOSUPPORT; |
812 | } | 916 | } |
813 | 917 | ||
814 | skbuff_setattr_return: | 918 | skbuff_setattr_return: |
@@ -833,9 +937,17 @@ int netlbl_skbuff_getattr(const struct sk_buff *skb, | |||
833 | u16 family, | 937 | u16 family, |
834 | struct netlbl_lsm_secattr *secattr) | 938 | struct netlbl_lsm_secattr *secattr) |
835 | { | 939 | { |
836 | if (CIPSO_V4_OPTEXIST(skb) && | 940 | switch (family) { |
837 | cipso_v4_skbuff_getattr(skb, secattr) == 0) | 941 | case AF_INET: |
838 | return 0; | 942 | if (CIPSO_V4_OPTEXIST(skb) && |
943 | cipso_v4_skbuff_getattr(skb, secattr) == 0) | ||
944 | return 0; | ||
945 | break; | ||
946 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
947 | case AF_INET6: | ||
948 | break; | ||
949 | #endif /* IPv6 */ | ||
950 | } | ||
839 | 951 | ||
840 | return netlbl_unlabel_getattr(skb, family, secattr); | 952 | return netlbl_unlabel_getattr(skb, family, secattr); |
841 | } | 953 | } |