aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/core/flow.c8
-rw-r--r--net/key/af_key.c197
-rw-r--r--net/xfrm/xfrm_policy.c88
-rw-r--r--net/xfrm/xfrm_state.c9
-rw-r--r--net/xfrm/xfrm_user.c148
5 files changed, 396 insertions, 54 deletions
diff --git a/net/core/flow.c b/net/core/flow.c
index 7e95b39de9fd..c4f25385029f 100644
--- a/net/core/flow.c
+++ b/net/core/flow.c
@@ -23,6 +23,7 @@
23#include <net/flow.h> 23#include <net/flow.h>
24#include <asm/atomic.h> 24#include <asm/atomic.h>
25#include <asm/semaphore.h> 25#include <asm/semaphore.h>
26#include <linux/security.h>
26 27
27struct flow_cache_entry { 28struct flow_cache_entry {
28 struct flow_cache_entry *next; 29 struct flow_cache_entry *next;
@@ -30,6 +31,7 @@ struct flow_cache_entry {
30 u8 dir; 31 u8 dir;
31 struct flowi key; 32 struct flowi key;
32 u32 genid; 33 u32 genid;
34 u32 sk_sid;
33 void *object; 35 void *object;
34 atomic_t *object_ref; 36 atomic_t *object_ref;
35}; 37};
@@ -162,7 +164,7 @@ static int flow_key_compare(struct flowi *key1, struct flowi *key2)
162 return 0; 164 return 0;
163} 165}
164 166
165void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir, 167void *flow_cache_lookup(struct flowi *key, u32 sk_sid, u16 family, u8 dir,
166 flow_resolve_t resolver) 168 flow_resolve_t resolver)
167{ 169{
168 struct flow_cache_entry *fle, **head; 170 struct flow_cache_entry *fle, **head;
@@ -186,6 +188,7 @@ void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
186 for (fle = *head; fle; fle = fle->next) { 188 for (fle = *head; fle; fle = fle->next) {
187 if (fle->family == family && 189 if (fle->family == family &&
188 fle->dir == dir && 190 fle->dir == dir &&
191 fle->sk_sid == sk_sid &&
189 flow_key_compare(key, &fle->key) == 0) { 192 flow_key_compare(key, &fle->key) == 0) {
190 if (fle->genid == atomic_read(&flow_cache_genid)) { 193 if (fle->genid == atomic_read(&flow_cache_genid)) {
191 void *ret = fle->object; 194 void *ret = fle->object;
@@ -210,6 +213,7 @@ void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
210 *head = fle; 213 *head = fle;
211 fle->family = family; 214 fle->family = family;
212 fle->dir = dir; 215 fle->dir = dir;
216 fle->sk_sid = sk_sid;
213 memcpy(&fle->key, key, sizeof(*key)); 217 memcpy(&fle->key, key, sizeof(*key));
214 fle->object = NULL; 218 fle->object = NULL;
215 flow_count(cpu)++; 219 flow_count(cpu)++;
@@ -221,7 +225,7 @@ nocache:
221 void *obj; 225 void *obj;
222 atomic_t *obj_ref; 226 atomic_t *obj_ref;
223 227
224 resolver(key, family, dir, &obj, &obj_ref); 228 resolver(key, sk_sid, family, dir, &obj, &obj_ref);
225 229
226 if (fle) { 230 if (fle) {
227 fle->genid = atomic_read(&flow_cache_genid); 231 fle->genid = atomic_read(&flow_cache_genid);
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 39031684b65c..d32f7791f1e4 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -336,6 +336,7 @@ static u8 sadb_ext_min_len[] = {
336 [SADB_X_EXT_NAT_T_SPORT] = (u8) sizeof(struct sadb_x_nat_t_port), 336 [SADB_X_EXT_NAT_T_SPORT] = (u8) sizeof(struct sadb_x_nat_t_port),
337 [SADB_X_EXT_NAT_T_DPORT] = (u8) sizeof(struct sadb_x_nat_t_port), 337 [SADB_X_EXT_NAT_T_DPORT] = (u8) sizeof(struct sadb_x_nat_t_port),
338 [SADB_X_EXT_NAT_T_OA] = (u8) sizeof(struct sadb_address), 338 [SADB_X_EXT_NAT_T_OA] = (u8) sizeof(struct sadb_address),
339 [SADB_X_EXT_SEC_CTX] = (u8) sizeof(struct sadb_x_sec_ctx),
339}; 340};
340 341
341/* Verify sadb_address_{len,prefixlen} against sa_family. */ 342/* Verify sadb_address_{len,prefixlen} against sa_family. */
@@ -383,6 +384,55 @@ static int verify_address_len(void *p)
383 return 0; 384 return 0;
384} 385}
385 386
387static inline int pfkey_sec_ctx_len(struct sadb_x_sec_ctx *sec_ctx)
388{
389 int len = 0;
390
391 len += sizeof(struct sadb_x_sec_ctx);
392 len += sec_ctx->sadb_x_ctx_len;
393 len += sizeof(uint64_t) - 1;
394 len /= sizeof(uint64_t);
395
396 return len;
397}
398
399static inline int verify_sec_ctx_len(void *p)
400{
401 struct sadb_x_sec_ctx *sec_ctx = (struct sadb_x_sec_ctx *)p;
402 int len;
403
404 if (sec_ctx->sadb_x_ctx_len > PAGE_SIZE)
405 return -EINVAL;
406
407 len = pfkey_sec_ctx_len(sec_ctx);
408
409 if (sec_ctx->sadb_x_sec_len != len)
410 return -EINVAL;
411
412 return 0;
413}
414
415static inline struct xfrm_user_sec_ctx *pfkey_sadb2xfrm_user_sec_ctx(struct sadb_x_sec_ctx *sec_ctx)
416{
417 struct xfrm_user_sec_ctx *uctx = NULL;
418 int ctx_size = sec_ctx->sadb_x_ctx_len;
419
420 uctx = kmalloc((sizeof(*uctx)+ctx_size), GFP_KERNEL);
421
422 if (!uctx)
423 return NULL;
424
425 uctx->len = pfkey_sec_ctx_len(sec_ctx);
426 uctx->exttype = sec_ctx->sadb_x_sec_exttype;
427 uctx->ctx_doi = sec_ctx->sadb_x_ctx_doi;
428 uctx->ctx_alg = sec_ctx->sadb_x_ctx_alg;
429 uctx->ctx_len = sec_ctx->sadb_x_ctx_len;
430 memcpy(uctx + 1, sec_ctx + 1,
431 uctx->ctx_len);
432
433 return uctx;
434}
435
386static int present_and_same_family(struct sadb_address *src, 436static int present_and_same_family(struct sadb_address *src,
387 struct sadb_address *dst) 437 struct sadb_address *dst)
388{ 438{
@@ -438,6 +488,10 @@ static int parse_exthdrs(struct sk_buff *skb, struct sadb_msg *hdr, void **ext_h
438 if (verify_address_len(p)) 488 if (verify_address_len(p))
439 return -EINVAL; 489 return -EINVAL;
440 } 490 }
491 if (ext_type == SADB_X_EXT_SEC_CTX) {
492 if (verify_sec_ctx_len(p))
493 return -EINVAL;
494 }
441 ext_hdrs[ext_type-1] = p; 495 ext_hdrs[ext_type-1] = p;
442 } 496 }
443 p += ext_len; 497 p += ext_len;
@@ -586,6 +640,9 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
586 struct sadb_key *key; 640 struct sadb_key *key;
587 struct sadb_x_sa2 *sa2; 641 struct sadb_x_sa2 *sa2;
588 struct sockaddr_in *sin; 642 struct sockaddr_in *sin;
643 struct sadb_x_sec_ctx *sec_ctx;
644 struct xfrm_sec_ctx *xfrm_ctx;
645 int ctx_size = 0;
589#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 646#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
590 struct sockaddr_in6 *sin6; 647 struct sockaddr_in6 *sin6;
591#endif 648#endif
@@ -609,6 +666,12 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
609 sizeof(struct sadb_address)*2 + 666 sizeof(struct sadb_address)*2 +
610 sockaddr_size*2 + 667 sockaddr_size*2 +
611 sizeof(struct sadb_x_sa2); 668 sizeof(struct sadb_x_sa2);
669
670 if ((xfrm_ctx = x->security)) {
671 ctx_size = PFKEY_ALIGN8(xfrm_ctx->ctx_len);
672 size += sizeof(struct sadb_x_sec_ctx) + ctx_size;
673 }
674
612 /* identity & sensitivity */ 675 /* identity & sensitivity */
613 676
614 if ((x->props.family == AF_INET && 677 if ((x->props.family == AF_INET &&
@@ -899,6 +962,20 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
899 n_port->sadb_x_nat_t_port_reserved = 0; 962 n_port->sadb_x_nat_t_port_reserved = 0;
900 } 963 }
901 964
965 /* security context */
966 if (xfrm_ctx) {
967 sec_ctx = (struct sadb_x_sec_ctx *) skb_put(skb,
968 sizeof(struct sadb_x_sec_ctx) + ctx_size);
969 sec_ctx->sadb_x_sec_len =
970 (sizeof(struct sadb_x_sec_ctx) + ctx_size) / sizeof(uint64_t);
971 sec_ctx->sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX;
972 sec_ctx->sadb_x_ctx_doi = xfrm_ctx->ctx_doi;
973 sec_ctx->sadb_x_ctx_alg = xfrm_ctx->ctx_alg;
974 sec_ctx->sadb_x_ctx_len = xfrm_ctx->ctx_len;
975 memcpy(sec_ctx + 1, xfrm_ctx->ctx_str,
976 xfrm_ctx->ctx_len);
977 }
978
902 return skb; 979 return skb;
903} 980}
904 981
@@ -909,6 +986,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
909 struct sadb_lifetime *lifetime; 986 struct sadb_lifetime *lifetime;
910 struct sadb_sa *sa; 987 struct sadb_sa *sa;
911 struct sadb_key *key; 988 struct sadb_key *key;
989 struct sadb_x_sec_ctx *sec_ctx;
912 uint16_t proto; 990 uint16_t proto;
913 int err; 991 int err;
914 992
@@ -993,6 +1071,21 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
993 x->lft.soft_add_expires_seconds = lifetime->sadb_lifetime_addtime; 1071 x->lft.soft_add_expires_seconds = lifetime->sadb_lifetime_addtime;
994 x->lft.soft_use_expires_seconds = lifetime->sadb_lifetime_usetime; 1072 x->lft.soft_use_expires_seconds = lifetime->sadb_lifetime_usetime;
995 } 1073 }
1074
1075 sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1];
1076 if (sec_ctx != NULL) {
1077 struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
1078
1079 if (!uctx)
1080 goto out;
1081
1082 err = security_xfrm_state_alloc(x, uctx);
1083 kfree(uctx);
1084
1085 if (err)
1086 goto out;
1087 }
1088
996 key = (struct sadb_key*) ext_hdrs[SADB_EXT_KEY_AUTH-1]; 1089 key = (struct sadb_key*) ext_hdrs[SADB_EXT_KEY_AUTH-1];
997 if (sa->sadb_sa_auth) { 1090 if (sa->sadb_sa_auth) {
998 int keysize = 0; 1091 int keysize = 0;
@@ -1720,6 +1813,18 @@ parse_ipsecrequests(struct xfrm_policy *xp, struct sadb_x_policy *pol)
1720 return 0; 1813 return 0;
1721} 1814}
1722 1815
1816static inline int pfkey_xfrm_policy2sec_ctx_size(struct xfrm_policy *xp)
1817{
1818 struct xfrm_sec_ctx *xfrm_ctx = xp->security;
1819
1820 if (xfrm_ctx) {
1821 int len = sizeof(struct sadb_x_sec_ctx);
1822 len += xfrm_ctx->ctx_len;
1823 return PFKEY_ALIGN8(len);
1824 }
1825 return 0;
1826}
1827
1723static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp) 1828static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp)
1724{ 1829{
1725 int sockaddr_size = pfkey_sockaddr_size(xp->family); 1830 int sockaddr_size = pfkey_sockaddr_size(xp->family);
@@ -1733,7 +1838,8 @@ static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp)
1733 (sockaddr_size * 2) + 1838 (sockaddr_size * 2) +
1734 sizeof(struct sadb_x_policy) + 1839 sizeof(struct sadb_x_policy) +
1735 (xp->xfrm_nr * (sizeof(struct sadb_x_ipsecrequest) + 1840 (xp->xfrm_nr * (sizeof(struct sadb_x_ipsecrequest) +
1736 (socklen * 2))); 1841 (socklen * 2))) +
1842 pfkey_xfrm_policy2sec_ctx_size(xp);
1737} 1843}
1738 1844
1739static struct sk_buff * pfkey_xfrm_policy2msg_prep(struct xfrm_policy *xp) 1845static struct sk_buff * pfkey_xfrm_policy2msg_prep(struct xfrm_policy *xp)
@@ -1757,6 +1863,8 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i
1757 struct sadb_lifetime *lifetime; 1863 struct sadb_lifetime *lifetime;
1758 struct sadb_x_policy *pol; 1864 struct sadb_x_policy *pol;
1759 struct sockaddr_in *sin; 1865 struct sockaddr_in *sin;
1866 struct sadb_x_sec_ctx *sec_ctx;
1867 struct xfrm_sec_ctx *xfrm_ctx;
1760#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1868#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1761 struct sockaddr_in6 *sin6; 1869 struct sockaddr_in6 *sin6;
1762#endif 1870#endif
@@ -1941,6 +2049,21 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i
1941 } 2049 }
1942 } 2050 }
1943 } 2051 }
2052
2053 /* security context */
2054 if ((xfrm_ctx = xp->security)) {
2055 int ctx_size = pfkey_xfrm_policy2sec_ctx_size(xp);
2056
2057 sec_ctx = (struct sadb_x_sec_ctx *) skb_put(skb, ctx_size);
2058 sec_ctx->sadb_x_sec_len = ctx_size / sizeof(uint64_t);
2059 sec_ctx->sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX;
2060 sec_ctx->sadb_x_ctx_doi = xfrm_ctx->ctx_doi;
2061 sec_ctx->sadb_x_ctx_alg = xfrm_ctx->ctx_alg;
2062 sec_ctx->sadb_x_ctx_len = xfrm_ctx->ctx_len;
2063 memcpy(sec_ctx + 1, xfrm_ctx->ctx_str,
2064 xfrm_ctx->ctx_len);
2065 }
2066
1944 hdr->sadb_msg_len = size / sizeof(uint64_t); 2067 hdr->sadb_msg_len = size / sizeof(uint64_t);
1945 hdr->sadb_msg_reserved = atomic_read(&xp->refcnt); 2068 hdr->sadb_msg_reserved = atomic_read(&xp->refcnt);
1946} 2069}
@@ -1976,12 +2099,13 @@ out:
1976 2099
1977static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) 2100static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
1978{ 2101{
1979 int err; 2102 int err = 0;
1980 struct sadb_lifetime *lifetime; 2103 struct sadb_lifetime *lifetime;
1981 struct sadb_address *sa; 2104 struct sadb_address *sa;
1982 struct sadb_x_policy *pol; 2105 struct sadb_x_policy *pol;
1983 struct xfrm_policy *xp; 2106 struct xfrm_policy *xp;
1984 struct km_event c; 2107 struct km_event c;
2108 struct sadb_x_sec_ctx *sec_ctx;
1985 2109
1986 if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1], 2110 if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
1987 ext_hdrs[SADB_EXT_ADDRESS_DST-1]) || 2111 ext_hdrs[SADB_EXT_ADDRESS_DST-1]) ||
@@ -2028,6 +2152,22 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
2028 if (xp->selector.dport) 2152 if (xp->selector.dport)
2029 xp->selector.dport_mask = ~0; 2153 xp->selector.dport_mask = ~0;
2030 2154
2155 sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1];
2156 if (sec_ctx != NULL) {
2157 struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
2158
2159 if (!uctx) {
2160 err = -ENOBUFS;
2161 goto out;
2162 }
2163
2164 err = security_xfrm_policy_alloc(xp, uctx);
2165 kfree(uctx);
2166
2167 if (err)
2168 goto out;
2169 }
2170
2031 xp->lft.soft_byte_limit = XFRM_INF; 2171 xp->lft.soft_byte_limit = XFRM_INF;
2032 xp->lft.hard_byte_limit = XFRM_INF; 2172 xp->lft.hard_byte_limit = XFRM_INF;
2033 xp->lft.soft_packet_limit = XFRM_INF; 2173 xp->lft.soft_packet_limit = XFRM_INF;
@@ -2051,10 +2191,9 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
2051 2191
2052 err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp, 2192 err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp,
2053 hdr->sadb_msg_type != SADB_X_SPDUPDATE); 2193 hdr->sadb_msg_type != SADB_X_SPDUPDATE);
2054 if (err) { 2194
2055 kfree(xp); 2195 if (err)
2056 return err; 2196 goto out;
2057 }
2058 2197
2059 if (hdr->sadb_msg_type == SADB_X_SPDUPDATE) 2198 if (hdr->sadb_msg_type == SADB_X_SPDUPDATE)
2060 c.event = XFRM_MSG_UPDPOLICY; 2199 c.event = XFRM_MSG_UPDPOLICY;
@@ -2069,6 +2208,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
2069 return 0; 2208 return 0;
2070 2209
2071out: 2210out:
2211 security_xfrm_policy_free(xp);
2072 kfree(xp); 2212 kfree(xp);
2073 return err; 2213 return err;
2074} 2214}
@@ -2078,9 +2218,10 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
2078 int err; 2218 int err;
2079 struct sadb_address *sa; 2219 struct sadb_address *sa;
2080 struct sadb_x_policy *pol; 2220 struct sadb_x_policy *pol;
2081 struct xfrm_policy *xp; 2221 struct xfrm_policy *xp, tmp;
2082 struct xfrm_selector sel; 2222 struct xfrm_selector sel;
2083 struct km_event c; 2223 struct km_event c;
2224 struct sadb_x_sec_ctx *sec_ctx;
2084 2225
2085 if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1], 2226 if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
2086 ext_hdrs[SADB_EXT_ADDRESS_DST-1]) || 2227 ext_hdrs[SADB_EXT_ADDRESS_DST-1]) ||
@@ -2109,7 +2250,24 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
2109 if (sel.dport) 2250 if (sel.dport)
2110 sel.dport_mask = ~0; 2251 sel.dport_mask = ~0;
2111 2252
2112 xp = xfrm_policy_bysel(pol->sadb_x_policy_dir-1, &sel, 1); 2253 sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1];
2254 memset(&tmp, 0, sizeof(struct xfrm_policy));
2255
2256 if (sec_ctx != NULL) {
2257 struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
2258
2259 if (!uctx)
2260 return -ENOMEM;
2261
2262 err = security_xfrm_policy_alloc(&tmp, uctx);
2263 kfree(uctx);
2264
2265 if (err)
2266 return err;
2267 }
2268
2269 xp = xfrm_policy_bysel_ctx(pol->sadb_x_policy_dir-1, &sel, tmp.security, 1);
2270 security_xfrm_policy_free(&tmp);
2113 if (xp == NULL) 2271 if (xp == NULL)
2114 return -ENOENT; 2272 return -ENOENT;
2115 2273
@@ -2660,6 +2818,7 @@ static struct xfrm_policy *pfkey_compile_policy(u16 family, int opt,
2660{ 2818{
2661 struct xfrm_policy *xp; 2819 struct xfrm_policy *xp;
2662 struct sadb_x_policy *pol = (struct sadb_x_policy*)data; 2820 struct sadb_x_policy *pol = (struct sadb_x_policy*)data;
2821 struct sadb_x_sec_ctx *sec_ctx;
2663 2822
2664 switch (family) { 2823 switch (family) {
2665 case AF_INET: 2824 case AF_INET:
@@ -2709,10 +2868,32 @@ static struct xfrm_policy *pfkey_compile_policy(u16 family, int opt,
2709 (*dir = parse_ipsecrequests(xp, pol)) < 0) 2868 (*dir = parse_ipsecrequests(xp, pol)) < 0)
2710 goto out; 2869 goto out;
2711 2870
2871 /* security context too */
2872 if (len >= (pol->sadb_x_policy_len*8 +
2873 sizeof(struct sadb_x_sec_ctx))) {
2874 char *p = (char *)pol;
2875 struct xfrm_user_sec_ctx *uctx;
2876
2877 p += pol->sadb_x_policy_len*8;
2878 sec_ctx = (struct sadb_x_sec_ctx *)p;
2879 if (len < pol->sadb_x_policy_len*8 +
2880 sec_ctx->sadb_x_sec_len)
2881 goto out;
2882 if ((*dir = verify_sec_ctx_len(p)))
2883 goto out;
2884 uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
2885 *dir = security_xfrm_policy_alloc(xp, uctx);
2886 kfree(uctx);
2887
2888 if (*dir)
2889 goto out;
2890 }
2891
2712 *dir = pol->sadb_x_policy_dir-1; 2892 *dir = pol->sadb_x_policy_dir-1;
2713 return xp; 2893 return xp;
2714 2894
2715out: 2895out:
2896 security_xfrm_policy_free(xp);
2716 kfree(xp); 2897 kfree(xp);
2717 return NULL; 2898 return NULL;
2718} 2899}
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index d19e274b9c4a..64a447375fdb 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -10,7 +10,7 @@
10 * YOSHIFUJI Hideaki 10 * YOSHIFUJI Hideaki
11 * Split up af-specific portion 11 * Split up af-specific portion
12 * Derek Atkins <derek@ihtfp.com> Add the post_input processor 12 * Derek Atkins <derek@ihtfp.com> Add the post_input processor
13 * 13 *
14 */ 14 */
15 15
16#include <asm/bug.h> 16#include <asm/bug.h>
@@ -256,6 +256,7 @@ void __xfrm_policy_destroy(struct xfrm_policy *policy)
256 if (del_timer(&policy->timer)) 256 if (del_timer(&policy->timer))
257 BUG(); 257 BUG();
258 258
259 security_xfrm_policy_free(policy);
259 kfree(policy); 260 kfree(policy);
260} 261}
261EXPORT_SYMBOL(__xfrm_policy_destroy); 262EXPORT_SYMBOL(__xfrm_policy_destroy);
@@ -350,7 +351,8 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
350 351
351 write_lock_bh(&xfrm_policy_lock); 352 write_lock_bh(&xfrm_policy_lock);
352 for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL;) { 353 for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL;) {
353 if (!delpol && memcmp(&policy->selector, &pol->selector, sizeof(pol->selector)) == 0) { 354 if (!delpol && memcmp(&policy->selector, &pol->selector, sizeof(pol->selector)) == 0 &&
355 xfrm_sec_ctx_match(pol->security, policy->security)) {
354 if (excl) { 356 if (excl) {
355 write_unlock_bh(&xfrm_policy_lock); 357 write_unlock_bh(&xfrm_policy_lock);
356 return -EEXIST; 358 return -EEXIST;
@@ -416,14 +418,15 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
416} 418}
417EXPORT_SYMBOL(xfrm_policy_insert); 419EXPORT_SYMBOL(xfrm_policy_insert);
418 420
419struct xfrm_policy *xfrm_policy_bysel(int dir, struct xfrm_selector *sel, 421struct xfrm_policy *xfrm_policy_bysel_ctx(int dir, struct xfrm_selector *sel,
420 int delete) 422 struct xfrm_sec_ctx *ctx, int delete)
421{ 423{
422 struct xfrm_policy *pol, **p; 424 struct xfrm_policy *pol, **p;
423 425
424 write_lock_bh(&xfrm_policy_lock); 426 write_lock_bh(&xfrm_policy_lock);
425 for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL; p = &pol->next) { 427 for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL; p = &pol->next) {
426 if (memcmp(sel, &pol->selector, sizeof(*sel)) == 0) { 428 if ((memcmp(sel, &pol->selector, sizeof(*sel)) == 0) &&
429 (xfrm_sec_ctx_match(ctx, pol->security))) {
427 xfrm_pol_hold(pol); 430 xfrm_pol_hold(pol);
428 if (delete) 431 if (delete)
429 *p = pol->next; 432 *p = pol->next;
@@ -438,7 +441,7 @@ struct xfrm_policy *xfrm_policy_bysel(int dir, struct xfrm_selector *sel,
438 } 441 }
439 return pol; 442 return pol;
440} 443}
441EXPORT_SYMBOL(xfrm_policy_bysel); 444EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
442 445
443struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete) 446struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete)
444{ 447{
@@ -519,7 +522,7 @@ EXPORT_SYMBOL(xfrm_policy_walk);
519 522
520/* Find policy to apply to this flow. */ 523/* Find policy to apply to this flow. */
521 524
522static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir, 525static void xfrm_policy_lookup(struct flowi *fl, u32 sk_sid, u16 family, u8 dir,
523 void **objp, atomic_t **obj_refp) 526 void **objp, atomic_t **obj_refp)
524{ 527{
525 struct xfrm_policy *pol; 528 struct xfrm_policy *pol;
@@ -533,9 +536,12 @@ static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir,
533 continue; 536 continue;
534 537
535 match = xfrm_selector_match(sel, fl, family); 538 match = xfrm_selector_match(sel, fl, family);
539
536 if (match) { 540 if (match) {
537 xfrm_pol_hold(pol); 541 if (!security_xfrm_policy_lookup(pol, sk_sid, dir)) {
538 break; 542 xfrm_pol_hold(pol);
543 break;
544 }
539 } 545 }
540 } 546 }
541 read_unlock_bh(&xfrm_policy_lock); 547 read_unlock_bh(&xfrm_policy_lock);
@@ -543,15 +549,37 @@ static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir,
543 *obj_refp = &pol->refcnt; 549 *obj_refp = &pol->refcnt;
544} 550}
545 551
546static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struct flowi *fl) 552static inline int policy_to_flow_dir(int dir)
553{
554 if (XFRM_POLICY_IN == FLOW_DIR_IN &&
555 XFRM_POLICY_OUT == FLOW_DIR_OUT &&
556 XFRM_POLICY_FWD == FLOW_DIR_FWD)
557 return dir;
558 switch (dir) {
559 default:
560 case XFRM_POLICY_IN:
561 return FLOW_DIR_IN;
562 case XFRM_POLICY_OUT:
563 return FLOW_DIR_OUT;
564 case XFRM_POLICY_FWD:
565 return FLOW_DIR_FWD;
566 };
567}
568
569static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struct flowi *fl, u32 sk_sid)
547{ 570{
548 struct xfrm_policy *pol; 571 struct xfrm_policy *pol;
549 572
550 read_lock_bh(&xfrm_policy_lock); 573 read_lock_bh(&xfrm_policy_lock);
551 if ((pol = sk->sk_policy[dir]) != NULL) { 574 if ((pol = sk->sk_policy[dir]) != NULL) {
552 int match = xfrm_selector_match(&pol->selector, fl, 575 int match = xfrm_selector_match(&pol->selector, fl,
553 sk->sk_family); 576 sk->sk_family);
577 int err = 0;
578
554 if (match) 579 if (match)
580 err = security_xfrm_policy_lookup(pol, sk_sid, policy_to_flow_dir(dir));
581
582 if (match && !err)
555 xfrm_pol_hold(pol); 583 xfrm_pol_hold(pol);
556 else 584 else
557 pol = NULL; 585 pol = NULL;
@@ -624,6 +652,10 @@ static struct xfrm_policy *clone_policy(struct xfrm_policy *old, int dir)
624 652
625 if (newp) { 653 if (newp) {
626 newp->selector = old->selector; 654 newp->selector = old->selector;
655 if (security_xfrm_policy_clone(old, newp)) {
656 kfree(newp);
657 return NULL; /* ENOMEM */
658 }
627 newp->lft = old->lft; 659 newp->lft = old->lft;
628 newp->curlft = old->curlft; 660 newp->curlft = old->curlft;
629 newp->action = old->action; 661 newp->action = old->action;
@@ -735,22 +767,6 @@ xfrm_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int nx,
735 return err; 767 return err;
736} 768}
737 769
738static inline int policy_to_flow_dir(int dir)
739{
740 if (XFRM_POLICY_IN == FLOW_DIR_IN &&
741 XFRM_POLICY_OUT == FLOW_DIR_OUT &&
742 XFRM_POLICY_FWD == FLOW_DIR_FWD)
743 return dir;
744 switch (dir) {
745 default:
746 case XFRM_POLICY_IN:
747 return FLOW_DIR_IN;
748 case XFRM_POLICY_OUT:
749 return FLOW_DIR_OUT;
750 case XFRM_POLICY_FWD:
751 return FLOW_DIR_FWD;
752 };
753}
754 770
755static int stale_bundle(struct dst_entry *dst); 771static int stale_bundle(struct dst_entry *dst);
756 772
@@ -769,19 +785,20 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
769 int err; 785 int err;
770 u32 genid; 786 u32 genid;
771 u16 family = dst_orig->ops->family; 787 u16 family = dst_orig->ops->family;
788 u8 dir = policy_to_flow_dir(XFRM_POLICY_OUT);
789 u32 sk_sid = security_sk_sid(sk, fl, dir);
772restart: 790restart:
773 genid = atomic_read(&flow_cache_genid); 791 genid = atomic_read(&flow_cache_genid);
774 policy = NULL; 792 policy = NULL;
775 if (sk && sk->sk_policy[1]) 793 if (sk && sk->sk_policy[1])
776 policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl); 794 policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl, sk_sid);
777 795
778 if (!policy) { 796 if (!policy) {
779 /* To accelerate a bit... */ 797 /* To accelerate a bit... */
780 if ((dst_orig->flags & DST_NOXFRM) || !xfrm_policy_list[XFRM_POLICY_OUT]) 798 if ((dst_orig->flags & DST_NOXFRM) || !xfrm_policy_list[XFRM_POLICY_OUT])
781 return 0; 799 return 0;
782 800
783 policy = flow_cache_lookup(fl, family, 801 policy = flow_cache_lookup(fl, sk_sid, family, dir,
784 policy_to_flow_dir(XFRM_POLICY_OUT),
785 xfrm_policy_lookup); 802 xfrm_policy_lookup);
786 } 803 }
787 804
@@ -962,16 +979,20 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
962{ 979{
963 struct xfrm_policy *pol; 980 struct xfrm_policy *pol;
964 struct flowi fl; 981 struct flowi fl;
982 u8 fl_dir = policy_to_flow_dir(dir);
983 u32 sk_sid;
965 984
966 if (_decode_session(skb, &fl, family) < 0) 985 if (_decode_session(skb, &fl, family) < 0)
967 return 0; 986 return 0;
968 987
988 sk_sid = security_sk_sid(sk, &fl, fl_dir);
989
969 /* First, check used SA against their selectors. */ 990 /* First, check used SA against their selectors. */
970 if (skb->sp) { 991 if (skb->sp) {
971 int i; 992 int i;
972 993
973 for (i=skb->sp->len-1; i>=0; i--) { 994 for (i=skb->sp->len-1; i>=0; i--) {
974 struct sec_decap_state *xvec = &(skb->sp->x[i]); 995 struct sec_decap_state *xvec = &(skb->sp->x[i]);
975 if (!xfrm_selector_match(&xvec->xvec->sel, &fl, family)) 996 if (!xfrm_selector_match(&xvec->xvec->sel, &fl, family))
976 return 0; 997 return 0;
977 998
@@ -986,11 +1007,10 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
986 1007
987 pol = NULL; 1008 pol = NULL;
988 if (sk && sk->sk_policy[dir]) 1009 if (sk && sk->sk_policy[dir])
989 pol = xfrm_sk_policy_lookup(sk, dir, &fl); 1010 pol = xfrm_sk_policy_lookup(sk, dir, &fl, sk_sid);
990 1011
991 if (!pol) 1012 if (!pol)
992 pol = flow_cache_lookup(&fl, family, 1013 pol = flow_cache_lookup(&fl, sk_sid, family, fl_dir,
993 policy_to_flow_dir(dir),
994 xfrm_policy_lookup); 1014 xfrm_policy_lookup);
995 1015
996 if (!pol) 1016 if (!pol)
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 479effc97666..e12d0be5f976 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -10,7 +10,7 @@
10 * Split up af-specific functions 10 * Split up af-specific functions
11 * Derek Atkins <derek@ihtfp.com> 11 * Derek Atkins <derek@ihtfp.com>
12 * Add UDP Encapsulation 12 * Add UDP Encapsulation
13 * 13 *
14 */ 14 */
15 15
16#include <linux/workqueue.h> 16#include <linux/workqueue.h>
@@ -70,6 +70,7 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x)
70 x->type->destructor(x); 70 x->type->destructor(x);
71 xfrm_put_type(x->type); 71 xfrm_put_type(x->type);
72 } 72 }
73 security_xfrm_state_free(x);
73 kfree(x); 74 kfree(x);
74} 75}
75 76
@@ -343,7 +344,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
343 selector. 344 selector.
344 */ 345 */
345 if (x->km.state == XFRM_STATE_VALID) { 346 if (x->km.state == XFRM_STATE_VALID) {
346 if (!xfrm_selector_match(&x->sel, fl, family)) 347 if (!xfrm_selector_match(&x->sel, fl, family) ||
348 !xfrm_sec_ctx_match(pol->security, x->security))
347 continue; 349 continue;
348 if (!best || 350 if (!best ||
349 best->km.dying > x->km.dying || 351 best->km.dying > x->km.dying ||
@@ -354,7 +356,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
354 acquire_in_progress = 1; 356 acquire_in_progress = 1;
355 } else if (x->km.state == XFRM_STATE_ERROR || 357 } else if (x->km.state == XFRM_STATE_ERROR ||
356 x->km.state == XFRM_STATE_EXPIRED) { 358 x->km.state == XFRM_STATE_EXPIRED) {
357 if (xfrm_selector_match(&x->sel, fl, family)) 359 if (xfrm_selector_match(&x->sel, fl, family) &&
360 xfrm_sec_ctx_match(pol->security, x->security))
358 error = -ESRCH; 361 error = -ESRCH;
359 } 362 }
360 } 363 }
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 0cdd9a07e043..92e2b804c606 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -7,7 +7,7 @@
7 * Kazunori MIYAZAWA @USAGI 7 * Kazunori MIYAZAWA @USAGI
8 * Kunihiro Ishiguro <kunihiro@ipinfusion.com> 8 * Kunihiro Ishiguro <kunihiro@ipinfusion.com>
9 * IPv6 support 9 * IPv6 support
10 * 10 *
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
@@ -88,6 +88,34 @@ static int verify_encap_tmpl(struct rtattr **xfrma)
88 return 0; 88 return 0;
89} 89}
90 90
91
92static inline int verify_sec_ctx_len(struct rtattr **xfrma)
93{
94 struct rtattr *rt = xfrma[XFRMA_SEC_CTX - 1];
95 struct xfrm_user_sec_ctx *uctx;
96 int len = 0;
97
98 if (!rt)
99 return 0;
100
101 if (rt->rta_len < sizeof(*uctx))
102 return -EINVAL;
103
104 uctx = RTA_DATA(rt);
105
106 if (uctx->ctx_len > PAGE_SIZE)
107 return -EINVAL;
108
109 len += sizeof(struct xfrm_user_sec_ctx);
110 len += uctx->ctx_len;
111
112 if (uctx->len != len)
113 return -EINVAL;
114
115 return 0;
116}
117
118
91static int verify_newsa_info(struct xfrm_usersa_info *p, 119static int verify_newsa_info(struct xfrm_usersa_info *p,
92 struct rtattr **xfrma) 120 struct rtattr **xfrma)
93{ 121{
@@ -145,6 +173,8 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
145 goto out; 173 goto out;
146 if ((err = verify_encap_tmpl(xfrma))) 174 if ((err = verify_encap_tmpl(xfrma)))
147 goto out; 175 goto out;
176 if ((err = verify_sec_ctx_len(xfrma)))
177 goto out;
148 178
149 err = -EINVAL; 179 err = -EINVAL;
150 switch (p->mode) { 180 switch (p->mode) {
@@ -209,6 +239,30 @@ static int attach_encap_tmpl(struct xfrm_encap_tmpl **encapp, struct rtattr *u_a
209 return 0; 239 return 0;
210} 240}
211 241
242
243static inline int xfrm_user_sec_ctx_size(struct xfrm_policy *xp)
244{
245 struct xfrm_sec_ctx *xfrm_ctx = xp->security;
246 int len = 0;
247
248 if (xfrm_ctx) {
249 len += sizeof(struct xfrm_user_sec_ctx);
250 len += xfrm_ctx->ctx_len;
251 }
252 return len;
253}
254
255static int attach_sec_ctx(struct xfrm_state *x, struct rtattr *u_arg)
256{
257 struct xfrm_user_sec_ctx *uctx;
258
259 if (!u_arg)
260 return 0;
261
262 uctx = RTA_DATA(u_arg);
263 return security_xfrm_state_alloc(x, uctx);
264}
265
212static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p) 266static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p)
213{ 267{
214 memcpy(&x->id, &p->id, sizeof(x->id)); 268 memcpy(&x->id, &p->id, sizeof(x->id));
@@ -253,6 +307,9 @@ static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p,
253 if (err) 307 if (err)
254 goto error; 308 goto error;
255 309
310 if ((err = attach_sec_ctx(x, xfrma[XFRMA_SEC_CTX-1])))
311 goto error;
312
256 x->km.seq = p->seq; 313 x->km.seq = p->seq;
257 314
258 return x; 315 return x;
@@ -272,11 +329,11 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
272 int err; 329 int err;
273 struct km_event c; 330 struct km_event c;
274 331
275 err = verify_newsa_info(p, (struct rtattr **) xfrma); 332 err = verify_newsa_info(p, (struct rtattr **)xfrma);
276 if (err) 333 if (err)
277 return err; 334 return err;
278 335
279 x = xfrm_state_construct(p, (struct rtattr **) xfrma, &err); 336 x = xfrm_state_construct(p, (struct rtattr **)xfrma, &err);
280 if (!x) 337 if (!x)
281 return err; 338 return err;
282 339
@@ -390,6 +447,19 @@ static int dump_one_state(struct xfrm_state *x, int count, void *ptr)
390 if (x->encap) 447 if (x->encap)
391 RTA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap); 448 RTA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);
392 449
450 if (x->security) {
451 int ctx_size = sizeof(struct xfrm_sec_ctx) +
452 x->security->ctx_len;
453 struct rtattr *rt = __RTA_PUT(skb, XFRMA_SEC_CTX, ctx_size);
454 struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);
455
456 uctx->exttype = XFRMA_SEC_CTX;
457 uctx->len = ctx_size;
458 uctx->ctx_doi = x->security->ctx_doi;
459 uctx->ctx_alg = x->security->ctx_alg;
460 uctx->ctx_len = x->security->ctx_len;
461 memcpy(uctx + 1, x->security->ctx_str, x->security->ctx_len);
462 }
393 nlh->nlmsg_len = skb->tail - b; 463 nlh->nlmsg_len = skb->tail - b;
394out: 464out:
395 sp->this_idx++; 465 sp->this_idx++;
@@ -603,6 +673,18 @@ static int verify_newpolicy_info(struct xfrm_userpolicy_info *p)
603 return verify_policy_dir(p->dir); 673 return verify_policy_dir(p->dir);
604} 674}
605 675
676static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct rtattr **xfrma)
677{
678 struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1];
679 struct xfrm_user_sec_ctx *uctx;
680
681 if (!rt)
682 return 0;
683
684 uctx = RTA_DATA(rt);
685 return security_xfrm_policy_alloc(pol, uctx);
686}
687
606static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut, 688static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut,
607 int nr) 689 int nr)
608{ 690{
@@ -681,7 +763,10 @@ static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p,
681 } 763 }
682 764
683 copy_from_user_policy(xp, p); 765 copy_from_user_policy(xp, p);
684 err = copy_from_user_tmpl(xp, xfrma); 766
767 if (!(err = copy_from_user_tmpl(xp, xfrma)))
768 err = copy_from_user_sec_ctx(xp, xfrma);
769
685 if (err) { 770 if (err) {
686 *errp = err; 771 *errp = err;
687 kfree(xp); 772 kfree(xp);
@@ -702,8 +787,11 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
702 err = verify_newpolicy_info(p); 787 err = verify_newpolicy_info(p);
703 if (err) 788 if (err)
704 return err; 789 return err;
790 err = verify_sec_ctx_len((struct rtattr **)xfrma);
791 if (err)
792 return err;
705 793
706 xp = xfrm_policy_construct(p, (struct rtattr **) xfrma, &err); 794 xp = xfrm_policy_construct(p, (struct rtattr **)xfrma, &err);
707 if (!xp) 795 if (!xp)
708 return err; 796 return err;
709 797
@@ -761,6 +849,27 @@ rtattr_failure:
761 return -1; 849 return -1;
762} 850}
763 851
852static int copy_to_user_sec_ctx(struct xfrm_policy *xp, struct sk_buff *skb)
853{
854 if (xp->security) {
855 int ctx_size = sizeof(struct xfrm_sec_ctx) +
856 xp->security->ctx_len;
857 struct rtattr *rt = __RTA_PUT(skb, XFRMA_SEC_CTX, ctx_size);
858 struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);
859
860 uctx->exttype = XFRMA_SEC_CTX;
861 uctx->len = ctx_size;
862 uctx->ctx_doi = xp->security->ctx_doi;
863 uctx->ctx_alg = xp->security->ctx_alg;
864 uctx->ctx_len = xp->security->ctx_len;
865 memcpy(uctx + 1, xp->security->ctx_str, xp->security->ctx_len);
866 }
867 return 0;
868
869 rtattr_failure:
870 return -1;
871}
872
764static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr) 873static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr)
765{ 874{
766 struct xfrm_dump_info *sp = ptr; 875 struct xfrm_dump_info *sp = ptr;
@@ -782,6 +891,8 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr
782 copy_to_user_policy(xp, p, dir); 891 copy_to_user_policy(xp, p, dir);
783 if (copy_to_user_tmpl(xp, skb) < 0) 892 if (copy_to_user_tmpl(xp, skb) < 0)
784 goto nlmsg_failure; 893 goto nlmsg_failure;
894 if (copy_to_user_sec_ctx(xp, skb))
895 goto nlmsg_failure;
785 896
786 nlh->nlmsg_len = skb->tail - b; 897 nlh->nlmsg_len = skb->tail - b;
787out: 898out:
@@ -852,8 +963,25 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
852 963
853 if (p->index) 964 if (p->index)
854 xp = xfrm_policy_byid(p->dir, p->index, delete); 965 xp = xfrm_policy_byid(p->dir, p->index, delete);
855 else 966 else {
856 xp = xfrm_policy_bysel(p->dir, &p->sel, delete); 967 struct rtattr **rtattrs = (struct rtattr **)xfrma;
968 struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1];
969 struct xfrm_policy tmp;
970
971 err = verify_sec_ctx_len(rtattrs);
972 if (err)
973 return err;
974
975 memset(&tmp, 0, sizeof(struct xfrm_policy));
976 if (rt) {
977 struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);
978
979 if ((err = security_xfrm_policy_alloc(&tmp, uctx)))
980 return err;
981 }
982 xp = xfrm_policy_bysel_ctx(p->dir, &p->sel, tmp.security, delete);
983 security_xfrm_policy_free(&tmp);
984 }
857 if (xp == NULL) 985 if (xp == NULL)
858 return -ENOENT; 986 return -ENOENT;
859 987
@@ -1224,6 +1352,8 @@ static int build_acquire(struct sk_buff *skb, struct xfrm_state *x,
1224 1352
1225 if (copy_to_user_tmpl(xp, skb) < 0) 1353 if (copy_to_user_tmpl(xp, skb) < 0)
1226 goto nlmsg_failure; 1354 goto nlmsg_failure;
1355 if (copy_to_user_sec_ctx(xp, skb))
1356 goto nlmsg_failure;
1227 1357
1228 nlh->nlmsg_len = skb->tail - b; 1358 nlh->nlmsg_len = skb->tail - b;
1229 return skb->len; 1359 return skb->len;
@@ -1241,6 +1371,7 @@ static int xfrm_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *xt,
1241 1371
1242 len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); 1372 len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
1243 len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire)); 1373 len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire));
1374 len += RTA_SPACE(xfrm_user_sec_ctx_size(xp));
1244 skb = alloc_skb(len, GFP_ATOMIC); 1375 skb = alloc_skb(len, GFP_ATOMIC);
1245 if (skb == NULL) 1376 if (skb == NULL)
1246 return -ENOMEM; 1377 return -ENOMEM;
@@ -1324,6 +1455,8 @@ static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp,
1324 copy_to_user_policy(xp, &upe->pol, dir); 1455 copy_to_user_policy(xp, &upe->pol, dir);
1325 if (copy_to_user_tmpl(xp, skb) < 0) 1456 if (copy_to_user_tmpl(xp, skb) < 0)
1326 goto nlmsg_failure; 1457 goto nlmsg_failure;
1458 if (copy_to_user_sec_ctx(xp, skb))
1459 goto nlmsg_failure;
1327 upe->hard = !!hard; 1460 upe->hard = !!hard;
1328 1461
1329 nlh->nlmsg_len = skb->tail - b; 1462 nlh->nlmsg_len = skb->tail - b;
@@ -1341,6 +1474,7 @@ static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_eve
1341 1474
1342 len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); 1475 len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
1343 len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire)); 1476 len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire));
1477 len += RTA_SPACE(xfrm_user_sec_ctx_size(xp));
1344 skb = alloc_skb(len, GFP_ATOMIC); 1478 skb = alloc_skb(len, GFP_ATOMIC);
1345 if (skb == NULL) 1479 if (skb == NULL)
1346 return -ENOMEM; 1480 return -ENOMEM;