Skip to content

Commit 39c4330

Browse files
KAGA-KOKOgregkh
authored andcommitted
scsi: core: Fix a scsi_show_rq() NULL pointer dereference
commit 14e3062 upstream. 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]> Signed-off-by: Martin K. Petersen <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 9854611 commit 39c4330

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
@@ -1284,6 +1284,7 @@ static int sd_init_command(struct scsi_cmnd *cmd)
12841284
static void sd_uninit_command(struct scsi_cmnd *SCpnt)
12851285
{
12861286
struct request *rq = SCpnt->request;
1287+
u8 *cmnd;
12871288

12881289
if (SCpnt->flags & SCMD_ZONE_WRITE_LOCK)
12891290
sd_zbc_write_unlock_zone(SCpnt);
@@ -1292,9 +1293,10 @@ static void sd_uninit_command(struct scsi_cmnd *SCpnt)
12921293
__free_page(rq->special_vec.bv_page);
12931294

12941295
if (SCpnt->cmnd != scsi_req(rq)->cmd) {
1295-
mempool_free(SCpnt->cmnd, sd_cdb_pool);
1296+
cmnd = SCpnt->cmnd;
12961297
SCpnt->cmnd = NULL;
12971298
SCpnt->cmd_len = 0;
1299+
mempool_free(cmnd, sd_cdb_pool);
12981300
}
12991301
}
13001302

0 commit comments

Comments
 (0)