From: Sasha Levin <sashal@kernel.org>
To: stable@vger.kernel.org
Cc: Bryam Vargas <hexlabsecurity@proton.me>,
Damien Le Moal <dlemoal@kernel.org>,
Niklas Cassel <cassel@kernel.org>,
Sasha Levin <sashal@kernel.org>
Subject: [PATCH 6.1.y] ata: libata-core: Reject an invalid concurrent positioning ranges count
Date: Tue, 28 Jul 2026 23:53:23 -0400 [thread overview]
Message-ID: <20260729035323.1379596-1-sashal@kernel.org> (raw)
In-Reply-To: <2026072113-nanometer-showdown-d9de@gregkh>
From: Bryam Vargas <hexlabsecurity@proton.me>
[ Upstream commit 533a0b940f901c15e5cbbd4b5d66e871c209e8ce ]
ata_dev_config_cpr() takes the number of range descriptors from buf[0]
of the concurrent positioning ranges log (up to 255), which the device
reports independently of the log size in the GPL directory. The count is
then walked at a fixed 32-byte stride in two places with no bound: the
log read here, and the INQUIRY VPD page B9h emitter, which writes one
descriptor per range into the fixed 2048-byte ata_scsi_rbuf. A device
reporting a count larger than its own log overflows the read buffer (up
to 7704 bytes past a 512-byte slab), and a count above 62 overflows the
response buffer on the emit side.
Bound the count once, on probe, against both the log the device returned
and the number of descriptors the VPD B9h response buffer can hold
(ATA_DEV_MAX_CPR, derived from the rbuf size). Reject an out-of-range
count with a warning; this keeps the emitter in bounds with no separate
change there.
Suggested-by: Damien Le Moal <dlemoal@kernel.org>
Fixes: fe22e1c2f705 ("libata: support concurrent positioning ranges log")
Fixes: c745dfc541e7 ("libata: fix reading concurrent positioning ranges log")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Reviewed-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/ata/libata-core.c | 18 ++++++++++++++++++
drivers/ata/libata-scsi.c | 2 --
drivers/ata/libata.h | 9 +++++++++
3 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 96b13b89f0a73c..ce4dac033578ae 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2598,6 +2598,24 @@ static void ata_dev_config_cpr(struct ata_device *dev)
if (!nr_cpr)
goto out;
+ /*
+ * The device reports the number of CPR descriptors independently of the
+ * log size, and that count is also used to emit VPD page B9h into the
+ * fixed-size rbuf. Reject a count larger than what that buffer can hold
+ * (ATA_DEV_MAX_CPR) or larger than the log the device actually returned.
+ */
+ if (nr_cpr > ATA_DEV_MAX_CPR) {
+ ata_dev_warn(dev,
+ "Too many concurrent positioning ranges\n");
+ goto out;
+ }
+
+ if (buf_len < 64 + (size_t)nr_cpr * 32) {
+ ata_dev_warn(dev,
+ "Invalid number of concurrent positioning ranges\n");
+ goto out;
+ }
+
cpr_log = kzalloc(struct_size(cpr_log, cpr, nr_cpr), GFP_KERNEL);
if (!cpr_log)
goto out;
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 5e492655230842..55bf5ebd9b082b 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -37,8 +37,6 @@
#include "libata.h"
#include "libata-transport.h"
-#define ATA_SCSI_RBUF_SIZE 576
-
static DEFINE_SPINLOCK(ata_scsi_rbuf_lock);
static u8 ata_scsi_rbuf[ATA_SCSI_RBUF_SIZE];
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index a5e0e676ed9a81..25e18bcc0192b6 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -112,6 +112,15 @@ static inline void ata_acpi_bind_dev(struct ata_device *dev) {}
#endif
/* libata-scsi.c */
+#define ATA_SCSI_RBUF_SIZE 576
+
+/*
+ * Maximum number of concurrent positioning ranges (CPR) supported. The ACS
+ * specifications allow up to 255, but we limit this to the number of CPR
+ * descriptors that fit in the rbuf buffer used to emit VPD page B9h.
+ */
+#define ATA_DEV_MAX_CPR min(255, ((ATA_SCSI_RBUF_SIZE - 64) / 32))
+
extern struct ata_device *ata_scsi_find_dev(struct ata_port *ap,
const struct scsi_device *scsidev);
extern int ata_scsi_add_hosts(struct ata_host *host,
--
2.53.0
prev parent reply other threads:[~2026-07-29 3:53 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-21 9:02 FAILED: patch "[PATCH] ata: libata-core: Reject an invalid concurrent positioning" failed to apply to 6.1-stable tree gregkh
2026-07-29 3:53 ` Sasha Levin [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=20260729035323.1379596-1-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=cassel@kernel.org \
--cc=dlemoal@kernel.org \
--cc=hexlabsecurity@proton.me \
--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