All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ata: libata-scsi: add out-of-bounds checks in ata_scsiop_inq_b9
@ 2026-07-10 19:32 Karuna Ramkumar
  2026-07-10 19:43 ` sashiko-bot
  0 siblings, 1 reply; 2+ messages in thread
From: Karuna Ramkumar @ 2026-07-10 19:32 UTC (permalink / raw)
  To: Damien Le Moal, Niklas Cassel
  Cc: linux-ide, linux-kernel, ipylypiv, tadamsjr, Karuna Ramkumar

The function ata_scsiop_inq_b9() currently attempts to write 64 +
nr_cpr * 32 number of bytes. If nr_cpr crosses 62, this can cause a
buffer overflow since rbuf is 2048 bytes (ATA_SCSI_RBUF_SIZE) in size.

Fix this by adding bounds check before writing to rbuf. If the total
bytes are greater than ATA_SCSI_RBUF_SIZE, then fail the command with
ABORTED_COMMAND error and exit the function.

Tested this flow by modifying nr_cpr and confirming that the function
exits early, avoiding performing an out-of-bounds write.

Fixes: fe22e1c2f705 ("libata: support concurrent positioning ranges log")
Link: https://lore.kernel.org/all/0E78BE5F-B4EE-460A-A6D5-F0CE47BFC7DF@kernel.org/
Assisted-by: Antigravity:gemini-3.5-flash
Signed-off-by: Karuna Ramkumar <rkaruna@google.com>
---
 drivers/ata/libata-scsi.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 5868526301a2..6f54e23a586c 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -2361,15 +2361,22 @@ 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 page_len;
 
 	if (!cpr_log) {
 		ata_scsi_set_invalid_field(dev, cmd, 2, 0xff);
 		return 0;
 	}
 
+	page_len = 64 + (int)cpr_log->nr_cpr * 32;
+	if (page_len > ATA_SCSI_RBUF_SIZE) {
+		ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, 0, 0);
+		return 0;
+	}
+
 	/* 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(page_len - 4, &rbuf[2]);
 
 	for (i = 0; i < cpr_log->nr_cpr; i++, desc += 32) {
 		desc[0] = cpr_log->cpr[i].num;
-- 
2.55.0.795.g602f6c329a-goog


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] ata: libata-scsi: add out-of-bounds checks in ata_scsiop_inq_b9
  2026-07-10 19:32 [PATCH] ata: libata-scsi: add out-of-bounds checks in ata_scsiop_inq_b9 Karuna Ramkumar
@ 2026-07-10 19:43 ` sashiko-bot
  0 siblings, 0 replies; 2+ messages in thread
From: sashiko-bot @ 2026-07-10 19:43 UTC (permalink / raw)
  To: Karuna Ramkumar; +Cc: linux-ide, dlemoal, cassel

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The newly added bounds check to prevent `page_len > ATA_SCSI_RBUF_SIZE` is mathematically dead code.
--

--- Patch [1]: [PATCH] ata: libata-scsi: add out-of-bounds checks in ata_scsiop_inq_b9 ---
commit bacad4b494e8c54b7f847f50ed2b764d2bdf3fde
Author: Karuna Ramkumar <rkaruna@google.com>
ata: libata-scsi: add out-of-bounds checks in ata_scsiop_inq_b9

This commit adds a bounds check to ata_scsiop_inq_b9() to ensure the
calculated page length does not exceed the SCSI request buffer size. If the
calculated size is larger, the command is aborted to prevent a buffer
overflow.

Link: https://lore.kernel.org/all/0E78BE5F-B4EE-460A-A6D5-F0CE47BFC7DF@kernel.org/

> diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
> --- a/drivers/ata/libata-scsi.c
> +++ b/drivers/ata/libata-scsi.c
[ ... ]
> @@ -2361,15 +2361,22 @@ static unsigned int ata_scsiop_inq_b9(struct ata_device *dev,
[ ... ]
>  	if (!cpr_log) {
>  		ata_scsi_set_invalid_field(dev, cmd, 2, 0xff);
>  		return 0;
>  	}
>  
> +	page_len = 64 + (int)cpr_log->nr_cpr * 32;
> +	if (page_len > ATA_SCSI_RBUF_SIZE) {
> +		ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, 0, 0);
> +		return 0;
> +	}

[Severity: Low]
Is this bounds check reachable during normal operation?

Looking at how cpr_log is populated in ata_read_cpr_log(), nr_cpr is
already explicitly validated against ATA_DEV_MAX_CPR. Since ATA_DEV_MAX_CPR
is mathematically derived from ATA_SCSI_RBUF_SIZE, a device reporting a
value exceeding this limit has its log discarded, leaving dev->cpr_log as
NULL.

Because ata_scsiop_inq_b9() immediately returns if cpr_log is NULL right
above this snippet, it seems page_len can never evaluate to a value greater
than ATA_SCSI_RBUF_SIZE. Does this make the new check mathematically dead
code under real inputs?

> +
>  	/* 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(page_len - 4, &rbuf[2]);
[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260710193235.334782-1-rkaruna@google.com?part=1

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-07-10 19:43 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-10 19:32 [PATCH] ata: libata-scsi: add out-of-bounds checks in ata_scsiop_inq_b9 Karuna Ramkumar
2026-07-10 19:43 ` sashiko-bot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.