Re: [PATCH -next v3 3/3] blk-cgroup: synchronize pd_free_fn() from blkg_free_workfn() and blkcg_deactivate_policy()

From: Tejun Heo
Date: Thu Jan 19 2023 - 11:16:11 EST


On Thu, Jan 19, 2023 at 07:03:50PM +0800, Yu Kuai wrote:
> From: Yu Kuai <yukuai3@xxxxxxxxxx>
>
> Currently parent pd can be freed before child pd:
>
> t1: remove cgroup C1
> blkcg_destroy_blkgs
> blkg_destroy
> list_del_init(&blkg->q_node)
> // remove blkg from queue list
> percpu_ref_kill(&blkg->refcnt)
> blkg_release
> call_rcu
>
> t2: from t1
> __blkg_release
> blkg_free
> schedule_work
> t4: deactivate policy
> blkcg_deactivate_policy
> pd_free_fn
> // parent of C1 is freed first
> t3: from t2
> blkg_free_workfn
> pd_free_fn
>
> If policy(for example, ioc_timer_fn() from iocost) access parent pd from
> child pd after pd_offline_fn(), then UAF can be triggered.
>
> Fix the problem by delaying 'list_del_init(&blkg->q_node)' from
> blkg_destroy() to blkg_free_workfn(), and using a new disk level mutex to
> synchronize blkg_free_workfn() and blkcg_deactivate_policy().
>
> Signed-off-by: Yu Kuai <yukuai3@xxxxxxxxxx>

Acked-by: Tejun Heo <tj@xxxxxxxxxx>

Thanks.

--
tejun