mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-17 10:41:26 +00:00
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 has been initialized. 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 [<ffffffff816071e3>] dump_stack+0x19/0x1b [<ffffffff8106e23d>] warn_slowpath_common+0x7d/0xc0 [<ffffffff8106e336>] warn_slowpath_fmt+0x46/0x50 [<ffffffffa0712e2f>] scst_calc_block_shift+0x7f/0xb0 [scst] [<ffffffffa072dbd7>] scst_block_generic_dev_done.part.39+0x6a/0x7d [scst] [<ffffffffa07162a4>] scst_block_generic_dev_done+0x34/0x40 [scst] [<ffffffffa0066205>] dev_user_disk_done+0x15/0x20 [scst_user] [<ffffffffa070c119>] scst_dev_done+0x49/0x150 [scst] [<ffffffffa070e1a0>] scst_process_active_cmd+0x240/0x390 [scst] [<ffffffffa070e7e1>] scst_process_redirect_cmd+0x121/0x1e0 [scst] [<ffffffffa070e916>] scst_cmd_done_local+0x76/0x120 [scst] [<ffffffffa006843a>] dev_user_process_reply_exec+0x8a/0x370 [scst_user] [<ffffffffa00699e2>] dev_user_process_reply+0x242/0x2e0 [scst_user] [<ffffffffa0069b80>] dev_user_reply_get_cmd.isra.17+0x100/0x2d0 [scst_user] [<ffffffffa0069ea7>] dev_user_ioctl+0x157/0x428 [scst_user] [<ffffffff811d999a>] do_vfs_ioctl+0x7a/0x2e0 [<ffffffff811d9c91>] SyS_ioctl+0x91/0xb0 [<ffffffff8161b269>] system_call_fastpath+0x16/0x1b Avoid this by additionally checking cmd->completed Reported-by: Gal Rosen <galr@storone.com> Reported-by: Abacus Liang <abacusl@hotmail.com> Reported-by: Shahar Salzman <shahar.salzman@kaminario.com> git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6196 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -3958,6 +3958,12 @@ static inline bool scst_cmd_atomic(struct scst_cmd *cmd)
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Returns TRUE if cmd completed with SAM_STAT_GOOD */
|
||||
static inline bool scst_cmd_completed_good(struct scst_cmd *cmd)
|
||||
{
|
||||
return cmd->completed && (cmd->status == SAM_STAT_GOOD);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns TRUE if cmd has been preliminary completed, i.e. completed or
|
||||
* aborted.
|
||||
|
||||
@@ -10933,7 +10933,6 @@ int scst_block_generic_dev_done(struct scst_cmd *cmd,
|
||||
void (*set_block_shift)(struct scst_cmd *cmd, int block_shift))
|
||||
{
|
||||
int opcode = cmd->cdb[0];
|
||||
int status = cmd->status;
|
||||
int res = SCST_CMD_STATE_DEFAULT;
|
||||
|
||||
TRACE_ENTRY();
|
||||
@@ -10945,7 +10944,7 @@ int scst_block_generic_dev_done(struct scst_cmd *cmd,
|
||||
*/
|
||||
|
||||
if (unlikely(opcode == READ_CAPACITY)) {
|
||||
if ((status == SAM_STAT_GOOD) || (status == SAM_STAT_CONDITION_MET)) {
|
||||
if (scst_cmd_completed_good(cmd)) {
|
||||
/* Always keep track of disk capacity */
|
||||
int buffer_size, sector_size, sh;
|
||||
uint8_t *buffer;
|
||||
@@ -11003,7 +11002,7 @@ int scst_tape_generic_dev_done(struct scst_cmd *cmd,
|
||||
* therefore change them only if necessary
|
||||
*/
|
||||
|
||||
if (unlikely(cmd->status != SAM_STAT_GOOD))
|
||||
if (unlikely(!scst_cmd_completed_good(cmd)))
|
||||
goto out;
|
||||
|
||||
switch (opcode) {
|
||||
|
||||
@@ -3590,7 +3590,7 @@ next:
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (likely(cmd->status == SAM_STAT_GOOD)) {
|
||||
if (likely(scst_cmd_completed_good(cmd))) {
|
||||
if (cmd->deferred_dif_read_check) {
|
||||
int rc = scst_dif_process_read(cmd);
|
||||
if (unlikely(rc != 0)) {
|
||||
|
||||
Reference in New Issue
Block a user