Messages in this thread | ![/](/images/icornerl.gif) | | Date | Thu, 25 Apr 2024 14:53:02 +0800 | Subject | Re: [PATCH 3/5] cachefiles: flush ondemand_object_worker during clean object | From | Baokun Li <> |
| |
Hi Jia,
On 2024/4/25 13:41, Jia Zhu wrote: > Thanks for catching this. How about adding a Fixes tag. > > Reviewed-by: Jia Zhu <zhujia.zj@bytedance.com> > > Ok, I will add the Fixes tag in the next iteration. Thank you very much for your review!
Cheers! Baokun > 在 2024/4/24 11:34, libaokun@huaweicloud.com 写道: >> From: Hou Tao <houtao1@huawei.com> >> >> When queuing ondemand_object_worker() to re-open the object, >> cachefiles_object is not pinned. The cachefiles_object may be freed when >> the pending read request is completed intentionally and the related >> erofs is umounted. If ondemand_object_worker() runs after the object is >> freed, it will incur use-after-free problem as shown below. >> >> process A processs B process C process D >> >> cachefiles_ondemand_send_req() >> // send a read req X >> // wait for its completion >> >> // close ondemand fd >> cachefiles_ondemand_fd_release() >> // set object as CLOSE >> >> cachefiles_ondemand_daemon_read() >> // set object as REOPENING >> queue_work(fscache_wq, &info->ondemand_work) >> >> // close /dev/cachefiles >> cachefiles_daemon_release >> cachefiles_flush_reqs >> complete(&req->done) >> >> // read req X is completed >> // umount the erofs fs >> cachefiles_put_object() >> // object will be freed >> cachefiles_ondemand_deinit_obj_info() >> kmem_cache_free(object) >> // both info and object are freed >> ondemand_object_worker() >> >> When dropping an object, it is no longer necessary to reopen the object, >> so use cancel_work_sync() to cancel or wait for ondemand_object_worker() >> to complete. >> >> Signed-off-by: Hou Tao <houtao1@huawei.com> >> Signed-off-by: Baokun Li <libaokun1@huawei.com> >> --- >> fs/cachefiles/ondemand.c | 3 +++ >> 1 file changed, 3 insertions(+) >> >> diff --git a/fs/cachefiles/ondemand.c b/fs/cachefiles/ondemand.c >> index d24bff43499b..f6440b3e7368 100644 >> --- a/fs/cachefiles/ondemand.c >> +++ b/fs/cachefiles/ondemand.c >> @@ -589,6 +589,9 @@ void cachefiles_ondemand_clean_object(struct >> cachefiles_object *object) >> } >> } >> xa_unlock(&cache->reqs); >> + >> + /* Wait for ondemand_object_worker() to finish to avoid UAF. */ >> + cancel_work_sync(&object->ondemand->ondemand_work); >> } >> int cachefiles_ondemand_init_obj_info(struct cachefiles_object >> *object,
| ![\](/images/icornerr.gif) |