Skip to content

Commit 9b81c84

Browse files
sashalevinaxboe
authored andcommitted
block: don't access bio->bi_error after bio_put()
Commit 4246a0b ("block: add a bi_error field to struct bio") has added a few dereferences of 'bio' after a call to bio_put(). This causes use-after-frees such as: [521120.719695] BUG: KASan: use after free in dio_bio_complete+0x2b3/0x320 at addr ffff880f36b38714 [521120.720638] Read of size 4 by task mount.ocfs2/9644 [521120.721212] ============================================================================= [521120.722056] BUG kmalloc-256 (Not tainted): kasan: bad access detected [521120.722968] ----------------------------------------------------------------------------- [521120.722968] [521120.723915] Disabling lock debugging due to kernel taint [521120.724539] INFO: Slab 0xffffea003cdace00 objects=32 used=25 fp=0xffff880f36b38600 flags=0x46fffff80004080 [521120.726037] INFO: Object 0xffff880f36b38700 @offset=1792 fp=0xffff880f36b38800 [521120.726037] [521120.726974] Bytes b4 ffff880f36b386f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [521120.727898] Object ffff880f36b38700: 00 88 b3 36 0f 88 ff ff 00 00 d8 de 0b 88 ff ff ...6............ [521120.728822] Object ffff880f36b38710: 02 00 00 f0 00 00 00 00 00 00 00 00 00 00 00 00 ................ [521120.729705] Object ffff880f36b38720: 01 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 ................ [521120.730623] Object ffff880f36b38730: 00 00 00 00 00 00 00 00 01 00 00 00 00 02 00 00 ................ [521120.731621] Object ffff880f36b38740: 00 02 00 00 01 00 00 00 d0 f7 87 ad ff ff ff ff ................ [521120.732776] Object ffff880f36b38750: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [521120.733640] Object ffff880f36b38760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [521120.734508] Object ffff880f36b38770: 01 00 03 00 01 00 00 00 88 87 b3 36 0f 88 ff ff ...........6.... [521120.735385] Object ffff880f36b38780: 00 73 22 ad 02 88 ff ff 40 13 e0 3c 00 ea ff ff .s".....@..<.... [521120.736667] Object ffff880f36b38790: 00 02 00 00 00 04 00 00 00 00 00 00 00 00 00 00 ................ [521120.737596] Object ffff880f36b387a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [521120.738524] Object ffff880f36b387b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [521120.739388] Object ffff880f36b387c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [521120.740277] Object ffff880f36b387d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [521120.741187] Object ffff880f36b387e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [521120.742233] Object ffff880f36b387f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [521120.743229] CPU: 41 PID: 9644 Comm: mount.ocfs2 Tainted: G B 4.2.0-rc6-next-20150810-sasha-00039-gf909086 #2420 [521120.744274] ffff880f36b38000 ffff880d89c8f638 ffffffffb6e9ba8a ffff880101c0e5c0 [521120.745025] ffff880d89c8f668 ffffffffad76a313 ffff880101c0e5c0 ffffea003cdace00 [521120.745908] ffff880f36b38700 ffff880f36b38798 ffff880d89c8f690 ffffffffad772854 [521120.747063] Call Trace: [521120.747520] dump_stack (lib/dump_stack.c:52) [521120.748053] print_trailer (mm/slub.c:653) [521120.748582] object_err (mm/slub.c:660) [521120.749079] kasan_report_error (include/linux/kasan.h:20 mm/kasan/report.c:152 mm/kasan/report.c:194) [521120.750834] __asan_report_load4_noabort (mm/kasan/report.c:250) [521120.753580] dio_bio_complete (fs/direct-io.c:478) [521120.755752] do_blockdev_direct_IO (fs/direct-io.c:494 fs/direct-io.c:1291) [521120.759765] __blockdev_direct_IO (fs/direct-io.c:1322) [521120.761658] blkdev_direct_IO (fs/block_dev.c:162) [521120.762993] generic_file_read_iter (mm/filemap.c:1738) [521120.767405] blkdev_read_iter (fs/block_dev.c:1649) [521120.768556] __vfs_read (fs/read_write.c:423 fs/read_write.c:434) [521120.772126] vfs_read (fs/read_write.c:454) [521120.773118] SyS_pread64 (fs/read_write.c:607 fs/read_write.c:594) [521120.776062] entry_SYSCALL_64_fastpath (arch/x86/entry/entry_64.S:186) [521120.777375] Memory state around the buggy address: [521120.778118] ffff880f36b38600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [521120.779211] ffff880f36b38680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [521120.780315] >ffff880f36b38700: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [521120.781465] ^ [521120.782083] ffff880f36b38780: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [521120.783717] ffff880f36b38800: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [521120.784818] ================================================================== This patch fixes a few of those places that I caught while auditing the patch, but the original patch should be audited further for more occurences of this issue since I'm not too familiar with the code. Signed-off-by: Sasha Levin <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 2c68f6d commit 9b81c84

File tree

4 files changed

+14
-6
lines changed

4 files changed

+14
-6
lines changed

drivers/md/dm-crypt.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,22 +1102,24 @@ static void crypt_endio(struct bio *clone)
11021102
struct dm_crypt_io *io = clone->bi_private;
11031103
struct crypt_config *cc = io->cc;
11041104
unsigned rw = bio_data_dir(clone);
1105+
int error;
11051106

11061107
/*
11071108
* free the processed pages
11081109
*/
11091110
if (rw == WRITE)
11101111
crypt_free_buffer_pages(cc, clone);
11111112

1113+
error = clone->bi_error;
11121114
bio_put(clone);
11131115

1114-
if (rw == READ && !clone->bi_error) {
1116+
if (rw == READ && !error) {
11151117
kcryptd_queue_crypt(io);
11161118
return;
11171119
}
11181120

1119-
if (unlikely(clone->bi_error))
1120-
io->error = clone->bi_error;
1121+
if (unlikely(error))
1122+
io->error = error;
11211123

11221124
crypt_dec_pending(io);
11231125
}

drivers/md/dm-io.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ static void endio(struct bio *bio)
138138
{
139139
struct io *io;
140140
unsigned region;
141+
int error;
141142

142143
if (bio->bi_error && bio_data_dir(bio) == READ)
143144
zero_fill_bio(bio);
@@ -147,9 +148,10 @@ static void endio(struct bio *bio)
147148
*/
148149
retrieve_io_and_region_from_bio(bio, &io, &region);
149150

151+
error = bio->bi_error;
150152
bio_put(bio);
151153

152-
dec_count(io, region, bio->bi_error);
154+
dec_count(io, region, error);
153155
}
154156

155157
/*-----------------------------------------------------------------

drivers/md/raid5.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4756,6 +4756,7 @@ static void raid5_align_endio(struct bio *bi)
47564756
struct mddev *mddev;
47574757
struct r5conf *conf;
47584758
struct md_rdev *rdev;
4759+
int error = bi->bi_error;
47594760

47604761
bio_put(bi);
47614762

@@ -4766,7 +4767,7 @@ static void raid5_align_endio(struct bio *bi)
47664767

47674768
rdev_dec_pending(rdev, conf->mddev);
47684769

4769-
if (!bi->bi_error) {
4770+
if (!error) {
47704771
trace_block_bio_complete(bdev_get_queue(raid_bi->bi_bdev),
47714772
raid_bi, 0);
47724773
bio_endio(raid_bi);

fs/direct-io.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,12 +459,14 @@ static int dio_bio_complete(struct dio *dio, struct bio *bio)
459459
{
460460
struct bio_vec *bvec;
461461
unsigned i;
462+
int err;
462463

463464
if (bio->bi_error)
464465
dio->io_error = -EIO;
465466

466467
if (dio->is_async && dio->rw == READ) {
467468
bio_check_pages_dirty(bio); /* transfers ownership */
469+
err = bio->bi_error;
468470
} else {
469471
bio_for_each_segment_all(bvec, bio, i) {
470472
struct page *page = bvec->bv_page;
@@ -473,9 +475,10 @@ static int dio_bio_complete(struct dio *dio, struct bio *bio)
473475
set_page_dirty_lock(page);
474476
page_cache_release(page);
475477
}
478+
err = bio->bi_error;
476479
bio_put(bio);
477480
}
478-
return bio->bi_error;
481+
return err;
479482
}
480483

481484
/*

0 commit comments

Comments
 (0)