diff options
Diffstat (limited to 'net/xfrm/xfrm_user.c')
-rw-r--r-- | net/xfrm/xfrm_user.c | 56 |
1 files changed, 25 insertions, 31 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index f964d4c00ffb..97681a390402 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -181,7 +181,9 @@ static int verify_newsa_info(struct xfrm_usersa_info *p, | |||
181 | attrs[XFRMA_ALG_AEAD] || | 181 | attrs[XFRMA_ALG_AEAD] || |
182 | attrs[XFRMA_ALG_CRYPT] || | 182 | attrs[XFRMA_ALG_CRYPT] || |
183 | attrs[XFRMA_ALG_COMP] || | 183 | attrs[XFRMA_ALG_COMP] || |
184 | attrs[XFRMA_TFCPAD]) | 184 | attrs[XFRMA_TFCPAD] || |
185 | (ntohl(p->id.spi) >= 0x10000)) | ||
186 | |||
185 | goto out; | 187 | goto out; |
186 | break; | 188 | break; |
187 | 189 | ||
@@ -877,7 +879,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) | 879 | static int xfrm_dump_sa_done(struct netlink_callback *cb) |
878 | { | 880 | { |
879 | struct xfrm_state_walk *walk = (struct xfrm_state_walk *) &cb->args[1]; | 881 | struct xfrm_state_walk *walk = (struct xfrm_state_walk *) &cb->args[1]; |
880 | xfrm_state_walk_done(walk); | 882 | struct sock *sk = cb->skb->sk; |
883 | struct net *net = sock_net(sk); | ||
884 | |||
885 | xfrm_state_walk_done(walk, net); | ||
881 | return 0; | 886 | return 0; |
882 | } | 887 | } |
883 | 888 | ||
@@ -1074,29 +1079,6 @@ out_noput: | |||
1074 | return err; | 1079 | return err; |
1075 | } | 1080 | } |
1076 | 1081 | ||
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, | 1082 | static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, |
1101 | struct nlattr **attrs) | 1083 | struct nlattr **attrs) |
1102 | { | 1084 | { |
@@ -1111,7 +1093,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1111 | struct xfrm_mark m; | 1093 | struct xfrm_mark m; |
1112 | 1094 | ||
1113 | p = nlmsg_data(nlh); | 1095 | p = nlmsg_data(nlh); |
1114 | err = verify_userspi_info(p); | 1096 | err = verify_spi_info(p->info.id.proto, p->min, p->max); |
1115 | if (err) | 1097 | if (err) |
1116 | goto out_noput; | 1098 | goto out_noput; |
1117 | 1099 | ||
@@ -1189,6 +1171,8 @@ static int verify_policy_type(u8 type) | |||
1189 | 1171 | ||
1190 | static int verify_newpolicy_info(struct xfrm_userpolicy_info *p) | 1172 | static int verify_newpolicy_info(struct xfrm_userpolicy_info *p) |
1191 | { | 1173 | { |
1174 | int ret; | ||
1175 | |||
1192 | switch (p->share) { | 1176 | switch (p->share) { |
1193 | case XFRM_SHARE_ANY: | 1177 | case XFRM_SHARE_ANY: |
1194 | case XFRM_SHARE_SESSION: | 1178 | case XFRM_SHARE_SESSION: |
@@ -1224,7 +1208,13 @@ static int verify_newpolicy_info(struct xfrm_userpolicy_info *p) | |||
1224 | return -EINVAL; | 1208 | return -EINVAL; |
1225 | } | 1209 | } |
1226 | 1210 | ||
1227 | return verify_policy_dir(p->dir); | 1211 | ret = verify_policy_dir(p->dir); |
1212 | if (ret) | ||
1213 | return ret; | ||
1214 | if (p->index && ((p->index & XFRM_POLICY_MAX) != p->dir)) | ||
1215 | return -EINVAL; | ||
1216 | |||
1217 | return 0; | ||
1228 | } | 1218 | } |
1229 | 1219 | ||
1230 | static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct nlattr **attrs) | 1220 | static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct nlattr **attrs) |
@@ -1547,8 +1537,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) | 1537 | static int xfrm_dump_policy_done(struct netlink_callback *cb) |
1548 | { | 1538 | { |
1549 | struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1]; | 1539 | struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1]; |
1540 | struct net *net = sock_net(cb->skb->sk); | ||
1550 | 1541 | ||
1551 | xfrm_policy_walk_done(walk); | 1542 | xfrm_policy_walk_done(walk, net); |
1552 | return 0; | 1543 | return 0; |
1553 | } | 1544 | } |
1554 | 1545 | ||
@@ -2129,6 +2120,7 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
2129 | u8 type; | 2120 | u8 type; |
2130 | int err; | 2121 | int err; |
2131 | int n = 0; | 2122 | int n = 0; |
2123 | struct net *net = sock_net(skb->sk); | ||
2132 | 2124 | ||
2133 | if (attrs[XFRMA_MIGRATE] == NULL) | 2125 | if (attrs[XFRMA_MIGRATE] == NULL) |
2134 | return -EINVAL; | 2126 | return -EINVAL; |
@@ -2146,7 +2138,7 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
2146 | if (!n) | 2138 | if (!n) |
2147 | return 0; | 2139 | return 0; |
2148 | 2140 | ||
2149 | xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp); | 2141 | xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net); |
2150 | 2142 | ||
2151 | return 0; | 2143 | return 0; |
2152 | } | 2144 | } |
@@ -2394,9 +2386,11 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2394 | 2386 | ||
2395 | static void xfrm_netlink_rcv(struct sk_buff *skb) | 2387 | static void xfrm_netlink_rcv(struct sk_buff *skb) |
2396 | { | 2388 | { |
2397 | mutex_lock(&xfrm_cfg_mutex); | 2389 | struct net *net = sock_net(skb->sk); |
2390 | |||
2391 | mutex_lock(&net->xfrm.xfrm_cfg_mutex); | ||
2398 | netlink_rcv_skb(skb, &xfrm_user_rcv_msg); | 2392 | netlink_rcv_skb(skb, &xfrm_user_rcv_msg); |
2399 | mutex_unlock(&xfrm_cfg_mutex); | 2393 | mutex_unlock(&net->xfrm.xfrm_cfg_mutex); |
2400 | } | 2394 | } |
2401 | 2395 | ||
2402 | static inline size_t xfrm_expire_msgsize(void) | 2396 | static inline size_t xfrm_expire_msgsize(void) |