aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/smack/smack.h11
-rw-r--r--security/smack/smack_lsm.c348
2 files changed, 319 insertions, 40 deletions
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 8ad30955e15d..bb28e099abfe 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -94,6 +94,17 @@ struct smk_netlbladdr {
94}; 94};
95 95
96/* 96/*
97 * An entry in the table identifying ports.
98 */
99struct smk_port_label {
100 struct list_head list;
101 struct sock *smk_sock; /* socket initialized on */
102 unsigned short smk_port; /* the port number */
103 char *smk_in; /* incoming label */
104 char *smk_out; /* outgoing label */
105};
106
107/*
97 * This is the repository for labels seen so that it is 108 * This is the repository for labels seen so that it is
98 * not necessary to keep allocating tiny chuncks of memory 109 * not necessary to keep allocating tiny chuncks of memory
99 * and so that they can be shared. 110 * and so that they can be shared.
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index d52c780bdb78..609e89de3c24 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -27,10 +27,13 @@
27#include <linux/ip.h> 27#include <linux/ip.h>
28#include <linux/tcp.h> 28#include <linux/tcp.h>
29#include <linux/udp.h> 29#include <linux/udp.h>
30#include <linux/dccp.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
31#include <linux/mutex.h> 32#include <linux/mutex.h>
32#include <linux/pipe_fs_i.h> 33#include <linux/pipe_fs_i.h>
33#include <net/cipso_ipv4.h> 34#include <net/cipso_ipv4.h>
35#include <net/ip.h>
36#include <net/ipv6.h>
34#include <linux/audit.h> 37#include <linux/audit.h>
35#include <linux/magic.h> 38#include <linux/magic.h>
36#include <linux/dcache.h> 39#include <linux/dcache.h>
@@ -45,6 +48,12 @@
45#define TRANS_TRUE "TRUE" 48#define TRANS_TRUE "TRUE"
46#define TRANS_TRUE_SIZE 4 49#define TRANS_TRUE_SIZE 4
47 50
51#define SMK_CONNECTING 0
52#define SMK_RECEIVING 1
53#define SMK_SENDING 2
54
55LIST_HEAD(smk_ipv6_port_list);
56
48/** 57/**
49 * smk_fetch - Fetch the smack label from a file. 58 * smk_fetch - Fetch the smack label from a file.
50 * @ip: a pointer to the inode 59 * @ip: a pointer to the inode
@@ -1878,6 +1887,155 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
1878} 1887}
1879 1888
1880/** 1889/**
1890 * smk_ipv6_port_label - Smack port access table management
1891 * @sock: socket
1892 * @address: address
1893 *
1894 * Create or update the port list entry
1895 */
1896static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address)
1897{
1898 struct sock *sk = sock->sk;
1899 struct sockaddr_in6 *addr6;
1900 struct socket_smack *ssp = sock->sk->sk_security;
1901 struct smk_port_label *spp;
1902 unsigned short port = 0;
1903
1904 if (address == NULL) {
1905 /*
1906 * This operation is changing the Smack information
1907 * on the bound socket. Take the changes to the port
1908 * as well.
1909 */
1910 list_for_each_entry(spp, &smk_ipv6_port_list, list) {
1911 if (sk != spp->smk_sock)
1912 continue;
1913 spp->smk_in = ssp->smk_in;
1914 spp->smk_out = ssp->smk_out;
1915 return;
1916 }
1917 /*
1918 * A NULL address is only used for updating existing
1919 * bound entries. If there isn't one, it's OK.
1920 */
1921 return;
1922 }
1923
1924 addr6 = (struct sockaddr_in6 *)address;
1925 port = ntohs(addr6->sin6_port);
1926 /*
1927 * This is a special case that is safely ignored.
1928 */
1929 if (port == 0)
1930 return;
1931
1932 /*
1933 * Look for an existing port list entry.
1934 * This is an indication that a port is getting reused.
1935 */
1936 list_for_each_entry(spp, &smk_ipv6_port_list, list) {
1937 if (spp->smk_port != port)
1938 continue;
1939 spp->smk_port = port;
1940 spp->smk_sock = sk;
1941 spp->smk_in = ssp->smk_in;
1942 spp->smk_out = ssp->smk_out;
1943 return;
1944 }
1945
1946 /*
1947 * A new port entry is required.
1948 */
1949 spp = kzalloc(sizeof(*spp), GFP_KERNEL);
1950 if (spp == NULL)
1951 return;
1952
1953 spp->smk_port = port;
1954 spp->smk_sock = sk;
1955 spp->smk_in = ssp->smk_in;
1956 spp->smk_out = ssp->smk_out;
1957
1958 list_add(&spp->list, &smk_ipv6_port_list);
1959 return;
1960}
1961
1962/**
1963 * smk_ipv6_port_check - check Smack port access
1964 * @sock: socket
1965 * @address: address
1966 *
1967 * Create or update the port list entry
1968 */
1969static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address,
1970 int act)
1971{
1972 __be16 *bep;
1973 __be32 *be32p;
1974 struct sockaddr_in6 *addr6;
1975 struct smk_port_label *spp;
1976 struct socket_smack *ssp = sk->sk_security;
1977 unsigned short port = 0;
1978 char *subject;
1979 char *object;
1980 struct smk_audit_info ad;
1981#ifdef CONFIG_AUDIT
1982 struct lsm_network_audit net;
1983#endif
1984
1985 if (act == SMK_RECEIVING) {
1986 subject = smack_net_ambient;
1987 object = ssp->smk_in;
1988 } else {
1989 subject = ssp->smk_out;
1990 object = smack_net_ambient;
1991 }
1992
1993 /*
1994 * Get the IP address and port from the address.
1995 */
1996 addr6 = (struct sockaddr_in6 *)address;
1997 port = ntohs(addr6->sin6_port);
1998 bep = (__be16 *)(&addr6->sin6_addr);
1999 be32p = (__be32 *)(&addr6->sin6_addr);
2000
2001 /*
2002 * It's remote, so port lookup does no good.
2003 */
2004 if (be32p[0] || be32p[1] || be32p[2] || bep[6] || ntohs(bep[7]) != 1)
2005 goto auditout;
2006
2007 /*
2008 * It's local so the send check has to have passed.
2009 */
2010 if (act == SMK_RECEIVING) {
2011 subject = smack_known_web.smk_known;
2012 goto auditout;
2013 }
2014
2015 list_for_each_entry(spp, &smk_ipv6_port_list, list) {
2016 if (spp->smk_port != port)
2017 continue;
2018 object = spp->smk_in;
2019 if (act == SMK_CONNECTING)
2020 ssp->smk_packet = spp->smk_out;
2021 break;
2022 }
2023
2024auditout:
2025
2026#ifdef CONFIG_AUDIT
2027 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
2028 ad.a.u.net->family = sk->sk_family;
2029 ad.a.u.net->dport = port;
2030 if (act == SMK_RECEIVING)
2031 ad.a.u.net->v6info.saddr = addr6->sin6_addr;
2032 else
2033 ad.a.u.net->v6info.daddr = addr6->sin6_addr;
2034#endif
2035 return smk_access(subject, object, MAY_WRITE, &ad);
2036}
2037
2038/**
1881 * smack_inode_setsecurity - set smack xattrs 2039 * smack_inode_setsecurity - set smack xattrs
1882 * @inode: the object 2040 * @inode: the object
1883 * @name: attribute name 2041 * @name: attribute name
@@ -1926,7 +2084,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
1926 ssp->smk_in = sp; 2084 ssp->smk_in = sp;
1927 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { 2085 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
1928 ssp->smk_out = sp; 2086 ssp->smk_out = sp;
1929 if (sock->sk->sk_family != PF_UNIX) { 2087 if (sock->sk->sk_family == PF_INET) {
1930 rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); 2088 rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
1931 if (rc != 0) 2089 if (rc != 0)
1932 printk(KERN_WARNING 2090 printk(KERN_WARNING
@@ -1936,6 +2094,9 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
1936 } else 2094 } else
1937 return -EOPNOTSUPP; 2095 return -EOPNOTSUPP;
1938 2096
2097 if (sock->sk->sk_family == PF_INET6)
2098 smk_ipv6_port_label(sock, NULL);
2099
1939 return 0; 2100 return 0;
1940} 2101}
1941 2102
@@ -1963,6 +2124,25 @@ static int smack_socket_post_create(struct socket *sock, int family,
1963} 2124}
1964 2125
1965/** 2126/**
2127 * smack_socket_bind - record port binding information.
2128 * @sock: the socket
2129 * @address: the port address
2130 * @addrlen: size of the address
2131 *
2132 * Records the label bound to a port.
2133 *
2134 * Returns 0
2135 */
2136static int smack_socket_bind(struct socket *sock, struct sockaddr *address,
2137 int addrlen)
2138{
2139 if (sock->sk != NULL && sock->sk->sk_family == PF_INET6)
2140 smk_ipv6_port_label(sock, address);
2141
2142 return 0;
2143}
2144
2145/**
1966 * smack_socket_connect - connect access check 2146 * smack_socket_connect - connect access check
1967 * @sock: the socket 2147 * @sock: the socket
1968 * @sap: the other end 2148 * @sap: the other end
@@ -1975,12 +2155,24 @@ static int smack_socket_post_create(struct socket *sock, int family,
1975static int smack_socket_connect(struct socket *sock, struct sockaddr *sap, 2155static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
1976 int addrlen) 2156 int addrlen)
1977{ 2157{
1978 if (sock->sk == NULL || sock->sk->sk_family != PF_INET) 2158 int rc = 0;
2159
2160 if (sock->sk == NULL)
1979 return 0; 2161 return 0;
1980 if (addrlen < sizeof(struct sockaddr_in))
1981 return -EINVAL;
1982 2162
1983 return smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap); 2163 switch (sock->sk->sk_family) {
2164 case PF_INET:
2165 if (addrlen < sizeof(struct sockaddr_in))
2166 return -EINVAL;
2167 rc = smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap);
2168 break;
2169 case PF_INET6:
2170 if (addrlen < sizeof(struct sockaddr_in6))
2171 return -EINVAL;
2172 rc = smk_ipv6_port_check(sock->sk, sap, SMK_CONNECTING);
2173 break;
2174 }
2175 return rc;
1984} 2176}
1985 2177
1986/** 2178/**
@@ -2792,22 +2984,32 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other)
2792 * @msg: the message 2984 * @msg: the message
2793 * @size: the size of the message 2985 * @size: the size of the message
2794 * 2986 *
2795 * Return 0 if the current subject can write to the destination 2987 * Return 0 if the current subject can write to the destination host.
2796 * host. This is only a question if the destination is a single 2988 * For IPv4 this is only a question if the destination is a single label host.
2797 * label host. 2989 * For IPv6 this is a check against the label of the port.
2798 */ 2990 */
2799static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, 2991static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
2800 int size) 2992 int size)
2801{ 2993{
2802 struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name; 2994 struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name;
2995 struct sockaddr *sap = (struct sockaddr *) msg->msg_name;
2996 int rc = 0;
2803 2997
2804 /* 2998 /*
2805 * Perfectly reasonable for this to be NULL 2999 * Perfectly reasonable for this to be NULL
2806 */ 3000 */
2807 if (sip == NULL || sip->sin_family != AF_INET) 3001 if (sip == NULL)
2808 return 0; 3002 return 0;
2809 3003
2810 return smack_netlabel_send(sock->sk, sip); 3004 switch (sip->sin_family) {
3005 case AF_INET:
3006 rc = smack_netlabel_send(sock->sk, sip);
3007 break;
3008 case AF_INET6:
3009 rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING);
3010 break;
3011 }
3012 return rc;
2811} 3013}
2812 3014
2813/** 3015/**
@@ -2878,6 +3080,54 @@ static char *smack_from_secattr(struct netlbl_lsm_secattr *sap,
2878 return smack_net_ambient; 3080 return smack_net_ambient;
2879} 3081}
2880 3082
3083static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr *sap)
3084{
3085 struct sockaddr_in6 *sip = (struct sockaddr_in6 *)sap;
3086 u8 nexthdr;
3087 int offset;
3088 int proto = -EINVAL;
3089 struct ipv6hdr _ipv6h;
3090 struct ipv6hdr *ip6;
3091 __be16 frag_off;
3092 struct tcphdr _tcph, *th;
3093 struct udphdr _udph, *uh;
3094 struct dccp_hdr _dccph, *dh;
3095
3096 sip->sin6_port = 0;
3097
3098 offset = skb_network_offset(skb);
3099 ip6 = skb_header_pointer(skb, offset, sizeof(_ipv6h), &_ipv6h);
3100 if (ip6 == NULL)
3101 return -EINVAL;
3102 sip->sin6_addr = ip6->saddr;
3103
3104 nexthdr = ip6->nexthdr;
3105 offset += sizeof(_ipv6h);
3106 offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off);
3107 if (offset < 0)
3108 return -EINVAL;
3109
3110 proto = nexthdr;
3111 switch (proto) {
3112 case IPPROTO_TCP:
3113 th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
3114 if (th != NULL)
3115 sip->sin6_port = th->source;
3116 break;
3117 case IPPROTO_UDP:
3118 uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
3119 if (uh != NULL)
3120 sip->sin6_port = uh->source;
3121 break;
3122 case IPPROTO_DCCP:
3123 dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph);
3124 if (dh != NULL)
3125 sip->sin6_port = dh->dccph_sport;
3126 break;
3127 }
3128 return proto;
3129}
3130
2881/** 3131/**
2882 * smack_socket_sock_rcv_skb - Smack packet delivery access check 3132 * smack_socket_sock_rcv_skb - Smack packet delivery access check
2883 * @sk: socket 3133 * @sk: socket
@@ -2889,43 +3139,52 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
2889{ 3139{
2890 struct netlbl_lsm_secattr secattr; 3140 struct netlbl_lsm_secattr secattr;
2891 struct socket_smack *ssp = sk->sk_security; 3141 struct socket_smack *ssp = sk->sk_security;
3142 struct sockaddr sadd;
2892 char *csp; 3143 char *csp;
2893 int rc; 3144 int rc = 0;
2894 struct smk_audit_info ad; 3145 struct smk_audit_info ad;
2895#ifdef CONFIG_AUDIT 3146#ifdef CONFIG_AUDIT
2896 struct lsm_network_audit net; 3147 struct lsm_network_audit net;
2897#endif 3148#endif
2898 if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) 3149 switch (sk->sk_family) {
2899 return 0; 3150 case PF_INET:
2900 3151 /*
2901 /* 3152 * Translate what netlabel gave us.
2902 * Translate what netlabel gave us. 3153 */
2903 */ 3154 netlbl_secattr_init(&secattr);
2904 netlbl_secattr_init(&secattr);
2905 3155
2906 rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr); 3156 rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr);
2907 if (rc == 0) 3157 if (rc == 0)
2908 csp = smack_from_secattr(&secattr, ssp); 3158 csp = smack_from_secattr(&secattr, ssp);
2909 else 3159 else
2910 csp = smack_net_ambient; 3160 csp = smack_net_ambient;
2911 3161
2912 netlbl_secattr_destroy(&secattr); 3162 netlbl_secattr_destroy(&secattr);
2913 3163
2914#ifdef CONFIG_AUDIT 3164#ifdef CONFIG_AUDIT
2915 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); 3165 smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
2916 ad.a.u.net->family = sk->sk_family; 3166 ad.a.u.net->family = sk->sk_family;
2917 ad.a.u.net->netif = skb->skb_iif; 3167 ad.a.u.net->netif = skb->skb_iif;
2918 ipv4_skb_to_auditdata(skb, &ad.a, NULL); 3168 ipv4_skb_to_auditdata(skb, &ad.a, NULL);
2919#endif 3169#endif
2920 /* 3170 /*
2921 * Receiving a packet requires that the other end 3171 * Receiving a packet requires that the other end
2922 * be able to write here. Read access is not required. 3172 * be able to write here. Read access is not required.
2923 * This is the simplist possible security model 3173 * This is the simplist possible security model
2924 * for networking. 3174 * for networking.
2925 */ 3175 */
2926 rc = smk_access(csp, ssp->smk_in, MAY_WRITE, &ad); 3176 rc = smk_access(csp, ssp->smk_in, MAY_WRITE, &ad);
2927 if (rc != 0) 3177 if (rc != 0)
2928 netlbl_skbuff_err(skb, rc, 0); 3178 netlbl_skbuff_err(skb, rc, 0);
3179 break;
3180 case PF_INET6:
3181 rc = smk_skb_to_addr_ipv6(skb, &sadd);
3182 if (rc == IPPROTO_UDP || rc == IPPROTO_TCP)
3183 rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING);
3184 else
3185 rc = 0;
3186 break;
3187 }
2929 return rc; 3188 return rc;
2930} 3189}
2931 3190
@@ -3063,9 +3322,17 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3063 struct lsm_network_audit net; 3322 struct lsm_network_audit net;
3064#endif 3323#endif
3065 3324
3066 /* handle mapped IPv4 packets arriving via IPv6 sockets */ 3325 if (family == PF_INET6) {
3067 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) 3326 /*
3068 family = PF_INET; 3327 * Handle mapped IPv4 packets arriving
3328 * via IPv6 sockets. Don't set up netlabel
3329 * processing on IPv6.
3330 */
3331 if (skb->protocol == htons(ETH_P_IP))
3332 family = PF_INET;
3333 else
3334 return 0;
3335 }
3069 3336
3070 netlbl_secattr_init(&secattr); 3337 netlbl_secattr_init(&secattr);
3071 rc = netlbl_skbuff_getattr(skb, family, &secattr); 3338 rc = netlbl_skbuff_getattr(skb, family, &secattr);
@@ -3498,6 +3765,7 @@ struct security_operations smack_ops = {
3498 .unix_may_send = smack_unix_may_send, 3765 .unix_may_send = smack_unix_may_send,
3499 3766
3500 .socket_post_create = smack_socket_post_create, 3767 .socket_post_create = smack_socket_post_create,
3768 .socket_bind = smack_socket_bind,
3501 .socket_connect = smack_socket_connect, 3769 .socket_connect = smack_socket_connect,
3502 .socket_sendmsg = smack_socket_sendmsg, 3770 .socket_sendmsg = smack_socket_sendmsg,
3503 .socket_sock_rcv_skb = smack_socket_sock_rcv_skb, 3771 .socket_sock_rcv_skb = smack_socket_sock_rcv_skb,