mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-12 23:33:55 +08:00
erofs: fix use-after-free of on-stack io[]
The root cause is the race as follows: Thread #1 Thread #2(irq ctx) z_erofs_runqueue() struct z_erofs_decompressqueue io_A[]; submit bio A z_erofs_decompress_kickoff(,,1) z_erofs_decompressqueue_endio(bio A) z_erofs_decompress_kickoff(,,-1) spin_lock_irqsave() atomic_add_return() io_wait_event() -> pending_bios is already 0 [end of function] wake_up_locked(io_A[]) // crash Referenced backtrace in kernel 5.4: [ 10.129422] Unable to handle kernel paging request at virtual address eb0454a4 [ 10.364157] CPU: 0 PID: 709 Comm: getprop Tainted: G WC O 5.4.147-ab09225 #1 [ 11.556325] [<c01b33b8>] (__wake_up_common) from [<c01b3300>] (__wake_up_locked+0x40/0x48) [ 11.565487] [<c01b3300>] (__wake_up_locked) from [<c044c8d0>] (z_erofs_vle_unzip_kickoff+0x6c/0xc0) [ 11.575438] [<c044c8d0>] (z_erofs_vle_unzip_kickoff) from [<c044c854>] (z_erofs_vle_read_endio+0x16c/0x17c) [ 11.586082] [<c044c854>] (z_erofs_vle_read_endio) from [<c06a80e8>] (clone_endio+0xb4/0x1d0) [ 11.595428] [<c06a80e8>] (clone_endio) from [<c04a1280>] (blk_update_request+0x150/0x4dc) [ 11.604516] [<c04a1280>] (blk_update_request) from [<c06dea28>] (mmc_blk_cqe_complete_rq+0x144/0x15c) [ 11.614640] [<c06dea28>] (mmc_blk_cqe_complete_rq) from [<c04a5d90>] (blk_done_softirq+0xb0/0xcc) [ 11.624419] [<c04a5d90>] (blk_done_softirq) from [<c010242c>] (__do_softirq+0x184/0x56c) [ 11.633419] [<c010242c>] (__do_softirq) from [<c01051e8>] (irq_exit+0xd4/0x138) [ 11.641640] [<c01051e8>] (irq_exit) from [<c010c314>] (__handle_domain_irq+0x94/0xd0) [ 11.650381] [<c010c314>] (__handle_domain_irq) from [<c04fde70>] (gic_handle_irq+0x50/0xd4) [ 11.659641] [<c04fde70>] (gic_handle_irq) from [<c0101b70>] (__irq_svc+0x70/0xb0) Signed-off-by: Hongyu Jin <hongyu.jin@unisoc.com> Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com> Reviewed-by: Chao Yu <chao@kernel.org> Link: https://lore.kernel.org/r/20220401115527.4935-1-hongyu.jin.cn@gmail.com Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
This commit is contained in:
parent
3123109284
commit
60b3005011
@ -1066,12 +1066,9 @@ static void z_erofs_decompress_kickoff(struct z_erofs_decompressqueue *io,
|
||||
|
||||
/* wake up the caller thread for sync decompression */
|
||||
if (sync) {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&io->u.wait.lock, flags);
|
||||
if (!atomic_add_return(bios, &io->pending_bios))
|
||||
wake_up_locked(&io->u.wait);
|
||||
spin_unlock_irqrestore(&io->u.wait.lock, flags);
|
||||
complete(&io->u.done);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1217,7 +1214,7 @@ jobqueue_init(struct super_block *sb,
|
||||
} else {
|
||||
fg_out:
|
||||
q = fgq;
|
||||
init_waitqueue_head(&fgq->u.wait);
|
||||
init_completion(&fgq->u.done);
|
||||
atomic_set(&fgq->pending_bios, 0);
|
||||
}
|
||||
q->sb = sb;
|
||||
@ -1419,8 +1416,7 @@ static void z_erofs_runqueue(struct super_block *sb,
|
||||
return;
|
||||
|
||||
/* wait until all bios are completed */
|
||||
io_wait_event(io[JQ_SUBMIT].u.wait,
|
||||
!atomic_read(&io[JQ_SUBMIT].pending_bios));
|
||||
wait_for_completion_io(&io[JQ_SUBMIT].u.done);
|
||||
|
||||
/* handle synchronous decompress queue in the caller context */
|
||||
z_erofs_decompress_queue(&io[JQ_SUBMIT], pagepool);
|
||||
|
@ -97,7 +97,7 @@ struct z_erofs_decompressqueue {
|
||||
z_erofs_next_pcluster_t head;
|
||||
|
||||
union {
|
||||
wait_queue_head_t wait;
|
||||
struct completion done;
|
||||
struct work_struct work;
|
||||
} u;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user