aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/cipso_ipv4.c130
-rw-r--r--net/netlabel/netlabel_kapi.c152
2 files changed, 250 insertions, 32 deletions
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index 7bc992976d29..039cc1ffe977 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -1942,23 +1942,85 @@ socket_setattr_failure:
1942} 1942}
1943 1943
1944/** 1944/**
1945 * cipso_v4_sock_delattr - Delete the CIPSO option from a socket 1945 * cipso_v4_req_setattr - Add a CIPSO option to a connection request socket
1946 * @sk: the socket 1946 * @req: the connection request socket
1947 * @doi_def: the CIPSO DOI to use
1948 * @secattr: the specific security attributes of the socket
1947 * 1949 *
1948 * Description: 1950 * Description:
1949 * Removes the CIPSO option from a socket, if present. 1951 * Set the CIPSO option on the given socket using the DOI definition and
1952 * security attributes passed to the function. Returns zero on success and
1953 * negative values on failure.
1950 * 1954 *
1951 */ 1955 */
1952void cipso_v4_sock_delattr(struct sock *sk) 1956int cipso_v4_req_setattr(struct request_sock *req,
1957 const struct cipso_v4_doi *doi_def,
1958 const struct netlbl_lsm_secattr *secattr)
1953{ 1959{
1954 u8 hdr_delta; 1960 int ret_val = -EPERM;
1955 struct ip_options *opt; 1961 unsigned char *buf = NULL;
1956 struct inet_sock *sk_inet; 1962 u32 buf_len;
1963 u32 opt_len;
1964 struct ip_options *opt = NULL;
1965 struct inet_request_sock *req_inet;
1957 1966
1958 sk_inet = inet_sk(sk); 1967 /* We allocate the maximum CIPSO option size here so we are probably
1959 opt = sk_inet->opt; 1968 * being a little wasteful, but it makes our life _much_ easier later
1960 if (opt == NULL || opt->cipso == 0) 1969 * on and after all we are only talking about 40 bytes. */
1961 return; 1970 buf_len = CIPSO_V4_OPT_LEN_MAX;
1971 buf = kmalloc(buf_len, GFP_ATOMIC);
1972 if (buf == NULL) {
1973 ret_val = -ENOMEM;
1974 goto req_setattr_failure;
1975 }
1976
1977 ret_val = cipso_v4_genopt(buf, buf_len, doi_def, secattr);
1978 if (ret_val < 0)
1979 goto req_setattr_failure;
1980 buf_len = ret_val;
1981
1982 /* We can't use ip_options_get() directly because it makes a call to
1983 * ip_options_get_alloc() which allocates memory with GFP_KERNEL and
1984 * we won't always have CAP_NET_RAW even though we _always_ want to
1985 * set the IPOPT_CIPSO option. */
1986 opt_len = (buf_len + 3) & ~3;
1987 opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC);
1988 if (opt == NULL) {
1989 ret_val = -ENOMEM;
1990 goto req_setattr_failure;
1991 }
1992 memcpy(opt->__data, buf, buf_len);
1993 opt->optlen = opt_len;
1994 opt->cipso = sizeof(struct iphdr);
1995 kfree(buf);
1996 buf = NULL;
1997
1998 req_inet = inet_rsk(req);
1999 opt = xchg(&req_inet->opt, opt);
2000 kfree(opt);
2001
2002 return 0;
2003
2004req_setattr_failure:
2005 kfree(buf);
2006 kfree(opt);
2007 return ret_val;
2008}
2009
2010/**
2011 * cipso_v4_delopt - Delete the CIPSO option from a set of IP options
2012 * @opt_ptr: IP option pointer
2013 *
2014 * Description:
2015 * Deletes the CIPSO IP option from a set of IP options and makes the necessary
2016 * adjustments to the IP option structure. Returns zero on success, negative
2017 * values on failure.
2018 *
2019 */
2020int cipso_v4_delopt(struct ip_options **opt_ptr)
2021{
2022 int hdr_delta = 0;
2023 struct ip_options *opt = *opt_ptr;
1962 2024
1963 if (opt->srr || opt->rr || opt->ts || opt->router_alert) { 2025 if (opt->srr || opt->rr || opt->ts || opt->router_alert) {
1964 u8 cipso_len; 2026 u8 cipso_len;
@@ -2003,11 +2065,34 @@ void cipso_v4_sock_delattr(struct sock *sk)
2003 } else { 2065 } else {
2004 /* only the cipso option was present on the socket so we can 2066 /* only the cipso option was present on the socket so we can
2005 * remove the entire option struct */ 2067 * remove the entire option struct */
2006 sk_inet->opt = NULL; 2068 *opt_ptr = NULL;
2007 hdr_delta = opt->optlen; 2069 hdr_delta = opt->optlen;
2008 kfree(opt); 2070 kfree(opt);
2009 } 2071 }
2010 2072
2073 return hdr_delta;
2074}
2075
2076/**
2077 * cipso_v4_sock_delattr - Delete the CIPSO option from a socket
2078 * @sk: the socket
2079 *
2080 * Description:
2081 * Removes the CIPSO option from a socket, if present.
2082 *
2083 */
2084void cipso_v4_sock_delattr(struct sock *sk)
2085{
2086 int hdr_delta;
2087 struct ip_options *opt;
2088 struct inet_sock *sk_inet;
2089
2090 sk_inet = inet_sk(sk);
2091 opt = sk_inet->opt;
2092 if (opt == NULL || opt->cipso == 0)
2093 return;
2094
2095 hdr_delta = cipso_v4_delopt(&sk_inet->opt);
2011 if (sk_inet->is_icsk && hdr_delta > 0) { 2096 if (sk_inet->is_icsk && hdr_delta > 0) {
2012 struct inet_connection_sock *sk_conn = inet_csk(sk); 2097 struct inet_connection_sock *sk_conn = inet_csk(sk);
2013 sk_conn->icsk_ext_hdr_len -= hdr_delta; 2098 sk_conn->icsk_ext_hdr_len -= hdr_delta;
@@ -2016,6 +2101,27 @@ void cipso_v4_sock_delattr(struct sock *sk)
2016} 2101}
2017 2102
2018/** 2103/**
2104 * cipso_v4_req_delattr - Delete the CIPSO option from a request socket
2105 * @reg: the request socket
2106 *
2107 * Description:
2108 * Removes the CIPSO option from a request socket, if present.
2109 *
2110 */
2111void cipso_v4_req_delattr(struct request_sock *req)
2112{
2113 struct ip_options *opt;
2114 struct inet_request_sock *req_inet;
2115
2116 req_inet = inet_rsk(req);
2117 opt = req_inet->opt;
2118 if (opt == NULL || opt->cipso == 0)
2119 return;
2120
2121 cipso_v4_delopt(&req_inet->opt);
2122}
2123
2124/**
2019 * cipso_v4_getattr - Helper function for the cipso_v4_*_getattr functions 2125 * cipso_v4_getattr - Helper function for the cipso_v4_*_getattr functions
2020 * @cipso: the CIPSO v4 option 2126 * @cipso: the CIPSO v4 option
2021 * @secattr: the security attributes 2127 * @secattr: the security attributes
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 */
635int netlbl_sock_setattr(struct sock *sk, 636int 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
661socket_setattr_return: 678socket_setattr_return:
@@ -689,9 +706,25 @@ void netlbl_sock_delattr(struct sock *sk)
689 * on failure. 706 * on failure.
690 * 707 *
691 */ 708 */
692int netlbl_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr) 709int 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
754conn_setattr_return: 787conn_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 */
802int 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
858req_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
814skbuff_setattr_return: 918skbuff_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}