Skip to content

Commit 766f6a7

Browse files
committed
Merge branch 'xfrm: fixes for xfrm_state_find under preemption'
Sabrina Dubroca says: ==================== While looking at the pcpu_id changes, I found two issues that can happen if we get preempted and the cpu_id changes. The second patch takes care of both problems. The first patch also makes sure we don't use state_ptrs uninitialized, which could currently happen. syzbot seems to have hit this issue [1]. [1] https://syzkaller.appspot.com/bug?extid=7ed9d47e15e88581dc5b ==================== Signed-off-by: Steffen Klassert <[email protected]>
2 parents b56bbaf + 7eb11c0 commit 766f6a7

File tree

1 file changed

+8
-15
lines changed

1 file changed

+8
-15
lines changed

net/xfrm/xfrm_state.c

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,14 +1307,8 @@ static void xfrm_hash_grow_check(struct net *net, int have_hash_collision)
13071307
static void xfrm_state_look_at(struct xfrm_policy *pol, struct xfrm_state *x,
13081308
const struct flowi *fl, unsigned short family,
13091309
struct xfrm_state **best, int *acq_in_progress,
1310-
int *error)
1310+
int *error, unsigned int pcpu_id)
13111311
{
1312-
/* We need the cpu id just as a lookup key,
1313-
* we don't require it to be stable.
1314-
*/
1315-
unsigned int pcpu_id = get_cpu();
1316-
put_cpu();
1317-
13181312
/* Resolution logic:
13191313
* 1. There is a valid state with matching selector. Done.
13201314
* 2. Valid state with inappropriate selector. Skip.
@@ -1381,14 +1375,15 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
13811375
/* We need the cpu id just as a lookup key,
13821376
* we don't require it to be stable.
13831377
*/
1384-
pcpu_id = get_cpu();
1385-
put_cpu();
1378+
pcpu_id = raw_smp_processor_id();
13861379

13871380
to_put = NULL;
13881381

13891382
sequence = read_seqcount_begin(&net->xfrm.xfrm_state_hash_generation);
13901383

13911384
rcu_read_lock();
1385+
xfrm_hash_ptrs_get(net, &state_ptrs);
1386+
13921387
hlist_for_each_entry_rcu(x, &pol->state_cache_list, state_cache) {
13931388
if (x->props.family == encap_family &&
13941389
x->props.reqid == tmpl->reqid &&
@@ -1400,7 +1395,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
14001395
tmpl->id.proto == x->id.proto &&
14011396
(tmpl->id.spi == x->id.spi || !tmpl->id.spi))
14021397
xfrm_state_look_at(pol, x, fl, encap_family,
1403-
&best, &acquire_in_progress, &error);
1398+
&best, &acquire_in_progress, &error, pcpu_id);
14041399
}
14051400

14061401
if (best)
@@ -1417,7 +1412,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
14171412
tmpl->id.proto == x->id.proto &&
14181413
(tmpl->id.spi == x->id.spi || !tmpl->id.spi))
14191414
xfrm_state_look_at(pol, x, fl, family,
1420-
&best, &acquire_in_progress, &error);
1415+
&best, &acquire_in_progress, &error, pcpu_id);
14211416
}
14221417

14231418
cached:
@@ -1429,8 +1424,6 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
14291424
else if (acquire_in_progress) /* XXX: acquire_in_progress should not happen */
14301425
WARN_ON(1);
14311426

1432-
xfrm_hash_ptrs_get(net, &state_ptrs);
1433-
14341427
h = __xfrm_dst_hash(daddr, saddr, tmpl->reqid, encap_family, state_ptrs.hmask);
14351428
hlist_for_each_entry_rcu(x, state_ptrs.bydst + h, bydst) {
14361429
#ifdef CONFIG_XFRM_OFFLOAD
@@ -1460,7 +1453,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
14601453
tmpl->id.proto == x->id.proto &&
14611454
(tmpl->id.spi == x->id.spi || !tmpl->id.spi))
14621455
xfrm_state_look_at(pol, x, fl, family,
1463-
&best, &acquire_in_progress, &error);
1456+
&best, &acquire_in_progress, &error, pcpu_id);
14641457
}
14651458
if (best || acquire_in_progress)
14661459
goto found;
@@ -1495,7 +1488,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
14951488
tmpl->id.proto == x->id.proto &&
14961489
(tmpl->id.spi == x->id.spi || !tmpl->id.spi))
14971490
xfrm_state_look_at(pol, x, fl, family,
1498-
&best, &acquire_in_progress, &error);
1491+
&best, &acquire_in_progress, &error, pcpu_id);
14991492
}
15001493

15011494
found:

0 commit comments

Comments
 (0)