Skip to content

Commit 60b3005

Browse files
Hongyu Jinhsiangkao
authored andcommitted
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>
1 parent 3123109 commit 60b3005

File tree

2 files changed

+5
-9
lines changed

2 files changed

+5
-9
lines changed

fs/erofs/zdata.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,12 +1066,9 @@ static void z_erofs_decompress_kickoff(struct z_erofs_decompressqueue *io,
10661066

10671067
/* wake up the caller thread for sync decompression */
10681068
if (sync) {
1069-
unsigned long flags;
1070-
1071-
spin_lock_irqsave(&io->u.wait.lock, flags);
10721069
if (!atomic_add_return(bios, &io->pending_bios))
1073-
wake_up_locked(&io->u.wait);
1074-
spin_unlock_irqrestore(&io->u.wait.lock, flags);
1070+
complete(&io->u.done);
1071+
10751072
return;
10761073
}
10771074

@@ -1217,7 +1214,7 @@ jobqueue_init(struct super_block *sb,
12171214
} else {
12181215
fg_out:
12191216
q = fgq;
1220-
init_waitqueue_head(&fgq->u.wait);
1217+
init_completion(&fgq->u.done);
12211218
atomic_set(&fgq->pending_bios, 0);
12221219
}
12231220
q->sb = sb;
@@ -1419,8 +1416,7 @@ static void z_erofs_runqueue(struct super_block *sb,
14191416
return;
14201417

14211418
/* wait until all bios are completed */
1422-
io_wait_event(io[JQ_SUBMIT].u.wait,
1423-
!atomic_read(&io[JQ_SUBMIT].pending_bios));
1419+
wait_for_completion_io(&io[JQ_SUBMIT].u.done);
14241420

14251421
/* handle synchronous decompress queue in the caller context */
14261422
z_erofs_decompress_queue(&io[JQ_SUBMIT], pagepool);

fs/erofs/zdata.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ struct z_erofs_decompressqueue {
9797
z_erofs_next_pcluster_t head;
9898

9999
union {
100-
wait_queue_head_t wait;
100+
struct completion done;
101101
struct work_struct work;
102102
} u;
103103
};

0 commit comments

Comments
 (0)