aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm')
-rw-r--r--net/xfrm/xfrm_policy.c16
-rw-r--r--net/xfrm/xfrm_user.c10
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. */
541static u32 xfrm_gen_index(struct net *net, int dir) 541static 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
1190static int verify_newpolicy_info(struct xfrm_userpolicy_info *p) 1190static 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
1230static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct nlattr **attrs) 1238static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct nlattr **attrs)