mirror of
https://github.com/SCST-project/scst.git
synced 2026-07-19 22:42:38 +00:00
Fix cdb_len handling to avoid crashes on attempts to copy negative cdb_len bytes + minor scst_user residual fix
git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1788 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -368,7 +368,7 @@ struct scst_user_scsi_cmd_parse
|
||||
uint64_t sess_h;
|
||||
|
||||
uint8_t cdb[SCST_MAX_CDB_SIZE];
|
||||
int16_t cdb_len;
|
||||
uint16_t cdb_len;
|
||||
uint16_t ext_cdb_len;
|
||||
|
||||
uint32_t timeout;
|
||||
@@ -483,7 +483,7 @@ struct scst_user_scsi_cmd_alloc_mem
|
||||
uint64_t sess_h;
|
||||
|
||||
uint8_t cdb[SCST_MAX_CDB_SIZE];
|
||||
int16_t cdb_len;
|
||||
uint16_t cdb_len;
|
||||
uint16_t ext_cdb_len;
|
||||
|
||||
int32_t alloc_len;
|
||||
@@ -586,7 +586,7 @@ struct scst_user_scsi_cmd_exec
|
||||
uint64_t sess_h;
|
||||
|
||||
uint8_t cdb[SCST_MAX_CDB_SIZE];
|
||||
int16_t cdb_len;
|
||||
uint16_t cdb_len;
|
||||
uint16_t ext_cdb_len;
|
||||
|
||||
int32_t data_len;
|
||||
@@ -843,7 +843,7 @@ struct scst_user_scsi_cmd_reply_parse
|
||||
{
|
||||
uint8_t queue_type;
|
||||
uint8_t data_direction;
|
||||
int16_t cdb_len;
|
||||
uint16_t cdb_len;
|
||||
uint32_t op_flags;
|
||||
int32_t data_len;
|
||||
int32_t bufflen;
|
||||
|
||||
+4
-4
@@ -1733,7 +1733,7 @@ struct scst_cmd {
|
||||
|
||||
/* CDB and its len */
|
||||
uint8_t cdb[SCST_MAX_CDB_SIZE];
|
||||
short cdb_len; /* it might be -1 */
|
||||
unsigned short cdb_len;
|
||||
unsigned short ext_cdb_len;
|
||||
uint8_t *ext_cdb;
|
||||
|
||||
@@ -2469,7 +2469,7 @@ bool scst_initiator_has_luns(struct scst_tgt *tgt, const char *initiator_name);
|
||||
|
||||
struct scst_cmd *scst_rx_cmd(struct scst_session *sess,
|
||||
const uint8_t *lun, int lun_len, const uint8_t *cdb,
|
||||
int cdb_len, int atomic);
|
||||
unsigned int cdb_len, int atomic);
|
||||
void scst_cmd_init_done(struct scst_cmd *cmd,
|
||||
enum scst_exec_context pref_context);
|
||||
|
||||
@@ -2700,7 +2700,7 @@ static inline const uint8_t *scst_cmd_get_cdb(struct scst_cmd *cmd)
|
||||
}
|
||||
|
||||
/* Returns cmd's CDB length */
|
||||
static inline int scst_cmd_get_cdb_len(struct scst_cmd *cmd)
|
||||
static inline unsigned int scst_cmd_get_cdb_len(struct scst_cmd *cmd)
|
||||
{
|
||||
return cmd->cdb_len;
|
||||
}
|
||||
@@ -2712,7 +2712,7 @@ static inline const uint8_t *scst_cmd_get_ext_cdb(struct scst_cmd *cmd)
|
||||
}
|
||||
|
||||
/* Returns cmd's extended CDB length */
|
||||
static inline int scst_cmd_get_ext_cdb_len(struct scst_cmd *cmd)
|
||||
static inline unsigned int scst_cmd_get_ext_cdb_len(struct scst_cmd *cmd)
|
||||
{
|
||||
return cmd->ext_cdb_len;
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ struct scst_user_scsi_cmd_parse {
|
||||
aligned_u64 sess_h;
|
||||
|
||||
uint8_t cdb[SCST_MAX_CDB_SIZE];
|
||||
int16_t cdb_len;
|
||||
uint16_t cdb_len;
|
||||
uint16_t ext_cdb_len;
|
||||
|
||||
int32_t timeout;
|
||||
@@ -138,7 +138,7 @@ struct scst_user_scsi_cmd_alloc_mem {
|
||||
aligned_u64 sess_h;
|
||||
|
||||
uint8_t cdb[SCST_MAX_CDB_SIZE];
|
||||
int16_t cdb_len;
|
||||
uint16_t cdb_len;
|
||||
uint16_t ext_cdb_len;
|
||||
|
||||
int32_t alloc_len;
|
||||
@@ -153,7 +153,7 @@ struct scst_user_scsi_cmd_exec {
|
||||
aligned_u64 sess_h;
|
||||
|
||||
uint8_t cdb[SCST_MAX_CDB_SIZE];
|
||||
int16_t cdb_len;
|
||||
uint16_t cdb_len;
|
||||
uint16_t ext_cdb_len;
|
||||
|
||||
int32_t data_len;
|
||||
@@ -218,7 +218,7 @@ struct scst_user_scsi_cmd_reply_parse {
|
||||
struct {
|
||||
uint8_t queue_type;
|
||||
uint8_t data_direction;
|
||||
int16_t cdb_len;
|
||||
uint16_t cdb_len;
|
||||
uint32_t op_flags;
|
||||
int32_t data_len;
|
||||
int32_t bufflen;
|
||||
|
||||
@@ -833,7 +833,6 @@ static int dev_user_parse(struct scst_cmd *cmd)
|
||||
ucmd->user_cmd.parse_cmd.expected_out_transfer_len =
|
||||
cmd->expected_out_transfer_len;
|
||||
ucmd->user_cmd.parse_cmd.sn = cmd->tgt_sn;
|
||||
ucmd->user_cmd.parse_cmd.cdb_len = cmd->cdb_len;
|
||||
ucmd->user_cmd.parse_cmd.op_flags = cmd->op_flags;
|
||||
ucmd->state = UCMD_STATE_PARSING;
|
||||
dev_user_add_to_ready(ucmd);
|
||||
@@ -1452,9 +1451,14 @@ static int dev_user_process_reply_exec(struct scst_user_cmd *ucmd,
|
||||
cmd->may_need_dma_sync = 1;
|
||||
scst_set_resp_data_len(cmd, ereply->resp_data_len);
|
||||
} else if (cmd->resp_data_len != ereply->resp_data_len) {
|
||||
if (ucmd->ubuff == 0)
|
||||
if (ucmd->ubuff == 0) {
|
||||
/*
|
||||
* We have an empty SG, so can't call
|
||||
* scst_set_resp_data_len()
|
||||
*/
|
||||
cmd->resp_data_len = ereply->resp_data_len;
|
||||
else
|
||||
cmd->resid_possible = 1;
|
||||
} else
|
||||
scst_set_resp_data_len(cmd, ereply->resp_data_len);
|
||||
}
|
||||
|
||||
|
||||
+1
-6
@@ -4923,16 +4923,11 @@ out:
|
||||
return;
|
||||
}
|
||||
|
||||
static const int SCST_CDB_LENGTH[8] = { 6, 10, 10, -1, 16, 12, -1, -1 };
|
||||
static const int SCST_CDB_LENGTH[8] = { 6, 10, 10, 0, 16, 12, 0, 0 };
|
||||
|
||||
#define SCST_CDB_GROUP(opcode) ((opcode >> 5) & 0x7)
|
||||
#define SCST_GET_CDB_LEN(opcode) SCST_CDB_LENGTH[SCST_CDB_GROUP(opcode)]
|
||||
|
||||
int scst_get_cdb_len(const uint8_t *cdb)
|
||||
{
|
||||
return SCST_GET_CDB_LEN(cdb[0]);
|
||||
}
|
||||
|
||||
/* get_trans_len_x extract x bytes from cdb as length starting from off */
|
||||
|
||||
static int get_trans_cdb_len_10(struct scst_cmd *cmd, uint8_t off)
|
||||
|
||||
@@ -555,8 +555,6 @@ void scst_acg_sysfs_put(struct scst_acg *acg);
|
||||
|
||||
#endif /* CONFIG_SCST_PROC */
|
||||
|
||||
int scst_get_cdb_len(const uint8_t *cdb);
|
||||
|
||||
void __scst_dev_check_set_UA(struct scst_device *dev, struct scst_cmd *exclude,
|
||||
const uint8_t *sense, int sense_len);
|
||||
static inline void scst_dev_check_set_UA(struct scst_device *dev,
|
||||
|
||||
@@ -108,8 +108,8 @@ static inline void scst_schedule_tasklet(struct scst_cmd *cmd)
|
||||
* same session.
|
||||
*/
|
||||
struct scst_cmd *scst_rx_cmd(struct scst_session *sess,
|
||||
const uint8_t *lun, int lun_len,
|
||||
const uint8_t *cdb, int cdb_len, int atomic)
|
||||
const uint8_t *lun, int lun_len, const uint8_t *cdb,
|
||||
unsigned int cdb_len, int atomic)
|
||||
{
|
||||
struct scst_cmd *cmd;
|
||||
|
||||
@@ -431,8 +431,6 @@ static int scst_pre_parse(struct scst_cmd *cmd)
|
||||
|
||||
EXTRACHECKS_BUG_ON(cmd->op_flags & SCST_INFO_VALID);
|
||||
|
||||
cmd->cdb_len = scst_get_cdb_len(cmd->cdb);
|
||||
|
||||
TRACE(TRACE_MINOR, "Unknown opcode 0x%02x for %s. "
|
||||
"Should you update scst_scsi_op_table?",
|
||||
cmd->cdb[0], dev->handler->name);
|
||||
@@ -573,7 +571,7 @@ static int scst_parse_cmd(struct scst_cmd *cmd)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (unlikely(cmd->cdb_len == -1)) {
|
||||
if (unlikely(cmd->cdb_len == 0)) {
|
||||
PRINT_ERROR("Unable to get CDB length for "
|
||||
"opcode 0x%02x. Returning INVALID "
|
||||
"OPCODE", cmd->cdb[0]);
|
||||
|
||||
@@ -778,6 +778,7 @@ void *main_loop(void *arg)
|
||||
PRINT_ERROR("SCST_USER_REPLY_AND_GET_CMD failed: "
|
||||
"%s (%d)", strerror(res), res);
|
||||
#if 1
|
||||
cmd.preply = 0;
|
||||
continue;
|
||||
#else
|
||||
goto out_close;
|
||||
|
||||
Reference in New Issue
Block a user