
From: Jingbo Xu <jefflexu@linux.alibaba.com> anolis inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IB5UKT Reference: https://gitee.com/anolis/cloud-kernel/commit/51839830d50d -------------------------------- ANBZ: #3213 Add missing lock protection in poll routine when iterating xarray, otherwise: 1. The radix_tree API itself doesn't imply RCU read lock, thus we may encounter UAF when dereferencing slot without radix_tree's lock held. 2. Even with RCU read lock held, only the slot of the radix tree is ensured to be pinned there, while the data structure (e.g. struct cachefiles_req) stored in the slot has no such guarantee. The poll routine will iterate the radix tree and dereference cachefiles_req accordingly. Thus RCU read lock is not adequate in this case and spinlock is needed here. 3. Otherwise, radix_tree_deref_slot_protected() will fail lockdep_is_held() checking. Fixes: f8ecbc39993a ("anolis: cachefiles: narrow the scope of triggering EPOLLIN events in ondemand mode") Signed-off-by: Jingbo Xu <jefflexu@linux.alibaba.com> Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com> Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com> Link: https://gitee.com/anolis/cloud-kernel/pulls/1004 Signed-off-by: Zizhi Wo <wozizhi@huawei.com> Signed-off-by: Baokun Li <libaokun1@huawei.com> --- fs/cachefiles/daemon.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/cachefiles/daemon.c b/fs/cachefiles/daemon.c index 4bb81e003ae1..e26ebbc89806 100644 --- a/fs/cachefiles/daemon.c +++ b/fs/cachefiles/daemon.c @@ -370,6 +370,7 @@ static __poll_t cachefiles_daemon_poll(struct file *file, if (cachefiles_in_ondemand_mode(cache)) { if (!radix_tree_empty(&cache->reqs)) { + xa_lock(&cache->reqs); radix_tree_for_each_tagged(slot, &cache->reqs, &iter, 0, CACHEFILES_REQ_NEW) { req = radix_tree_deref_slot_protected(slot, @@ -379,6 +380,7 @@ static __poll_t cachefiles_daemon_poll(struct file *file, break; } } + xa_unlock(&cache->reqs); } } else { if (test_bit(CACHEFILES_STATE_CHANGED, &cache->flags)) -- 2.46.1