From: Niklas Cassel <cassel@kernel.org>
To: shao.mingyin@zte.com.cn
Cc: dlemoal@kernel.org, linux-ide@vger.kernel.org,
linux-kernel@vger.kernel.org, stable@vger.kernel.org
Subject: Re: [PATCH v3 1/4] ata: libata-scsi: reject reserved bits in 32-byte passthru
Date: Fri, 13 Nov 2026 16:36:46 +0100 [thread overview]
Message-ID: <avcujpOaXJPfjgxQ@ryzen> (raw)
In-Reply-To: <20261112220120113cXLhRk6iDVvhfgGPoZ5vJ@zte.com.cn>
On Thu, Nov 12, 2026 at 10:01:20PM +0800, shao.mingyin@zte.com.cn wrote:
> From: Shao Mingyin <shao.mingyin@zte.com.cn>
>
> ATA PASS-THROUGH(32) has no MULTIPLE_COUNT field. Byte 1 is CONTROL,
> and bits 7:5 are reserved or obsolete. Interpreting these bits as a
> multiple count can issue spurious count mismatch warnings for multiple
> commands instead of rejecting the invalid CDB.
>
> Reject nonzero byte 1 bits 7:5 with field pointer 1. Skip the CDB count
> comparison for the 32-byte form while retaining the device multiple-mode
> check. Also point to byte 10 for invalid PROTOCOL. The 12- and 16-byte
> MULTIPLE_COUNT checks remain unchanged.
>
> Fixes: b1ffbf854e08 ("libata: Support for an ATA PASS-THROUGH(32) command.")
> Suggested-by: Niklas Cassel <cassel@kernel.org>
> Signed-off-by: Shao Mingyin <shao.mingyin@zte.com.cn>
> ---
> Changes in v3 (Damien Le Moal):
> - Reject nonzero reserved/obsolete bits 7:5 of byte 1 with fp=1.
> - Retain the short-CDB count and device multiple-mode checks.
> - Update the subject, description and CONTROL-byte test expectations.
> v2: https://lore.kernel.org/all/20261111223129430zClEJF8TDgu_h8ZYM843Q@zte.com.cn/
>
> Validation on x86-64 with GCC 13 and UBSAN: a userspace harness compiles
> ata_scsi_pass_thru() verbatim with SCSI/device stubs. All 256 CONTROL
> values are checked for both non-multiple and multiple commands. Nonzero
> bits 7:5 are rejected with field pointer 1; values with those bits clear
> are accepted without count warnings. The device multiple-mode check and
> 12-/16-byte count checks still pass. Field pointers are observed helper
> arguments; sense construction and device access use stubs.
>
> drivers/ata/libata-scsi.c | 25 +++++++++++++++----------
> 1 file changed, 15 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
> index a61fb03312793ca94d81d8061a16c66e786c4cf3..0bc147cf4c0fa50c7d5b84029b7fb1a548c6f1a3 100644
> --- a/drivers/ata/libata-scsi.c
> +++ b/drivers/ata/libata-scsi.c
> @@ -3388,7 +3388,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
>
> tf->protocol = ata_scsi_map_proto(cdb[1 + cdb_offset]);
> if (tf->protocol == ATA_PROT_UNKNOWN) {
> - fp = 1;
> + fp = 1 + cdb_offset;
> goto invalid_fld;
> }
>
> @@ -3573,27 +3573,32 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
> goto invalid_fld;
> }
>
> - /* sanity check for pio multi commands */
> + /* Sanity check for pio multi commands (not supported with ATA 32). */
This comment is misleading.
READ/WRITE MULTIPLE commands are still accepted with the 32-byte CDB, it is
only the count comparison that will be skipped.
libata reads dev->multi_count from IDENTIFY word 59, during probe/revalidate,
and after receiving a ATA_CMD_SET_MULTI command.
The MULTI_COUNT field is obsolete for 12-byte and 16-byte CDBs in SAT-6
(tables 203 and 209), and the 32-byte CDB has no such field (table 210).
The MULTI_COUNT field was only compared with dev->multi_count, and
if there was a mismatch, libata simply printed a warning:
"invalid multi_count %u ignored", yet the command was still sent and
limited by dev->multi_count (see e.g. ata_pio_sectors() for SFF
controllers).
> + if (cdb[0] == VARIABLE_LENGTH_CMD && (cdb[1] & 0xe0)) {
> + fp = 1;
> + goto invalid_fld;
> + }
In the 32-byte CDB, byte 1 is CONTROL (SAT-6 r2 spec, table 210), and its
bits 7:6 are vendor specific (6.5, table 10), not reserved or obsolete as
the commit message says.
The reserved bits in place of MULTIPLE_COUNT are bits 7:5 of byte 10.
So I think the test should be:
if (cdb[0] == VARIABLE_LENGTH_CMD && (cdb[10] & 0xe0)) {
fp = 10;
goto invalid_fld;
}
Kind regards,
Niklas
next prev parent reply other threads:[~2026-11-13 15:36 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-12 14:01 [PATCH v3 0/4] ata: libata-scsi: fix ATA PASS-THROUGH(32) handling shao.mingyin
2026-11-12 14:01 ` [PATCH v3 1/4] ata: libata-scsi: reject reserved bits in 32-byte passthru shao.mingyin
2026-11-13 0:20 ` Damien Le Moal
2026-11-13 6:05 ` shao.mingyin
2026-11-13 15:36 ` Niklas Cassel [this message]
2026-11-12 14:01 ` [PATCH v3 2/4] ata: libata-scsi: reject unsupported ATA-32 service actions shao.mingyin
2026-11-12 14:01 ` [PATCH v3 3/4] ata: libata-scsi: generate SAT sense data for ATA PASS-THROUGH(32) shao.mingyin
2026-11-12 14:01 ` [PATCH v3 4/4] ata: libata-scsi: fix remaining passthru field pointers shao.mingyin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=avcujpOaXJPfjgxQ@ryzen \
--to=cassel@kernel.org \
--cc=dlemoal@kernel.org \
--cc=linux-ide@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=shao.mingyin@zte.com.cn \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox