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))