aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-03-28 20:30:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-03-28 20:30:42 -0400
commit7541bba880fb6989f489f0c68fa246a375b44035 (patch)
tree19ce55af8e8732aa61cb8db529cf2304d9d738b5 /net/ipv4
parent795e2fe0a3b69dbc040d7efcf517e0cbad6901d0 (diff)
parent4303154e86597885bc3cbc178a48ccbc8213875f (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6: smack: Add a new '-CIPSO' option to the network address label configuration netlabel: Cleanup the Smack/NetLabel code to fix incoming TCP connections lsm: Remove the socket_post_accept() hook selinux: Remove the "compat_net" compatibility code netlabel: Label incoming TCP connections correctly in SELinux lsm: Relocate the IPv4 security_inet_conn_request() hooks TOMOYO: Fix a typo. smack: convert smack to standard linux lists
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/cipso_ipv4.c130
-rw-r--r--net/ipv4/syncookies.c9
-rw-r--r--net/ipv4/tcp_ipv4.c7
3 files changed, 127 insertions, 19 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/ipv4/syncookies.c b/net/ipv4/syncookies.c
index d346c22aa6ae..b35a950d2e06 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -288,10 +288,6 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
288 if (!req) 288 if (!req)
289 goto out; 289 goto out;
290 290
291 if (security_inet_conn_request(sk, skb, req)) {
292 reqsk_free(req);
293 goto out;
294 }
295 ireq = inet_rsk(req); 291 ireq = inet_rsk(req);
296 treq = tcp_rsk(req); 292 treq = tcp_rsk(req);
297 treq->rcv_isn = ntohl(th->seq) - 1; 293 treq->rcv_isn = ntohl(th->seq) - 1;
@@ -322,6 +318,11 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
322 } 318 }
323 } 319 }
324 320
321 if (security_inet_conn_request(sk, skb, req)) {
322 reqsk_free(req);
323 goto out;
324 }
325
325 req->expires = 0UL; 326 req->expires = 0UL;
326 req->retrans = 0; 327 req->retrans = 0;
327 328
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index d0a314879d81..5d427f86b414 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1230,14 +1230,15 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
1230 1230
1231 tcp_openreq_init(req, &tmp_opt, skb); 1231 tcp_openreq_init(req, &tmp_opt, skb);
1232 1232
1233 if (security_inet_conn_request(sk, skb, req))
1234 goto drop_and_free;
1235
1236 ireq = inet_rsk(req); 1233 ireq = inet_rsk(req);
1237 ireq->loc_addr = daddr; 1234 ireq->loc_addr = daddr;
1238 ireq->rmt_addr = saddr; 1235 ireq->rmt_addr = saddr;
1239 ireq->no_srccheck = inet_sk(sk)->transparent; 1236 ireq->no_srccheck = inet_sk(sk)->transparent;
1240 ireq->opt = tcp_v4_save_options(sk, skb); 1237 ireq->opt = tcp_v4_save_options(sk, skb);
1238
1239 if (security_inet_conn_request(sk, skb, req))
1240 goto drop_and_free;
1241
1241 if (!want_cookie) 1242 if (!want_cookie)
1242 TCP_ECN_create_request(req, tcp_hdr(skb)); 1243 TCP_ECN_create_request(req, tcp_hdr(skb));
1243 1244