Linux ATA/IDE development
 help / color / mirror / Atom feed
From: Damien Le Moal <dlemoal@kernel.org>
To: shao.mingyin@zte.com.cn, cassel@kernel.org, linux-ide@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Subject: Re: [PATCH v2 1/4] ata: libata-scsi: skip MULTIPLE_COUNT for 32-byte passthru
Date: Thu, 12 Nov 2026 08:28:41 +0900	[thread overview]
Message-ID: <440db014-a58c-44e4-bc96-e950e69b6763@kernel.org> (raw)
In-Reply-To: <20261111223129430zClEJF8TDgu_h8ZYM843Q@zte.com.cn>

On 11/11/26 23:31, shao.mingyin@zte.com.cn wrote:
> From: Shao Mingyin <shao.mingyin@zte.com.cn>
> 
> ATA PASS-THROUGH(32) has no MULTIPLE_COUNT field. Reading byte 1 as
> that field instead interprets the variable-length CDB CONTROL byte,
> which can reject a non-multiple command or cause a spurious count
> mismatch warning for READ/WRITE MULTIPLE.
> 
> Skip the CDB count checks for the 32-byte form while retaining the
> check that multiple mode is enabled on the device. Also report byte 10
> for an invalid PROTOCOL, where that field resides in a 32-byte CDB.
> 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 v2 (Niklas Cassel):
> - Skip the nonexistent MULTIPLE_COUNT field for the 32-byte CDB;
>   preserve the device multiple-mode check and the short-CDB checks.
> - Move the invalid-PROTOCOL field pointer fix here from patch 3.
> - Regenerate with git format-patch; do not edit diff hunks or indexes.
> - Do not carry the v1 Reviewed-by tag over the reworked code.
> v1: https://lore.kernel.org/all/20261104220939917jqg8_alGN5sACGWq5M9D-@zte.com.cn/
> 
> Validation on x86-64 with GCC 13 and UBSAN: a userspace harness compiled
> ata_scsi_pass_thru() verbatim with SCSI/device stubs. An invalid PROTOCOL
> in a 32-byte CDB passed field pointer 1 to the invalid-field helper before
> the fix and 10 afterwards. CONTROL-byte variations no longer caused
> false rejection or multiple-count warnings. A device with multiple mode
> disabled still rejected READ/WRITE MULTIPLE; short-CDB checks were kept.
> 
>  drivers/ata/libata-scsi.c | 23 ++++++++++++-----------
>  1 file changed, 12 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
> index a61fb03312793ca94d81d8061a16c66e786c4cf3..227240514651ada8b5feb87a154833fb2cddf064 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,28 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
>  		goto invalid_fld;
>  	}
>  
> -	/* sanity check for pio multi commands */
> -	if ((cdb[1] & 0xe0) && !is_multi_taskfile(tf)) {
> +	/* The 32-byte CDB has no MULTIPLE_COUNT field. */
> +	if (cdb[0] != VARIABLE_LENGTH_CMD &&
> +	    (cdb[1] & 0xe0) && !is_multi_taskfile(tf)) {

Sinc ATA 32 defines these beets as reserved/obsolete, we should check that they
are 0 and reject the command if they are not. So something like:

	/* Sanity check for pio multi commands (not supported with ATA 32). */
	if (cdb[0] == VARIABLE_LENGTH_CMD && (cdb[1] & 0xe0)) {
		fp = 1;
		goto invalid_fld;
	}

	if ((cdb[1] & 0xe0) && !is_multi_taskfile(tf)) {
		...

>  		fp = 1;
>  		goto invalid_fld;
>  	}
>  
>  	if (is_multi_taskfile(tf)) {
> -		unsigned int multi_count = 1 << (cdb[1] >> 5);
> -
>  		if (!dev->multi_count) {
>  			ata_scsi_set_sense(dev, scmd, ABORTED_COMMAND,
>  					   NO_ADDITIONAL_SENSE_INFORMATION);
>  			return 1;
>  		}
>  
> -		/* compare the passed through multi_count
> -		 * with the cached multi_count of libata
> -		 */
> -		if (multi_count != dev->multi_count)
> -			ata_dev_warn(dev, "invalid multi_count %u ignored\n",
> -				     multi_count);
> +		if (cdb[0] != VARIABLE_LENGTH_CMD) {
> +			unsigned int multi_count = 1 << (cdb[1] >> 5);
> +
> +			/* Compare with the cached multiple count of libata. */
> +			if (multi_count != dev->multi_count)
> +				ata_dev_warn(dev, "invalid multi_count %u ignored\n",
> +					     multi_count);
> +		}
>  	}
>  
>  	/*


-- 
Damien Le Moal
Western Digital Research

  reply	other threads:[~2026-11-11 23:28 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-11 14:31 [PATCH v2 0/4] ata: libata-scsi: fix ATA PASS-THROUGH(32) handling shao.mingyin
2026-11-11 14:31 ` [PATCH v2 1/4] ata: libata-scsi: skip MULTIPLE_COUNT for 32-byte passthru shao.mingyin
2026-11-11 23:28   ` Damien Le Moal [this message]
2026-11-12  4:12     ` shao.mingyin
2026-11-11 14:31 ` [PATCH v2 2/4] ata: libata-scsi: reject unsupported ATA-32 service actions shao.mingyin
2026-11-11 14:31 ` [PATCH v2 3/4] ata: libata-scsi: generate SAT sense data for ATA PASS-THROUGH(32) shao.mingyin
2026-11-11 14:31 ` [PATCH v2 4/4] ata: libata-scsi: fix remaining passthru field pointers shao.mingyin
2026-11-11 23:30   ` Damien Le Moal

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=440db014-a58c-44e4-bc96-e950e69b6763@kernel.org \
    --to=dlemoal@kernel.org \
    --cc=cassel@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