Skip to content

Commit 14e3062

Browse files
KAGA-KOKOmartinkpetersen
authored andcommitted
scsi: core: Fix a scsi_show_rq() NULL pointer dereference
Avoid that scsi_show_rq() triggers a NULL pointer dereference if called after sd_uninit_command(). Swap the NULL pointer assignment and the mempool_free() call in sd_uninit_command() to make it less likely that scsi_show_rq() triggers a use-after-free. Note: even with these changes scsi_show_rq() can trigger a use-after-free but that's a lesser evil than e.g. suppressing debug information for T10 PI Type 2 commands completely. This patch fixes the following oops: BUG: unable to handle kernel NULL pointer dereference at (null) IP: scsi_format_opcode_name+0x1a/0x1c0 CPU: 1 PID: 1881 Comm: cat Not tainted 4.14.0-rc2.blk_mq_io_hang+ torvalds#516 Call Trace: __scsi_format_command+0x27/0xc0 scsi_show_rq+0x5c/0xc0 __blk_mq_debugfs_rq_show+0x116/0x130 blk_mq_debugfs_rq_show+0xe/0x10 seq_read+0xfe/0x3b0 full_proxy_read+0x54/0x90 __vfs_read+0x37/0x160 vfs_read+0x96/0x130 SyS_read+0x55/0xc0 entry_SYSCALL_64_fastpath+0x1a/0xa5 [mkp: added Type 2] Fixes: 0eebd00 ("scsi: Implement blk_mq_ops.show_rq()") Reported-by: Ming Lei <[email protected]> Signed-off-by: Bart Van Assche <[email protected]> Cc: James E.J. Bottomley <[email protected]> Cc: Martin K. Petersen <[email protected]> Cc: Ming Lei <[email protected]> Cc: Christoph Hellwig <[email protected]> Cc: Hannes Reinecke <[email protected]> Cc: Johannes Thumshirn <[email protected]> Cc: [email protected] Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 3e5c635 commit 14e3062

File tree

2 files changed

+7
-3
lines changed

2 files changed

+7
-3
lines changed

drivers/scsi/scsi_debugfs.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ void scsi_show_rq(struct seq_file *m, struct request *rq)
88
{
99
struct scsi_cmnd *cmd = container_of(scsi_req(rq), typeof(*cmd), req);
1010
int msecs = jiffies_to_msecs(jiffies - cmd->jiffies_at_alloc);
11-
char buf[80];
11+
const u8 *const cdb = READ_ONCE(cmd->cmnd);
12+
char buf[80] = "(?)";
1213

13-
__scsi_format_command(buf, sizeof(buf), cmd->cmnd, cmd->cmd_len);
14+
if (cdb)
15+
__scsi_format_command(buf, sizeof(buf), cdb, cmd->cmd_len);
1416
seq_printf(m, ", .cmd=%s, .retries=%d, allocated %d.%03d s ago", buf,
1517
cmd->retries, msecs / 1000, msecs % 1000);
1618
}

drivers/scsi/sd.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1312,6 +1312,7 @@ static int sd_init_command(struct scsi_cmnd *cmd)
13121312
static void sd_uninit_command(struct scsi_cmnd *SCpnt)
13131313
{
13141314
struct request *rq = SCpnt->request;
1315+
u8 *cmnd;
13151316

13161317
if (SCpnt->flags & SCMD_ZONE_WRITE_LOCK)
13171318
sd_zbc_write_unlock_zone(SCpnt);
@@ -1320,9 +1321,10 @@ static void sd_uninit_command(struct scsi_cmnd *SCpnt)
13201321
__free_page(rq->special_vec.bv_page);
13211322

13221323
if (SCpnt->cmnd != scsi_req(rq)->cmd) {
1323-
mempool_free(SCpnt->cmnd, sd_cdb_pool);
1324+
cmnd = SCpnt->cmnd;
13241325
SCpnt->cmnd = NULL;
13251326
SCpnt->cmd_len = 0;
1327+
mempool_free(cmnd, sd_cdb_pool);
13261328
}
13271329
}
13281330

0 commit comments

Comments
 (0)