Hello Ridong, On Sat, Nov 23, 2024 at 08:05:09AM +0000, Chen Ridong wrote: > From: Chen Ridong <chenridong@xxxxxxxxxx> > > A bug was found when run ltp test: ...snip... > This can be explained as bellow: > > pcrypt_aead_encrypt > ... > padata_do_parallel > refcount_inc(&pd->refcnt); // add refcnt > ... > padata_do_serial > padata_reorder // pd > while (1) { > padata_find_next(pd, true); // using pd > queue_work_on > ... > padata_serial_worker crypto_del_alg > padata_put_pd_cnt // sub refcnt > padata_free_shell > padata_put_pd(ps->pd); > // pd is freed > // loop again, but pd is freed > // call padata_find_next, UAF > } Thanks for the fix and clear explanation. > diff --git a/kernel/padata.c b/kernel/padata.c > index 5d8e18cdcb25..627014825266 100644 > --- a/kernel/padata.c > +++ b/kernel/padata.c > @@ -319,6 +319,7 @@ static void padata_reorder(struct parallel_data *pd) > if (!spin_trylock_bh(&pd->lock)) > return; > > + padata_get_pd(pd); > while (1) { > padata = padata_find_next(pd, true); > > @@ -355,6 +356,7 @@ static void padata_reorder(struct parallel_data *pd) > reorder = per_cpu_ptr(pd->reorder_list, pd->cpu); > if (!list_empty(&reorder->list) && padata_find_next(pd, false)) > queue_work(pinst->serial_wq, &pd->reorder_work); > + padata_put_pd(pd); Putting the ref unconditionally here doesn't cover the case where reorder_work is queued and accesses the freed pd. The review of patches 3-5 from this series has a potential solution for this that also keeps some of these refcount operations out of the fast path: https://lore.kernel.org/all/20221019083708.27138-1-nstange@xxxxxxx/