Re: [PATCH RESEND 2] libata: if T_LENGTH is zero, dma direction should be DMA_NONE
From: Damien Le Moal <hidden>
Date: 2021-12-13 23:50:57
Also in:
lkml
On 2021/12/14 7:15, George Kennedy wrote:
On 12/13/2021 4:37 PM, Damien Le Moal wrote:quoted
On 2021/12/14 0:33, George Kennedy wrote:quoted
Avoid data corruption by rejecting pass-through commands where T_LENGTH is zero (No data is transferred) and the dma direction is not DMA_NONE. Cc:[off-list ref] # 5.4.y5.4 only ? What about other LTS versions ? They do not have that bug ?Our distros are based on 5.4.y, 5.15.y and 4.14.y, so the fix should go there, but it looks like the fix is also needed in: 5.14.y, 5.13.y, 5.10.y, and 4.19.y.
Then please resend with: Cc: stable@vger.kernel.org No version specified.
Thank you, Georgequoted
quoted
Reported-by: syzkaller<redacted> Signed-off-by: George Kennedy<redacted> --- drivers/ata/libata-scsi.c | 6 ++++++ 1 file changed, 6 insertions(+)diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 1b84d55..d428392 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c@@ -2859,6 +2859,12 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) goto invalid_fld; } + /* if T_LENGTH is zero (No data is transferred), then dir should be DMA_NONE */ + if ((cdb[2 + cdb_offset] & 3) == 0 && scmd->sc_data_direction != DMA_NONE) { + fp = 2 + cdb_offset; + goto invalid_fld; + } + if (ata_is_ncq(tf->protocol) && (cdb[2 + cdb_offset] & 0x3) == 0)
cdb[2 + cdb_offset] & 3) is used again for the ncq test, so you can group things:
if (!(cdb[2 + cdb_offset] & 0x3)) {
/*
* When T_LENGTH is zero (no data is transferred),
* then dir should be DMA_NONE.
*/
if (scmd->sc_data_direction != DMA_NONE) {
fp = 2 + cdb_offset;
goto invalid_fld;
}
if (ata_is_ncq(tf->protocol))
tf->protocol = ATA_PROT_NCQ_NODATA;
}
quoted
quoted
tf->protocol = ATA_PROT_NCQ_NODATA; -- 1.8.3.1
-- Damien Le Moal Western Digital Research