mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-21 04:31:26 +00:00
scst: Limit the size of READ CAPACITY buffers
Fixes: be8b679bb8 ("scst: fix tapes handling with Windows initiators")
Reported-by: James McCarthy <mccarthy1029@gmail.com>
git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9336 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -2342,6 +2342,8 @@ struct scst_cmd {
|
|||||||
uint8_t lba_len; /* LBA length in cdb */
|
uint8_t lba_len; /* LBA length in cdb */
|
||||||
uint8_t len_off; /* length offset in cdb */
|
uint8_t len_off; /* length offset in cdb */
|
||||||
uint8_t len_len; /* length length in cdb */
|
uint8_t len_len; /* length length in cdb */
|
||||||
|
/* If not zero, logarithm base 2 of the maximum data buffer length. */
|
||||||
|
uint8_t log2_max_buf_len;
|
||||||
uint32_t op_flags; /* various flags of this opcode */
|
uint32_t op_flags; /* various flags of this opcode */
|
||||||
const char *op_name; /* op code SCSI full name */
|
const char *op_name; /* op code SCSI full name */
|
||||||
|
|
||||||
|
|||||||
@@ -550,6 +550,8 @@ struct scst_sdbops {
|
|||||||
* target <--> init: SCST_DATA_READ|
|
* target <--> init: SCST_DATA_READ|
|
||||||
* SCST_DATA_WRITE
|
* SCST_DATA_WRITE
|
||||||
*/
|
*/
|
||||||
|
/* If not zero, logarithm base 2 of the maximum data buffer length. */
|
||||||
|
uint8_t log2_max_buf_len;
|
||||||
uint32_t info_op_flags; /* various flags of this opcode */
|
uint32_t info_op_flags; /* various flags of this opcode */
|
||||||
const char *info_op_name;/* op code SCSI full name */
|
const char *info_op_name;/* op code SCSI full name */
|
||||||
int (*get_cdb_info)(struct scst_cmd *cmd, const struct scst_sdbops *sdbops);
|
int (*get_cdb_info)(struct scst_cmd *cmd, const struct scst_sdbops *sdbops);
|
||||||
@@ -876,6 +878,7 @@ static const struct scst_sdbops scst_scsi_op_table[] = {
|
|||||||
.info_data_direction = SCST_DATA_READ,
|
.info_data_direction = SCST_DATA_READ,
|
||||||
.info_op_flags = SCST_IMPLICIT_HQ|SCST_REG_RESERVE_ALLOWED|
|
.info_op_flags = SCST_IMPLICIT_HQ|SCST_REG_RESERVE_ALLOWED|
|
||||||
SCST_WRITE_EXCL_ALLOWED|SCST_EXCL_ACCESS_ALLOWED,
|
SCST_WRITE_EXCL_ALLOWED|SCST_EXCL_ACCESS_ALLOWED,
|
||||||
|
.log2_max_buf_len = 3,
|
||||||
.get_cdb_info = get_cdb_info_read_capacity},
|
.get_cdb_info = get_cdb_info_read_capacity},
|
||||||
{.ops = 0x25, .devkey = " O ",
|
{.ops = 0x25, .devkey = " O ",
|
||||||
.info_op_name = "GET WINDOW",
|
.info_op_name = "GET WINDOW",
|
||||||
@@ -11213,6 +11216,7 @@ static int get_cdb_info_serv_act_in(struct scst_cmd *cmd,
|
|||||||
SCST_REG_RESERVE_ALLOWED |
|
SCST_REG_RESERVE_ALLOWED |
|
||||||
SCST_WRITE_EXCL_ALLOWED |
|
SCST_WRITE_EXCL_ALLOWED |
|
||||||
SCST_EXCL_ACCESS_ALLOWED;
|
SCST_EXCL_ACCESS_ALLOWED;
|
||||||
|
cmd->log2_max_buf_len = 5;
|
||||||
break;
|
break;
|
||||||
case SAI_GET_LBA_STATUS:
|
case SAI_GET_LBA_STATUS:
|
||||||
cmd->op_name = "GET LBA STATUS";
|
cmd->op_name = "GET LBA STATUS";
|
||||||
@@ -11818,6 +11822,8 @@ static int get_cdb_info_dyn_runtime_attr(struct scst_cmd *cmd,
|
|||||||
static int scst_set_cmd_from_cdb_info(struct scst_cmd *cmd,
|
static int scst_set_cmd_from_cdb_info(struct scst_cmd *cmd,
|
||||||
const struct scst_sdbops *ptr)
|
const struct scst_sdbops *ptr)
|
||||||
{
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
cmd->cdb_len = SCST_GET_CDB_LEN(cmd->cdb[0]);
|
cmd->cdb_len = SCST_GET_CDB_LEN(cmd->cdb[0]);
|
||||||
cmd->cmd_naca = (cmd->cdb[cmd->cdb_len - 1] & CONTROL_BYTE_NACA_BIT);
|
cmd->cmd_naca = (cmd->cdb[cmd->cdb_len - 1] & CONTROL_BYTE_NACA_BIT);
|
||||||
cmd->cmd_linked = (cmd->cdb[cmd->cdb_len - 1] & CONTROL_BYTE_LINK_BIT);
|
cmd->cmd_linked = (cmd->cdb[cmd->cdb_len - 1] & CONTROL_BYTE_LINK_BIT);
|
||||||
@@ -11828,7 +11834,16 @@ static int scst_set_cmd_from_cdb_info(struct scst_cmd *cmd,
|
|||||||
cmd->lba_len = ptr->info_lba_len;
|
cmd->lba_len = ptr->info_lba_len;
|
||||||
cmd->len_off = ptr->info_len_off;
|
cmd->len_off = ptr->info_len_off;
|
||||||
cmd->len_len = ptr->info_len_len;
|
cmd->len_len = ptr->info_len_len;
|
||||||
return (*ptr->get_cdb_info)(cmd, ptr);
|
cmd->log2_max_buf_len = ptr->log2_max_buf_len;
|
||||||
|
res = (*ptr->get_cdb_info)(cmd, ptr);
|
||||||
|
if (!cmd->log2_max_buf_len ||
|
||||||
|
cmd->bufflen <= (1U << cmd->log2_max_buf_len))
|
||||||
|
return res;
|
||||||
|
PRINT_ERROR("Data buffer length %d is too big for SCSI command %s (max %d)",
|
||||||
|
cmd->bufflen, scst_get_opcode_name(cmd),
|
||||||
|
1U << cmd->log2_max_buf_len);
|
||||||
|
scst_set_invalid_field_in_cdb(cmd, cmd->len_off, 0);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_cdb_info_var_len(struct scst_cmd *cmd,
|
static int get_cdb_info_var_len(struct scst_cmd *cmd,
|
||||||
|
|||||||
Reference in New Issue
Block a user