From be9d368361c6f302acde580e9914f14265bed2db Mon Sep 17 00:00:00 2001 From: Gleb Chesnokov Date: Thu, 28 Dec 2023 11:35:06 +0300 Subject: [PATCH] scst_targ: Fix shift out of bounds This patch should fix the following UBSAN warning: UBSAN: shift-out-of-bounds in scst/src/scst_targ.c:3912:6 shift exponent -1 is negative Call Trace: show_stack+0x52/0x5c dump_stack_lvl+0x4a/0x63 dump_stack+0x10/0x16 ubsan_epilogue+0x9/0x36 __ubsan_handle_shift_out_of_bounds.cold+0x61/0xef scst_process_active_cmd.cold+0xf/0x2d [scst] scst_process_redirect_cmd+0xd4/0x2e0 [scst] scst_tgt_cmd_done+0x48/0x70 [scst] scst_local_targ_xmit_response+0x64/0x220 [scst_local] scst_process_active_cmd+0x891/0x2140 [scst] scst_process_redirect_cmd+0xd4/0x2e0 [scst] scst_cmd_done_local+0x80/0x110 [scst] dev_user_process_reply+0x597/0x1160 [scst_user] dev_user_ioctl+0x145/0xb23 [scst_user] __x64_sys_ioctl+0x95/0xd0 do_syscall_64+0x5c/0xc0 entry_SYSCALL_64_after_hwframe+0x62/0xcc Reported-by: Rob Turk --- scst/src/scst_targ.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index 4b4eac7dd..a325e7bbd 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -3852,8 +3852,6 @@ static int scst_finish_cmd(struct scst_cmd *cmd) int res; struct scst_session *sess = cmd->sess; struct scst_io_stat_entry *stat; - int block_shift, align_len; - uint64_t lba; TRACE_ENTRY(); @@ -3898,20 +3896,15 @@ static int scst_finish_cmd(struct scst_cmd *cmd) stat = &sess->io_stats[cmd->data_direction]; stat->cmd_count++; stat->io_byte_count += cmd->bufflen + cmd->out_bufflen; - if (likely(cmd->dev != NULL)) { - block_shift = cmd->dev->block_shift; - /* Let's track only 4K unaligned cmds at the moment */ - align_len = (block_shift != 0) ? 4095 : 0; - lba = cmd->lba; - } else { - block_shift = 0; - align_len = 0; - lba = 0; - } - if (unlikely(((lba << block_shift) & align_len) != 0) || - unlikely(((cmd->bufflen + cmd->out_bufflen) & align_len) != 0)) - stat->unaligned_cmd_count++; + if (likely(cmd->dev && cmd->dev->block_shift > 0)) { + /* Let's track only 4K unaligned cmds at the moment */ + int align_len = 4095; + + if (unlikely(((cmd->lba << cmd->dev->block_shift) & align_len) != 0) || + unlikely(((cmd->bufflen + cmd->out_bufflen) & align_len) != 0)) + stat->unaligned_cmd_count++; + } list_del(&cmd->sess_cmd_list_entry);