[PATCH v2 2/4] ata: libata-scsi: reject unsupported ATA-32 service actions
From: shao.mingyin
Date: Wed Nov 11 2026 - 09:38:19 EST
From: Shao Mingyin <shao.mingyin@xxxxxxxxxx>
ata_scsi_var_len_cdb_xlat() returns 1 for an unsupported service action
without setting sense data. ata_scsi_translate() then completes the
command with the SCSI result still zero, reporting SAM_STAT_GOOD even
though no ATA command was issued and no data was transferred.
Set ILLEGAL REQUEST/INVALID FIELD IN CDB before returning, with the
field pointer referring to the SERVICE ACTION field at byte 8.
Fixes: b1ffbf854e08 ("libata: Support for an ATA PASS-THROUGH(32) command.")
Reviewed-by: Damien Le Moal <dlemoal@xxxxxxxxxx>
Signed-off-by: Shao Mingyin <shao.mingyin@xxxxxxxxxx>
---
Changes in v2:
- No code changes; regenerate against the series base and keep the
Reviewed-by tag.
v1: https://lore.kernel.org/all/20261104221102824qAKUWNkiSgZ1yRnQM8hI9@xxxxxxxxxx/
Validation on x86-64 with GCC 13 and UBSAN: a userspace harness compiled
the translation functions verbatim with SCSI/device stubs. For service
action 0x1234, completion changed from result 0 to ILLEGAL REQUEST,
INVALID FIELD IN CDB; the invalid-field helper received field pointer 8.
A valid ATA_32 service action remained accepted.
drivers/ata/libata-scsi.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 227240514651ada8b5feb87a154833fb2cddf064..3fffa2617339fb7aa8a9035bbd88258794e1bf63 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -5028,7 +5028,13 @@ static unsigned int ata_scsi_var_len_cdb_xlat(struct ata_queued_cmd *qc)
if (sa == ATA_32)
return ata_scsi_pass_thru(qc);
- /* unsupported service action */
+ /*
+ * Unsupported service action. Set the sense data explicitly, as
+ * returning 1 without it makes ata_scsi_translate() complete the
+ * command with the SCSI result still zero, that is, with
+ * SAM_STAT_GOOD.
+ */
+ ata_scsi_set_invalid_field(qc->dev, scmd, 8, 0xff);
return 1;
}