drivers/scsi/scsi_debug.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
REPORT ZONES allocation length is the initiator's receive buffer size,
not a minimum valid response size. Short allocation lengths are valid:
an initiator may request only the first few bytes of the response before
issuing a larger request.
scsi_debug currently derives the number of descriptors from
alloc_len - RZONES_DESC_HD and allocates only alloc_len bytes. For a
nonzero allocation length smaller than the report header, that
subtraction underflows and the handler can write header fields or zone
descriptors past the allocated buffer.
Keep accepting short allocation lengths, but allocate enough internal
space for the report header and only emit descriptors that fit after the
header. Limit the transfer back to the initiator to the requested
allocation length. Non-PARTIAL short requests still return the normal
leading report-length field, so 4-byte length probes continue to work.
Assisted-by: Codex:gpt-5.5-cyber-preview
Signed-off-by: Samuel Moelius <sam.moelius@trailofbits.com>
---
drivers/scsi/scsi_debug.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 1515495fd9ea..6084257dabe1 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -5895,7 +5895,7 @@ static int resp_report_zones(struct scsi_cmnd *scp,
{
unsigned int rep_max_zones, nrz = 0;
int ret = 0;
- u32 alloc_len, rep_opts, rep_len;
+ u32 alloc_len, arr_len, rep_opts, rep_len;
bool partial;
u64 lba, zs_lba;
u8 *arr = NULL, *desc;
@@ -5919,9 +5919,14 @@ static int resp_report_zones(struct scsi_cmnd *scp,
return check_condition_result;
}
- rep_max_zones = (alloc_len - 64) >> ilog2(RZONES_DESC_HD);
+ if (alloc_len > RZONES_DESC_HD)
+ rep_max_zones = (alloc_len - RZONES_DESC_HD) >>
+ ilog2(RZONES_DESC_HD);
+ else
+ rep_max_zones = 0;
+ arr_len = RZONES_DESC_HD + rep_max_zones * RZONES_DESC_HD;
- arr = kzalloc(alloc_len, GFP_ATOMIC | __GFP_NOWARN);
+ arr = kzalloc(arr_len, GFP_ATOMIC | __GFP_NOWARN);
if (!arr) {
mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC,
INSUFF_RES_ASCQ);
--
2.43.0
© 2016 - 2026 Red Hat, Inc.