diff options
| author | Paolo Bonzini <pbonzini@redhat.com> | 2012-09-07 11:30:33 -0400 |
|---|---|---|
| committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-09-07 14:09:08 -0400 |
| commit | 0d7f1299ca5540b9a63ab6e8bf0e89ea963eb6af (patch) | |
| tree | 25bba610d95a2d7256830eb41032e5b1e2853fd4 | |
| parent | 306c11b28d7bb85a7adda741798a2b6b60dd305a (diff) | |
target: report too-small parameter lists everywhere
Several places were not checking that the parameter list length
was large enough, and thus accessing invalid memory. Zero-length
parameter lists are just a special case of this.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
| -rw-r--r-- | drivers/target/target_core_alua.c | 7 | ||||
| -rw-r--r-- | drivers/target/target_core_iblock.c | 17 | ||||
| -rw-r--r-- | drivers/target/target_core_pr.c | 8 |
3 files changed, 30 insertions, 2 deletions
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 91799973081a..41641ba54828 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c | |||
| @@ -218,6 +218,13 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
| 218 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 218 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
| 219 | return -EINVAL; | 219 | return -EINVAL; |
| 220 | } | 220 | } |
| 221 | if (cmd->data_length < 4) { | ||
| 222 | pr_warn("SET TARGET PORT GROUPS parameter list length %u too" | ||
| 223 | " small\n", cmd->data_length); | ||
| 224 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | ||
| 225 | return -EINVAL; | ||
| 226 | } | ||
| 227 | |||
| 221 | buf = transport_kmap_data_sg(cmd); | 228 | buf = transport_kmap_data_sg(cmd); |
| 222 | 229 | ||
| 223 | /* | 230 | /* |
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 76db75e836ed..9ba495477fd2 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c | |||
| @@ -325,17 +325,30 @@ static int iblock_execute_unmap(struct se_cmd *cmd) | |||
| 325 | struct iblock_dev *ibd = dev->dev_ptr; | 325 | struct iblock_dev *ibd = dev->dev_ptr; |
| 326 | unsigned char *buf, *ptr = NULL; | 326 | unsigned char *buf, *ptr = NULL; |
| 327 | sector_t lba; | 327 | sector_t lba; |
| 328 | int size = cmd->data_length; | 328 | int size; |
| 329 | u32 range; | 329 | u32 range; |
| 330 | int ret = 0; | 330 | int ret = 0; |
| 331 | int dl, bd_dl; | 331 | int dl, bd_dl; |
| 332 | 332 | ||
| 333 | if (cmd->data_length < 8) { | ||
| 334 | pr_warn("UNMAP parameter list length %u too small\n", | ||
| 335 | cmd->data_length); | ||
| 336 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | ||
| 337 | return -EINVAL; | ||
| 338 | } | ||
| 339 | |||
| 333 | buf = transport_kmap_data_sg(cmd); | 340 | buf = transport_kmap_data_sg(cmd); |
| 334 | 341 | ||
| 335 | dl = get_unaligned_be16(&buf[0]); | 342 | dl = get_unaligned_be16(&buf[0]); |
| 336 | bd_dl = get_unaligned_be16(&buf[2]); | 343 | bd_dl = get_unaligned_be16(&buf[2]); |
| 337 | 344 | ||
| 338 | size = min(size - 8, bd_dl); | 345 | size = cmd->data_length - 8; |
| 346 | if (bd_dl > size) | ||
| 347 | pr_warn("UNMAP parameter list length %u too small, ignoring bd_dl %u\n", | ||
| 348 | cmd->data_length, bd_dl); | ||
| 349 | else | ||
| 350 | size = bd_dl; | ||
| 351 | |||
| 339 | if (size / 16 > dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { | 352 | if (size / 16 > dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { |
| 340 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 353 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
| 341 | ret = -EINVAL; | 354 | ret = -EINVAL; |
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 1e946502c378..956c84c6b666 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
| @@ -1540,6 +1540,14 @@ static int core_scsi3_decode_spec_i_port( | |||
| 1540 | tidh_new->dest_local_nexus = 1; | 1540 | tidh_new->dest_local_nexus = 1; |
| 1541 | list_add_tail(&tidh_new->dest_list, &tid_dest_list); | 1541 | list_add_tail(&tidh_new->dest_list, &tid_dest_list); |
| 1542 | 1542 | ||
| 1543 | if (cmd->data_length < 28) { | ||
| 1544 | pr_warn("SPC-PR: Received PR OUT parameter list" | ||
| 1545 | " length too small: %u\n", cmd->data_length); | ||
| 1546 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | ||
| 1547 | ret = -EINVAL; | ||
| 1548 | goto out; | ||
| 1549 | } | ||
| 1550 | |||
| 1543 | buf = transport_kmap_data_sg(cmd); | 1551 | buf = transport_kmap_data_sg(cmd); |
| 1544 | /* | 1552 | /* |
| 1545 | * For a PERSISTENT RESERVE OUT specify initiator ports payload, | 1553 | * For a PERSISTENT RESERVE OUT specify initiator ports payload, |
