From acacb09327d6b3224cc3e4be6f58685cb5e56253 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 13 Apr 2015 09:29:27 +0200 Subject: [PATCH] scst_targ: Avoid incorrect block size changes The scst_block_generic_dev_done() function parses the READ CAPACITY response without checking whether the response buffer contains valid data. This can lead to incorrect block size changes and also to the following kernel warning: WARNING: at scst/src/scst_lib.c:7353 scst_calc_block_shift+0x7f/0xb0 [scst]() 1 << 23 != 12595456 [] dump_stack+0x19/0x1b [] warn_slowpath_common+0x7d/0xc0 [] warn_slowpath_fmt+0x46/0x50 [] scst_calc_block_shift+0x7f/0xb0 [scst] [] scst_block_generic_dev_done.part.39+0x6a/0x7d [scst] [] scst_block_generic_dev_done+0x34/0x40 [scst] [] dev_user_disk_done+0x15/0x20 [scst_user] [] scst_dev_done+0x49/0x150 [scst] [] scst_process_active_cmd+0x240/0x390 [scst] [] scst_process_redirect_cmd+0x121/0x1e0 [scst] [] scst_cmd_done_local+0x76/0x120 [scst] [] dev_user_process_reply_exec+0x8a/0x370 [scst_user] [] dev_user_process_reply+0x242/0x2e0 [scst_user] [] dev_user_reply_get_cmd.isra.17+0x100/0x2d0 [scst_user] [] dev_user_ioctl+0x157/0x428 [scst_user] [] do_vfs_ioctl+0x7a/0x2e0 [] SyS_ioctl+0x91/0xb0 [] system_call_fastpath+0x16/0x1b Avoid this by calling dev_done() handlers only for completed commands and not for aborted commands. Reported-by: Gal Rosen Reported-by: Abacus Liang Reported-by: Shahar Salzman Signed-off-by: Bart Van Assche --- scst/src/scst_lib.c | 6 ++++++ scst/src/scst_targ.c | 5 +++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index 9b99c3e73..0d3e2881d 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -8264,6 +8264,9 @@ int scst_block_generic_dev_done(struct scst_cmd *cmd, TRACE_ENTRY(); + /* Do not call this function for aborted commands. */ + WARN_ON_ONCE(!cmd->completed); + if (unlikely(opcode == READ_CAPACITY)) { if ((status == SAM_STAT_GOOD) || (status == SAM_STAT_CONDITION_MET)) { /* Always keep track of disk capacity */ @@ -8314,6 +8317,9 @@ int scst_tape_generic_dev_done(struct scst_cmd *cmd, TRACE_ENTRY(); + /* Do not call this function for aborted commands. */ + WARN_ON_ONCE(!cmd->completed); + if (unlikely(cmd->status != SAM_STAT_GOOD)) goto out; diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index 79247a4e5..5a1e258a1 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -3762,8 +3762,9 @@ static int scst_dev_done(struct scst_cmd *cmd) state = SCST_CMD_STATE_PRE_XMIT_RESP1; - if (likely((cmd->op_flags & SCST_FULLY_LOCAL_CMD) == 0) && - likely(devt->dev_done != NULL)) { + if (likely(cmd->completed && + !(cmd->op_flags & SCST_FULLY_LOCAL_CMD) && + devt->dev_done)) { int rc; if (unlikely(!devt->dev_done_atomic &&