diff options
Diffstat (limited to 'net/xfrm')
-rw-r--r-- | net/xfrm/xfrm_policy.c | 16 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 10 |
2 files changed, 20 insertions, 6 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 9a91f7431c41..a5bbdfb2874b 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -538,7 +538,7 @@ static void xfrm_hash_resize(struct work_struct *work) | |||
538 | 538 | ||
539 | /* Generate new index... KAME seems to generate them ordered by cost | 539 | /* Generate new index... KAME seems to generate them ordered by cost |
540 | * of an absolute inpredictability of ordering of rules. This will not pass. */ | 540 | * of an absolute inpredictability of ordering of rules. This will not pass. */ |
541 | static u32 xfrm_gen_index(struct net *net, int dir) | 541 | static u32 xfrm_gen_index(struct net *net, int dir, u32 index) |
542 | { | 542 | { |
543 | static u32 idx_generator; | 543 | static u32 idx_generator; |
544 | 544 | ||
@@ -548,8 +548,14 @@ static u32 xfrm_gen_index(struct net *net, int dir) | |||
548 | u32 idx; | 548 | u32 idx; |
549 | int found; | 549 | int found; |
550 | 550 | ||
551 | idx = (idx_generator | dir); | 551 | if (!index) { |
552 | idx_generator += 8; | 552 | idx = (idx_generator | dir); |
553 | idx_generator += 8; | ||
554 | } else { | ||
555 | idx = index; | ||
556 | index = 0; | ||
557 | } | ||
558 | |||
553 | if (idx == 0) | 559 | if (idx == 0) |
554 | idx = 8; | 560 | idx = 8; |
555 | list = net->xfrm.policy_byidx + idx_hash(net, idx); | 561 | list = net->xfrm.policy_byidx + idx_hash(net, idx); |
@@ -672,7 +678,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) | |||
672 | xfrm_policy_requeue(delpol, policy); | 678 | xfrm_policy_requeue(delpol, policy); |
673 | __xfrm_policy_unlink(delpol, dir); | 679 | __xfrm_policy_unlink(delpol, dir); |
674 | } | 680 | } |
675 | policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir); | 681 | policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir, policy->index); |
676 | hlist_add_head(&policy->byidx, net->xfrm.policy_byidx+idx_hash(net, policy->index)); | 682 | hlist_add_head(&policy->byidx, net->xfrm.policy_byidx+idx_hash(net, policy->index)); |
677 | policy->curlft.add_time = get_seconds(); | 683 | policy->curlft.add_time = get_seconds(); |
678 | policy->curlft.use_time = 0; | 684 | policy->curlft.use_time = 0; |
@@ -1192,7 +1198,7 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol) | |||
1192 | sk->sk_policy[dir] = pol; | 1198 | sk->sk_policy[dir] = pol; |
1193 | if (pol) { | 1199 | if (pol) { |
1194 | pol->curlft.add_time = get_seconds(); | 1200 | pol->curlft.add_time = get_seconds(); |
1195 | pol->index = xfrm_gen_index(net, XFRM_POLICY_MAX+dir); | 1201 | pol->index = xfrm_gen_index(net, XFRM_POLICY_MAX+dir, 0); |
1196 | __xfrm_policy_link(pol, XFRM_POLICY_MAX+dir); | 1202 | __xfrm_policy_link(pol, XFRM_POLICY_MAX+dir); |
1197 | } | 1203 | } |
1198 | if (old_pol) { | 1204 | if (old_pol) { |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index f964d4c00ffb..4e0546e9bb0a 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -1189,6 +1189,8 @@ static int verify_policy_type(u8 type) | |||
1189 | 1189 | ||
1190 | static int verify_newpolicy_info(struct xfrm_userpolicy_info *p) | 1190 | static int verify_newpolicy_info(struct xfrm_userpolicy_info *p) |
1191 | { | 1191 | { |
1192 | int ret; | ||
1193 | |||
1192 | switch (p->share) { | 1194 | switch (p->share) { |
1193 | case XFRM_SHARE_ANY: | 1195 | case XFRM_SHARE_ANY: |
1194 | case XFRM_SHARE_SESSION: | 1196 | case XFRM_SHARE_SESSION: |
@@ -1224,7 +1226,13 @@ static int verify_newpolicy_info(struct xfrm_userpolicy_info *p) | |||
1224 | return -EINVAL; | 1226 | return -EINVAL; |
1225 | } | 1227 | } |
1226 | 1228 | ||
1227 | return verify_policy_dir(p->dir); | 1229 | ret = verify_policy_dir(p->dir); |
1230 | if (ret) | ||
1231 | return ret; | ||
1232 | if (p->index && ((p->index & XFRM_POLICY_MAX) != p->dir)) | ||
1233 | return -EINVAL; | ||
1234 | |||
1235 | return 0; | ||
1228 | } | 1236 | } |
1229 | 1237 | ||
1230 | static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct nlattr **attrs) | 1238 | static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct nlattr **attrs) |