diff options
Diffstat (limited to 'net/xfrm/xfrm_user.c')
-rw-r--r-- | net/xfrm/xfrm_user.c | 85 |
1 files changed, 37 insertions, 48 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index f964d4c00ffb..2f7ddc3a59b4 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -32,11 +32,6 @@ | |||
32 | #include <linux/in6.h> | 32 | #include <linux/in6.h> |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | static inline int aead_len(struct xfrm_algo_aead *alg) | ||
36 | { | ||
37 | return sizeof(*alg) + ((alg->alg_key_len + 7) / 8); | ||
38 | } | ||
39 | |||
40 | static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type) | 35 | static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type) |
41 | { | 36 | { |
42 | struct nlattr *rt = attrs[type]; | 37 | struct nlattr *rt = attrs[type]; |
@@ -181,7 +176,9 @@ static int verify_newsa_info(struct xfrm_usersa_info *p, | |||
181 | attrs[XFRMA_ALG_AEAD] || | 176 | attrs[XFRMA_ALG_AEAD] || |
182 | attrs[XFRMA_ALG_CRYPT] || | 177 | attrs[XFRMA_ALG_CRYPT] || |
183 | attrs[XFRMA_ALG_COMP] || | 178 | attrs[XFRMA_ALG_COMP] || |
184 | attrs[XFRMA_TFCPAD]) | 179 | attrs[XFRMA_TFCPAD] || |
180 | (ntohl(p->id.spi) >= 0x10000)) | ||
181 | |||
185 | goto out; | 182 | goto out; |
186 | break; | 183 | break; |
187 | 184 | ||
@@ -600,7 +597,7 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
600 | int err; | 597 | int err; |
601 | struct km_event c; | 598 | struct km_event c; |
602 | kuid_t loginuid = audit_get_loginuid(current); | 599 | kuid_t loginuid = audit_get_loginuid(current); |
603 | u32 sessionid = audit_get_sessionid(current); | 600 | unsigned int sessionid = audit_get_sessionid(current); |
604 | u32 sid; | 601 | u32 sid; |
605 | 602 | ||
606 | err = verify_newsa_info(p, attrs); | 603 | err = verify_newsa_info(p, attrs); |
@@ -679,7 +676,7 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
679 | struct km_event c; | 676 | struct km_event c; |
680 | struct xfrm_usersa_id *p = nlmsg_data(nlh); | 677 | struct xfrm_usersa_id *p = nlmsg_data(nlh); |
681 | kuid_t loginuid = audit_get_loginuid(current); | 678 | kuid_t loginuid = audit_get_loginuid(current); |
682 | u32 sessionid = audit_get_sessionid(current); | 679 | unsigned int sessionid = audit_get_sessionid(current); |
683 | u32 sid; | 680 | u32 sid; |
684 | 681 | ||
685 | x = xfrm_user_state_lookup(net, p, attrs, &err); | 682 | x = xfrm_user_state_lookup(net, p, attrs, &err); |
@@ -877,7 +874,10 @@ static int dump_one_state(struct xfrm_state *x, int count, void *ptr) | |||
877 | static int xfrm_dump_sa_done(struct netlink_callback *cb) | 874 | static int xfrm_dump_sa_done(struct netlink_callback *cb) |
878 | { | 875 | { |
879 | struct xfrm_state_walk *walk = (struct xfrm_state_walk *) &cb->args[1]; | 876 | struct xfrm_state_walk *walk = (struct xfrm_state_walk *) &cb->args[1]; |
880 | xfrm_state_walk_done(walk); | 877 | struct sock *sk = cb->skb->sk; |
878 | struct net *net = sock_net(sk); | ||
879 | |||
880 | xfrm_state_walk_done(walk, net); | ||
881 | return 0; | 881 | return 0; |
882 | } | 882 | } |
883 | 883 | ||
@@ -1074,29 +1074,6 @@ out_noput: | |||
1074 | return err; | 1074 | return err; |
1075 | } | 1075 | } |
1076 | 1076 | ||
1077 | static int verify_userspi_info(struct xfrm_userspi_info *p) | ||
1078 | { | ||
1079 | switch (p->info.id.proto) { | ||
1080 | case IPPROTO_AH: | ||
1081 | case IPPROTO_ESP: | ||
1082 | break; | ||
1083 | |||
1084 | case IPPROTO_COMP: | ||
1085 | /* IPCOMP spi is 16-bits. */ | ||
1086 | if (p->max >= 0x10000) | ||
1087 | return -EINVAL; | ||
1088 | break; | ||
1089 | |||
1090 | default: | ||
1091 | return -EINVAL; | ||
1092 | } | ||
1093 | |||
1094 | if (p->min > p->max) | ||
1095 | return -EINVAL; | ||
1096 | |||
1097 | return 0; | ||
1098 | } | ||
1099 | |||
1100 | static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, | 1077 | static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, |
1101 | struct nlattr **attrs) | 1078 | struct nlattr **attrs) |
1102 | { | 1079 | { |
@@ -1111,7 +1088,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1111 | struct xfrm_mark m; | 1088 | struct xfrm_mark m; |
1112 | 1089 | ||
1113 | p = nlmsg_data(nlh); | 1090 | p = nlmsg_data(nlh); |
1114 | err = verify_userspi_info(p); | 1091 | err = verify_spi_info(p->info.id.proto, p->min, p->max); |
1115 | if (err) | 1092 | if (err) |
1116 | goto out_noput; | 1093 | goto out_noput; |
1117 | 1094 | ||
@@ -1189,6 +1166,8 @@ static int verify_policy_type(u8 type) | |||
1189 | 1166 | ||
1190 | static int verify_newpolicy_info(struct xfrm_userpolicy_info *p) | 1167 | static int verify_newpolicy_info(struct xfrm_userpolicy_info *p) |
1191 | { | 1168 | { |
1169 | int ret; | ||
1170 | |||
1192 | switch (p->share) { | 1171 | switch (p->share) { |
1193 | case XFRM_SHARE_ANY: | 1172 | case XFRM_SHARE_ANY: |
1194 | case XFRM_SHARE_SESSION: | 1173 | case XFRM_SHARE_SESSION: |
@@ -1224,7 +1203,13 @@ static int verify_newpolicy_info(struct xfrm_userpolicy_info *p) | |||
1224 | return -EINVAL; | 1203 | return -EINVAL; |
1225 | } | 1204 | } |
1226 | 1205 | ||
1227 | return verify_policy_dir(p->dir); | 1206 | ret = verify_policy_dir(p->dir); |
1207 | if (ret) | ||
1208 | return ret; | ||
1209 | if (p->index && ((p->index & XFRM_POLICY_MAX) != p->dir)) | ||
1210 | return -EINVAL; | ||
1211 | |||
1212 | return 0; | ||
1228 | } | 1213 | } |
1229 | 1214 | ||
1230 | static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct nlattr **attrs) | 1215 | static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct nlattr **attrs) |
@@ -1236,7 +1221,7 @@ static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct nlattr **attrs | |||
1236 | return 0; | 1221 | return 0; |
1237 | 1222 | ||
1238 | uctx = nla_data(rt); | 1223 | uctx = nla_data(rt); |
1239 | return security_xfrm_policy_alloc(&pol->security, uctx); | 1224 | return security_xfrm_policy_alloc(&pol->security, uctx, GFP_KERNEL); |
1240 | } | 1225 | } |
1241 | 1226 | ||
1242 | static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut, | 1227 | static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut, |
@@ -1405,7 +1390,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1405 | int err; | 1390 | int err; |
1406 | int excl; | 1391 | int excl; |
1407 | kuid_t loginuid = audit_get_loginuid(current); | 1392 | kuid_t loginuid = audit_get_loginuid(current); |
1408 | u32 sessionid = audit_get_sessionid(current); | 1393 | unsigned int sessionid = audit_get_sessionid(current); |
1409 | u32 sid; | 1394 | u32 sid; |
1410 | 1395 | ||
1411 | err = verify_newpolicy_info(p); | 1396 | err = verify_newpolicy_info(p); |
@@ -1547,8 +1532,9 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr | |||
1547 | static int xfrm_dump_policy_done(struct netlink_callback *cb) | 1532 | static int xfrm_dump_policy_done(struct netlink_callback *cb) |
1548 | { | 1533 | { |
1549 | struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1]; | 1534 | struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1]; |
1535 | struct net *net = sock_net(cb->skb->sk); | ||
1550 | 1536 | ||
1551 | xfrm_policy_walk_done(walk); | 1537 | xfrm_policy_walk_done(walk, net); |
1552 | return 0; | 1538 | return 0; |
1553 | } | 1539 | } |
1554 | 1540 | ||
@@ -1640,7 +1626,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1640 | if (rt) { | 1626 | if (rt) { |
1641 | struct xfrm_user_sec_ctx *uctx = nla_data(rt); | 1627 | struct xfrm_user_sec_ctx *uctx = nla_data(rt); |
1642 | 1628 | ||
1643 | err = security_xfrm_policy_alloc(&ctx, uctx); | 1629 | err = security_xfrm_policy_alloc(&ctx, uctx, GFP_KERNEL); |
1644 | if (err) | 1630 | if (err) |
1645 | return err; | 1631 | return err; |
1646 | } | 1632 | } |
@@ -1663,7 +1649,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1663 | } | 1649 | } |
1664 | } else { | 1650 | } else { |
1665 | kuid_t loginuid = audit_get_loginuid(current); | 1651 | kuid_t loginuid = audit_get_loginuid(current); |
1666 | u32 sessionid = audit_get_sessionid(current); | 1652 | unsigned int sessionid = audit_get_sessionid(current); |
1667 | u32 sid; | 1653 | u32 sid; |
1668 | 1654 | ||
1669 | security_task_getsecid(current, &sid); | 1655 | security_task_getsecid(current, &sid); |
@@ -1740,11 +1726,11 @@ static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, const struct | |||
1740 | return -EMSGSIZE; | 1726 | return -EMSGSIZE; |
1741 | 1727 | ||
1742 | id = nlmsg_data(nlh); | 1728 | id = nlmsg_data(nlh); |
1743 | memcpy(&id->sa_id.daddr, &x->id.daddr,sizeof(x->id.daddr)); | 1729 | memcpy(&id->sa_id.daddr, &x->id.daddr, sizeof(x->id.daddr)); |
1744 | id->sa_id.spi = x->id.spi; | 1730 | id->sa_id.spi = x->id.spi; |
1745 | id->sa_id.family = x->props.family; | 1731 | id->sa_id.family = x->props.family; |
1746 | id->sa_id.proto = x->id.proto; | 1732 | id->sa_id.proto = x->id.proto; |
1747 | memcpy(&id->saddr, &x->props.saddr,sizeof(x->props.saddr)); | 1733 | memcpy(&id->saddr, &x->props.saddr, sizeof(x->props.saddr)); |
1748 | id->reqid = x->props.reqid; | 1734 | id->reqid = x->props.reqid; |
1749 | id->flags = c->data.aevent; | 1735 | id->flags = c->data.aevent; |
1750 | 1736 | ||
@@ -1833,7 +1819,7 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1833 | struct net *net = sock_net(skb->sk); | 1819 | struct net *net = sock_net(skb->sk); |
1834 | struct xfrm_state *x; | 1820 | struct xfrm_state *x; |
1835 | struct km_event c; | 1821 | struct km_event c; |
1836 | int err = - EINVAL; | 1822 | int err = -EINVAL; |
1837 | u32 mark = 0; | 1823 | u32 mark = 0; |
1838 | struct xfrm_mark m; | 1824 | struct xfrm_mark m; |
1839 | struct xfrm_aevent_id *p = nlmsg_data(nlh); | 1825 | struct xfrm_aevent_id *p = nlmsg_data(nlh); |
@@ -1942,7 +1928,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1942 | if (rt) { | 1928 | if (rt) { |
1943 | struct xfrm_user_sec_ctx *uctx = nla_data(rt); | 1929 | struct xfrm_user_sec_ctx *uctx = nla_data(rt); |
1944 | 1930 | ||
1945 | err = security_xfrm_policy_alloc(&ctx, uctx); | 1931 | err = security_xfrm_policy_alloc(&ctx, uctx, GFP_KERNEL); |
1946 | if (err) | 1932 | if (err) |
1947 | return err; | 1933 | return err; |
1948 | } | 1934 | } |
@@ -1959,7 +1945,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1959 | err = 0; | 1945 | err = 0; |
1960 | if (up->hard) { | 1946 | if (up->hard) { |
1961 | kuid_t loginuid = audit_get_loginuid(current); | 1947 | kuid_t loginuid = audit_get_loginuid(current); |
1962 | u32 sessionid = audit_get_sessionid(current); | 1948 | unsigned int sessionid = audit_get_sessionid(current); |
1963 | u32 sid; | 1949 | u32 sid; |
1964 | 1950 | ||
1965 | security_task_getsecid(current, &sid); | 1951 | security_task_getsecid(current, &sid); |
@@ -2002,7 +1988,7 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
2002 | 1988 | ||
2003 | if (ue->hard) { | 1989 | if (ue->hard) { |
2004 | kuid_t loginuid = audit_get_loginuid(current); | 1990 | kuid_t loginuid = audit_get_loginuid(current); |
2005 | u32 sessionid = audit_get_sessionid(current); | 1991 | unsigned int sessionid = audit_get_sessionid(current); |
2006 | u32 sid; | 1992 | u32 sid; |
2007 | 1993 | ||
2008 | security_task_getsecid(current, &sid); | 1994 | security_task_getsecid(current, &sid); |
@@ -2129,6 +2115,7 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
2129 | u8 type; | 2115 | u8 type; |
2130 | int err; | 2116 | int err; |
2131 | int n = 0; | 2117 | int n = 0; |
2118 | struct net *net = sock_net(skb->sk); | ||
2132 | 2119 | ||
2133 | if (attrs[XFRMA_MIGRATE] == NULL) | 2120 | if (attrs[XFRMA_MIGRATE] == NULL) |
2134 | return -EINVAL; | 2121 | return -EINVAL; |
@@ -2146,7 +2133,7 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
2146 | if (!n) | 2133 | if (!n) |
2147 | return 0; | 2134 | return 0; |
2148 | 2135 | ||
2149 | xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp); | 2136 | xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net); |
2150 | 2137 | ||
2151 | return 0; | 2138 | return 0; |
2152 | } | 2139 | } |
@@ -2394,9 +2381,11 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2394 | 2381 | ||
2395 | static void xfrm_netlink_rcv(struct sk_buff *skb) | 2382 | static void xfrm_netlink_rcv(struct sk_buff *skb) |
2396 | { | 2383 | { |
2397 | mutex_lock(&xfrm_cfg_mutex); | 2384 | struct net *net = sock_net(skb->sk); |
2385 | |||
2386 | mutex_lock(&net->xfrm.xfrm_cfg_mutex); | ||
2398 | netlink_rcv_skb(skb, &xfrm_user_rcv_msg); | 2387 | netlink_rcv_skb(skb, &xfrm_user_rcv_msg); |
2399 | mutex_unlock(&xfrm_cfg_mutex); | 2388 | mutex_unlock(&net->xfrm.xfrm_cfg_mutex); |
2400 | } | 2389 | } |
2401 | 2390 | ||
2402 | static inline size_t xfrm_expire_msgsize(void) | 2391 | static inline size_t xfrm_expire_msgsize(void) |