Unverified Commit d289e187 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!15683 CVE-2025-21726

Merge Pull Request from: @ci-robot 
 
PR sync from: Zicheng Qu <quzicheng@huawei.com>
https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/PHSJ2J5JWOWKVPKT6GJMYG46TTWGZQK7/ 
Chen Ridong (2):
  padata: add pd get/put refcnt helper
  padata: avoid UAF for reorder_work

 
https://gitee.com/src-openeuler/kernel/issues/IBPBHS
https://gitee.com/src-openeuler/kernel/issues/IBPBDP 
 
Link:https://gitee.com/openeuler/kernel/pulls/15683

 

Reviewed-by: default avatarLu Jialin <lujialin4@huawei.com>
Reviewed-by: default avatarLi Nan <linan122@huawei.com>
Signed-off-by: default avatarLi Nan <linan122@huawei.com>
parents b82e5397 f8fc1343
Loading
Loading
Loading
Loading
+29 −8
Original line number Diff line number Diff line
@@ -60,6 +60,22 @@ struct padata_mt_job_state {
static void padata_free_pd(struct parallel_data *pd);
static void __init padata_mt_helper(struct work_struct *work);

static inline void padata_get_pd(struct parallel_data *pd)
{
	refcount_inc(&pd->refcnt);
}

static inline void padata_put_pd_cnt(struct parallel_data *pd, int cnt)
{
	if (refcount_sub_and_test(cnt, &pd->refcnt))
		padata_free_pd(pd);
}

static inline void padata_put_pd(struct parallel_data *pd)
{
	padata_put_pd_cnt(pd, 1);
}

static int padata_index_to_cpu(struct parallel_data *pd, int cpu_index)
{
	int cpu, target_cpu;
@@ -211,7 +227,7 @@ int padata_do_parallel(struct padata_shell *ps,
	if ((pinst->flags & PADATA_RESET))
		goto out;

	refcount_inc(&pd->refcnt);
	padata_get_pd(pd);
	padata->pd = pd;
	padata->cb_cpu = *cb_cpu;

@@ -341,9 +357,15 @@ static void padata_reorder(struct parallel_data *pd)
	smp_mb();

	reorder = per_cpu_ptr(pd->reorder_list, pd->cpu);
	if (!list_empty(&reorder->list) && padata_find_next(pd, false))
	if (!list_empty(&reorder->list) && padata_find_next(pd, false)) {
		/*
		 * Other context(eg. the padata_serial_worker) can finish the request.
		 * To avoid UAF issue, add pd ref here, and put pd ref after reorder_work finish.
		 */
		padata_get_pd(pd);
		queue_work(pinst->serial_wq, &pd->reorder_work);
	}
}

static void invoke_padata_reorder(struct work_struct *work)
{
@@ -353,6 +375,8 @@ static void invoke_padata_reorder(struct work_struct *work)
	pd = container_of(work, struct parallel_data, reorder_work);
	padata_reorder(pd);
	local_bh_enable();
	/* Pairs with putting the reorder_work in the serial_wq */
	padata_put_pd(pd);
}

static void padata_serial_worker(struct work_struct *serial_work)
@@ -385,8 +409,7 @@ static void padata_serial_worker(struct work_struct *serial_work)
	}
	local_bh_enable();

	if (refcount_sub_and_test(cnt, &pd->refcnt))
		padata_free_pd(pd);
	padata_put_pd_cnt(pd, cnt);
}

/**
@@ -680,8 +703,7 @@ static int padata_replace(struct padata_instance *pinst)
	synchronize_rcu();

	list_for_each_entry_continue_reverse(ps, &pinst->pslist, list)
		if (refcount_dec_and_test(&ps->opd->refcnt))
			padata_free_pd(ps->opd);
		padata_put_pd(ps->opd);

	pinst->flags &= ~PADATA_RESET;

@@ -1129,8 +1151,7 @@ void padata_free_shell(struct padata_shell *ps)
	mutex_lock(&ps->pinst->lock);
	list_del(&ps->list);
	pd = rcu_dereference_protected(ps->pd, 1);
	if (refcount_dec_and_test(&pd->refcnt))
		padata_free_pd(pd);
	padata_put_pd(pd);
	mutex_unlock(&ps->pinst->lock);

	kfree(ps);