Linux ATA/IDE development
 help / color / mirror / Atom feed
From: Damien Le Moal <dlemoal@kernel.org>
To: hexlabsecurity@proton.me, Niklas Cassel <cassel@kernel.org>
Cc: linux-ide@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 2/2] ata: libata-scsi: Bound the VPD B9h ranges to the response buffer
Date: Mon, 22 Jun 2026 20:42:29 +0900	[thread overview]
Message-ID: <306825e1-ce7f-48b2-a643-ba18af05c51f@kernel.org> (raw)
In-Reply-To: <20260619-b4-disp-6200c44e-v1-2-4624a4707d9e@proton.me>

On 6/20/26 11:36, Bryam Vargas via B4 Relay wrote:
> From: Bryam Vargas <hexlabsecurity@proton.me>
> 
> ata_scsiop_inq_b9() writes one 32-byte range descriptor per
> cpr_log->nr_cpr into the fixed 2048-byte ata_scsi_rbuf with no bound.
> The count originates from the device (concurrent positioning ranges log
> 0x47, up to 255), so an INQUIRY VPD page B9h to a drive whose log
> advertises more than 62 ranges overflows the static buffer by up to 6168
> bytes: a global out-of-bounds write into adjacent kernel data.
> 
> Emit only as many descriptors as the response buffer can hold and size
> the page length to match. The companion core fix bounds the stored count
> against the device log, but a large self-consistent log still yields
> nr_cpr up to 255, so the emitter needs its own bound.
> 
> Fixes: fe22e1c2f705 ("libata: support concurrent positioning ranges log")
> Cc: stable@vger.kernel.org
> Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
> ---
>  drivers/ata/libata-scsi.c | 12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
> index d43207c6e467..d43306c5d375 100644
> --- a/drivers/ata/libata-scsi.c
> +++ b/drivers/ata/libata-scsi.c
> @@ -2355,18 +2355,24 @@ static unsigned int ata_scsiop_inq_b9(struct ata_device *dev,
>  {
>  	struct ata_cpr_log *cpr_log = dev->cpr_log;
>  	u8 *desc = &rbuf[64];
> -	int i;
> +	int i, nr_cpr;
>  
>  	if (!cpr_log) {
>  		ata_scsi_set_invalid_field(dev, cmd, 2, 0xff);
>  		return 0;
>  	}
>  
> +	/*
> +	 * The page is built in the fixed-size ata_scsi_rbuf, so the number of
> +	 * range descriptors returned is bounded by that buffer's size.
> +	 */
> +	nr_cpr = min_t(int, cpr_log->nr_cpr, (ATA_SCSI_RBUF_SIZE - 64) / 32);
> +

I do not think this is the right place to fix this. Rather, we should define the
maximum number of ranges we can support given a 2K rbuf, that is, (2048 - 64) /
32 = 62, and check on probe that we are not actually exceeding that value when
scanning the disk. If we do, warn and ignore CPR.

62 ranges would mean 62 actuators... We are light years away from seeing drives
with that many actuators (we are lucky if we get 2, so...).

So I think we can drop this patch and simply reinforce the checks on the number
of cpr in patch 1. Or make this additional patch another fix if you prefer.
Either way is OK with me.

>  	/* SCSI Concurrent Positioning Ranges VPD page: SBC-5 rev 1 or later */
>  	rbuf[1] = 0xb9;
> -	put_unaligned_be16(64 + (int)cpr_log->nr_cpr * 32 - 4, &rbuf[2]);
> +	put_unaligned_be16(64 + nr_cpr * 32 - 4, &rbuf[2]);
>  
> -	for (i = 0; i < cpr_log->nr_cpr; i++, desc += 32) {
> +	for (i = 0; i < nr_cpr; i++, desc += 32) {
>  		desc[0] = cpr_log->cpr[i].num;
>  		desc[1] = cpr_log->cpr[i].num_storage_elements;
>  		put_unaligned_be64(cpr_log->cpr[i].start_lba, &desc[8]);
> 


-- 
Damien Le Moal
Western Digital Research

      reply	other threads:[~2026-06-22 11:42 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-20  2:36 [PATCH 0/2] ata: bound the concurrent positioning ranges count from the device Bryam Vargas via B4 Relay
2026-06-20  2:36 ` [PATCH 1/2] ata: libata-core: Clamp the concurrent positioning ranges count Bryam Vargas via B4 Relay
2026-06-22 11:36   ` Damien Le Moal
2026-06-20  2:36 ` [PATCH 2/2] ata: libata-scsi: Bound the VPD B9h ranges to the response buffer Bryam Vargas via B4 Relay
2026-06-22 11:42   ` Damien Le Moal [this message]

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=306825e1-ce7f-48b2-a643-ba18af05c51f@kernel.org \
    --to=dlemoal@kernel.org \
    --cc=cassel@kernel.org \
    --cc=hexlabsecurity@proton.me \
    --cc=linux-ide@vger.kernel.org \
    --cc=linux-kernel@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