mmc: block: Fix use after free issue with request pointer
Accessing the request pointer after submitting the request could
result in use after free as the request could be completed and
freed by the time its accessed. Fix the usage appropriately.
Kasan report:
[ 55.025818] ==================================================================
[ 55.032035] BUG: KASAN: use-after-free in mmc_blk_cmdq_issue_rq+0xd58/0xe20 at addr ffffffc04c5119ac
[ 55.041134] Read of size 4 by task mmc-cmdqd/0/343
[ 55.045905] =============================================================================
[ 55.054069] BUG blkdev_requests (Tainted: G W ): kasan: bad access detected
[ 55.061958] -----------------------------------------------------------------------------
[ 55.061958]
[ 55.071609] INFO: Allocated in mempool_alloc_slab+0x18/0x20 age=2 cpu=1 pid=1105
[ 55.078975] alloc_debug_processing+0x118/0x170
[ 55.083491] __slab_alloc.isra.20.constprop.22+0x2a4/0x3a0
[ 55.088954] kmem_cache_alloc+0xb0/0x228
[ 55.092865] mempool_alloc_slab+0x14/0x20
[ 55.096853] mempool_alloc+0xdc/0x1ec
[ 55.100507] get_request+0x3c4/0x838
[ 55.104060] blk_queue_bio+0x1f0/0x448
[ 55.107791] generic_make_request+0x13c/0x1bc
[ 55.112136] submit_bio+0x154/0x2b4
[ 55.115606] mpage_bio_submit+0x3c/0x50
[ 55.119423] mpage_readpages+0x140/0x17c
[ 55.123334] blkdev_readpages+0x1c/0x28
[ 55.127153] __do_page_cache_readahead+0x218/0x2ec
[ 55.131930] ondemand_readahead+0x2cc/0x2f0
[ 55.136091] page_cache_sync_readahead+0x7c/0x94
[ 55.140697] ext4_readdir+0xb34/0xb78
[ 55.144347] INFO: Freed in mempool_free_slab+0x18/0x20 age=12 cpu=0 pid=603
[ 55.151287] free_debug_processing+0x240/0x2f0
[ 55.155709] __slab_free+0x44/0x374
[ 55.159179] kmem_cache_free+0x1d8/0x264
[ 55.163092] mempool_free_slab+0x14/0x20
[ 55.166991] mempool_free+0xd0/0xec
[ 55.170468] __blk_put_request+0x168/0x1ac
[ 55.174546] blk_finish_request+0x110/0x124
[ 55.178713] blk_end_bidi_request+0x70/0xa0
[ 55.182880] blk_end_request+0xc/0x18
[ 55.186527] mmc_blk_cmdq_complete_rq+0x1fc/0x284
[ 55.191216] mmc_cmdq_softirq_done+0x38/0x48
[ 55.195467] blk_done_softirq+0x130/0x160
[ 55.199461] __do_softirq+0x280/0x528
[ 55.203105] irq_exit+0x9c/0x114
[ 55.206317] __handle_domain_irq+0xc4/0x110
[ 55.210486] gic_handle_irq+0x5c/0xd8
[ 55.214130] INFO: Slab 0xffffffba48c77b00 objects=25 used=1 fp=0xffffffc04c510798 flags=0x4080
[ 55.222723] INFO: Object 0xffffffc04c511950 @offset=6480 fp=0xffffffc0aed4e408
[ 55.222723]
[ 55.231407] Bytes b4 ffffffc04c511940: 00 00 00 00 00 00 00 00 a8 9f ff ff 00 00 00 00 ................
[ 55.240870] Object ffffffc04c511950: 08 e4 d4 ae c0 ff ff ff 08 e4 d4 ae c0 ff ff ff ................
[ 55.250161] Object ffffffc04c511960: 5d a0 ff ff 00 00 00 00 00 00 00 00 00 00 00 00 ]...............
[ 55.259442] Object ffffffc04c511970: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
[ 55.268730] Object ffffffc04c511980: 00 39 6a 56 c0 ff ff ff 00 00 00 00 00 00 00 00 .9jV............
[ 55.278017] Object ffffffc04c511990: 00 00 41 24 01 00 00 00 01 00 00 00 00 00 00 00 ..A$............
[ 55.287306] Object ffffffc04c5119a0: 00 00 00 00 00 00 00 00 01 00 00 00 00 10 00 00 ................
[ 55.296595] Object ffffffc04c5119b0: 88 64 32 00 00 00 00 00 00 ea c2 b5 c0 ff ff ff .d2.............
[ 55.305882] Object ffffffc04c5119c0: 00 ea c2 b5 c0 ff ff ff 00 00 00 00 00 00 00 00 ................
[ 55.315172] Object ffffffc04c5119d0: d8 75 c2 55 c0 ff ff ff 01 00 00 00 00 00 00 00 .u.U............
[ 55.324459] Object ffffffc04c5119e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
[ 55.333747] Object ffffffc04c5119f0: 00 8d fb 54 c0 ff ff ff 98 e3 d4 ae c0 ff ff ff ...T............
[ 55.343035] Object ffffffc04c511a00: 00 80 f7 b6 c0 ff ff ff 00 00 00 00 00 00 00 00 ................
[ 55.352323] Object ffffffc04c511a10: 40 53 e3 b6 c0 ff ff ff 80 0a 56 55 c0 ff ff ff @S........VU....
[ 55.361613] Object ffffffc04c511a20: 51 a0 ff ff 00 00 00 00 01 00 00 00 00 00 00 00 Q...............
[ 55.370901] Object ffffffc04c511a30: 00 00 00 00 00 00 00 00 ff ff ff ff 00 00 00 00 ................
[ 55.380187] Object ffffffc04c511a40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
[ 55.389475] Object ffffffc04c511a50: 40 1a 51 4c c0 ff ff ff 10 00 00 00 00 00 00 00 @.QL............
[ 55.398764] Object ffffffc04c511a60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
[ 55.408053] Object ffffffc04c511a70: 00 00 00 00 00 00 00 00 78 1a 51 4c c0 ff ff ff ........x.QL....
[ 55.417342] Object ffffffc04c511a80: 78 1a 51 4c c0 ff ff ff 00 00 00 00 00 00 00 00 x.QL............
[ 55.426628] Object ffffffc04c511a90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
[ 55.435917] Object ffffffc04c511aa0: 00 00 00 00 00 00 00 00 ........
[ 55.444534] Call trace:
[ 55.447073] Memory state around the buggy address:
[ 55.451719] ffffffc04c511880: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 55.458920] ffffffc04c511900: fc fc fc fc fc fc fc fc fc fc 00 00 00 00 00 00
[ 55.466126] >ffffffc04c511980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 55.473328] ^
[ 55.477844] ffffffc04c511a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 55.485050] ffffffc04c511a80: 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc fc
Change-Id: I24fdca1b4562fd7c1f3a1584d1efccd94ed6698a
Signed-off-by: Venkat Gopalakrishnan <venkatg@codeaurora.org>
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index ba3daed..3084b9c 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -3189,6 +3189,7 @@
struct mmc_host *host = card->host;
struct mmc_cmdq_context_info *ctx = &host->cmdq_ctx;
struct mmc_cmdq_req *mc_rq;
+ u8 active_small_sector_read = 0;
int ret = 0;
mmc_deferred_scaling(host);
@@ -3203,15 +3204,16 @@
mc_rq = mmc_blk_cmdq_rw_prep(active_mqrq, mq);
- ret = mmc_blk_cmdq_start_req(card->host, mc_rq);
-
- if (!ret && (card->quirks & MMC_QUIRK_CMDQ_EMPTY_BEFORE_DCMD)) {
+ if (card->quirks & MMC_QUIRK_CMDQ_EMPTY_BEFORE_DCMD) {
unsigned int sectors = blk_rq_sectors(req);
if (((sectors > 0) && (sectors < 8))
&& (rq_data_dir(req) == READ))
- host->cmdq_ctx.active_small_sector_read_reqs++;
+ active_small_sector_read = 1;
}
+ ret = mmc_blk_cmdq_start_req(card->host, mc_rq);
+ if (!ret && active_small_sector_read)
+ host->cmdq_ctx.active_small_sector_read_reqs++;
/*
* When in SVS2 on low load scenario and there are lots of requests
* queued for CMDQ we need to wait till the queue is empty to scale