zram: fix use-after-free in zram_writeback_endio#795
Conversation
|
Upstream branch: 6d35786 |
|
Upstream branch: 6d35786 |
f19d9fa to
75e4f5b
Compare
6f75bd1 to
1f0d33a
Compare
|
Upstream branch: 6d35786 |
75e4f5b to
552b1f8
Compare
|
Upstream branch: 6d35786 |
552b1f8 to
7ef25b0
Compare
|
Upstream branch: 6d35786 |
7ef25b0 to
92785ab
Compare
|
Upstream branch: 6d35786 |
92785ab to
739a0e7
Compare
1f0d33a to
b1870f6
Compare
|
Upstream branch: aa54b1d |
739a0e7 to
1622a88
Compare
|
Upstream branch: aa54b1d |
1622a88 to
36cc32f
Compare
|
Upstream branch: aa54b1d |
36cc32f to
b6e24f3
Compare
b1870f6 to
ca57796
Compare
|
Upstream branch: 70eda68 |
b6e24f3 to
651faf4
Compare
ca57796 to
c1feb59
Compare
|
Upstream branch: 8bc67e4 |
651faf4 to
3d43e2c
Compare
c1feb59 to
ea833a1
Compare
|
Upstream branch: 6779b50 |
3d43e2c to
2bf16c1
Compare
ea833a1 to
7af85d1
Compare
|
Upstream branch: 79bd2dd |
2bf16c1 to
597f8c7
Compare
7af85d1 to
de94ac7
Compare
|
Upstream branch: eed108e |
A crash was observed in zram_writeback_endio due to a NULL pointer
dereference in wake_up. The root cause is a race condition between the
bio completion handler (zram_writeback_endio) and the writeback task.
In zram_writeback_endio, wake_up() is called on &wb_ctl->done_wait after
releasing wb_ctl->done_lock. This creates a race window where the
writeback task can see num_inflight become 0, return, and free wb_ctl
before zram_writeback_endio calls wake_up().
CPU 0 (zram_writeback_endio) CPU 1 (writeback_store)
============================ ============================
zram_writeback_slots
zram_submit_wb_request
zram_submit_wb_request
wait_event(wb_ctl->done_wait)
spin_lock(&wb_ctl->done_lock);
list_add(&req->entry, &wb_ctl->done_reqs);
spin_unlock(&wb_ctl->done_lock);
wake_up(&wb_ctl->done_wait);
zram_complete_done_reqs
spin_lock(&wb_ctl->done_lock);
list_add(&req->entry, &wb_ctl->done_reqs);
spin_unlock(&wb_ctl->done_lock);
while (num_inflight) > 0)
spin_lock(&wb_ctl->done_lock);
list_del(&req->entry);
spin_unlock(&wb_ctl->done_lock);
// num_inflight becomes 0
atomic_dec(num_inflight);
// Leave zram_writeback_slots
// Free wb_ctl
release_wb_ctl(wb_ctl);
// UAF crash!
wake_up(&wb_ctl->done_wait);
This patch fixes this race by using RCU. By protecting wb_ctl with
rcu_read_lock() in zram_writeback_endio and using kfree_rcu() to free
it, we ensure that wb_ctl remains valid during the execution of
zram_writeback_endio.
Fixes: f405066 ("zram: introduce writeback bio batching")
Cc: stable@vger.kernel.org
Suggested-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Suggested-by: Minchan Kim <minchan@kernel.org>
Signed-off-by: Richard Chang <richardycc@google.com>
Signed-off-by: wang wei <a929244872@163.com>
597f8c7 to
3e7e043
Compare
Pull request for series with
subject: zram: fix use-after-free in zram_writeback_endio
version: 1
url: https://patchwork.kernel.org/project/linux-block/list/?series=1089254