aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2018-11-27 07:28:54 -0500
committerSteffen Klassert <steffen.klassert@secunet.com>2018-11-28 01:05:48 -0500
commit88584c30e31967db2ad03c7015a9aea3460deb2c (patch)
tree6406da2c4e7866f0ce659a891a4f2f1ffe652d7d /net/xfrm
parent3fcccec008cf095ac61018cfce0e4bb76edddb5b (diff)
xfrm: policy: fix policy hash rebuild
Dan Carpenter reports following static checker warning: net/xfrm/xfrm_policy.c:1316 xfrm_hash_rebuild() warn: 'dir' is out of bounds '3' vs '2' | 1280 /* reset the bydst and inexact table in all directions */ | 1281 xfrm_hash_reset_inexact_table(net); | 1282 | 1283 for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { | ^^^^^^^^^^^^^^^^^^^^^ |dir == XFRM_POLICY_MAX at the end of this loop. | 1304 /* re-insert all policies by order of creation */ | 1305 list_for_each_entry_reverse(policy, &net->xfrm.policy_all, walk.all) { [..] | 1314 xfrm_policy_id2dir(policy->index)); | 1315 if (!chain) { | 1316 void *p = xfrm_policy_inexact_insert(policy, dir, 0); Fix this by updating 'dir' based on current policy. Otherwise, the inexact policies won't be found anymore during lookup, as they get hashed to a bogus bin. Reported-by: Dan Carpenter <dan.carpenter@oracle.com> Fixes: cc1bb845adc9 ("xfrm: policy: return NULL when inexact search needed") Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/xfrm')
-rw-r--r--net/xfrm/xfrm_policy.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index ddc3335dd552..be04091eb7db 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1303,15 +1303,16 @@ static void xfrm_hash_rebuild(struct work_struct *work)
1303 1303
1304 /* re-insert all policies by order of creation */ 1304 /* re-insert all policies by order of creation */
1305 list_for_each_entry_reverse(policy, &net->xfrm.policy_all, walk.all) { 1305 list_for_each_entry_reverse(policy, &net->xfrm.policy_all, walk.all) {
1306 if (policy->walk.dead || 1306 if (policy->walk.dead)
1307 xfrm_policy_id2dir(policy->index) >= XFRM_POLICY_MAX) { 1307 continue;
1308 dir = xfrm_policy_id2dir(policy->index);
1309 if (dir >= XFRM_POLICY_MAX) {
1308 /* skip socket policies */ 1310 /* skip socket policies */
1309 continue; 1311 continue;
1310 } 1312 }
1311 newpos = NULL; 1313 newpos = NULL;
1312 chain = policy_hash_bysel(net, &policy->selector, 1314 chain = policy_hash_bysel(net, &policy->selector,
1313 policy->family, 1315 policy->family, dir);
1314 xfrm_policy_id2dir(policy->index));
1315 if (!chain) { 1316 if (!chain) {
1316 void *p = xfrm_policy_inexact_insert(policy, dir, 0); 1317 void *p = xfrm_policy_inexact_insert(policy, dir, 0);
1317 1318