diff options
| author | Damien Le Moal <damien.lemoal@wdc.com> | 2018-06-26 07:56:54 -0400 |
|---|---|---|
| committer | Tejun Heo <tj@kernel.org> | 2018-07-02 11:59:11 -0400 |
| commit | b320a0a9f23c98f21631eb27bcbbca91c79b1c6e (patch) | |
| tree | 825d8e21f42ebfb0710d38ac2485a4849627d504 | |
| parent | ba44579141f9e2c0229e6e7eeb00b5fa68f0f74a (diff) | |
ata: Fix ZBC_OUT command block check
The block (LBA) specified must not exceed the last addressable LBA,
which is dev->nr_sectors - 1. So fix the correct check is
"if (block >= dev->n_sectors)" and not "if (block > dev->n_sectords)".
Additionally, the asc/ascq to return for an LBA that is not a zone start
LBA should be ILLEGAL REQUEST, regardless if the bad LBA is out of
range.
Reported-by: David Butterfield <david.butterfield@wdc.com>
Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
Cc: stable@vger.kernel.org
Signed-off-by: Tejun Heo <tj@kernel.org>
| -rw-r--r-- | drivers/ata/libata-scsi.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 6a91d04351d9..a5543751f446 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
| @@ -3805,8 +3805,13 @@ static unsigned int ata_scsi_zbc_out_xlat(struct ata_queued_cmd *qc) | |||
| 3805 | */ | 3805 | */ |
| 3806 | goto invalid_param_len; | 3806 | goto invalid_param_len; |
| 3807 | } | 3807 | } |
| 3808 | if (block > dev->n_sectors) | 3808 | if (block >= dev->n_sectors) { |
| 3809 | goto out_of_range; | 3809 | /* |
| 3810 | * Block must be a valid zone ID (a zone start LBA). | ||
| 3811 | */ | ||
| 3812 | fp = 2; | ||
| 3813 | goto invalid_fld; | ||
| 3814 | } | ||
| 3810 | 3815 | ||
| 3811 | all = cdb[14] & 0x1; | 3816 | all = cdb[14] & 0x1; |
| 3812 | 3817 | ||
| @@ -3837,10 +3842,6 @@ static unsigned int ata_scsi_zbc_out_xlat(struct ata_queued_cmd *qc) | |||
| 3837 | invalid_fld: | 3842 | invalid_fld: |
| 3838 | ata_scsi_set_invalid_field(qc->dev, scmd, fp, 0xff); | 3843 | ata_scsi_set_invalid_field(qc->dev, scmd, fp, 0xff); |
| 3839 | return 1; | 3844 | return 1; |
| 3840 | out_of_range: | ||
| 3841 | /* "Logical Block Address out of range" */ | ||
| 3842 | ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x21, 0x00); | ||
| 3843 | return 1; | ||
| 3844 | invalid_param_len: | 3845 | invalid_param_len: |
| 3845 | /* "Parameter list length error" */ | 3846 | /* "Parameter list length error" */ |
| 3846 | ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x1a, 0x0); | 3847 | ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x1a, 0x0); |
