* [PATCH] scsi: target: iscsi: reject zero-length Extended CDB AHS
@ 2026-04-04 1:44 carlos.bilbao
2026-04-07 9:23 ` Dmitry Bogdanov
2026-04-09 2:42 ` [PATCH v2] scsi: target: iscsi: reject invalid size " carlos.bilbao
0 siblings, 2 replies; 10+ messages in thread
From: carlos.bilbao @ 2026-04-04 1:44 UTC (permalink / raw)
To: martin.petersen, kees
Cc: pabeni, mlombard, kuniyu, d.bogdanov, michael.christie,
linux-scsi, target-devel, linux-kernel, bilbao, Carlos Bilbao
From: Carlos Bilbao <carlos.bilbao@kernel.org>
If ecdb_ahdr->ahslength is zero, two bugs follow:
kmalloc(be16_to_cpu(ecdb_ahdr->ahslength) + 15, ...)
allocates 15 bytes, but the immediately following memcpy writes
ISCSI_CDB_SIZE (16) bytes into it, a one-byte heap overflow. Also:
memcpy(cdb + ISCSI_CDB_SIZE, ecdb_ahdr->ecdb,
be16_to_cpu(ecdb_ahdr->ahslength) - 1);
(u16)0 - 1 promotes to (int)-1 which converts to SIZE_MAX as size_t,
causing a massive out-of-bounds write.
Reject ahslength == 0 with ISCSI_REASON_PROTOCOL_ERROR before the kmalloc.
Fixes: 8f1f7d297bce ("scsi: target: iscsi: Add support for extended CDB AHS")
Signed-off-by: Carlos Bilbao (Lambda) <carlos.bilbao@kernel.org>
---
drivers/target/iscsi/iscsi_target.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index e80449f6ce15..8db24d35c762 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -1100,6 +1100,8 @@ int iscsit_setup_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
cdb = hdr->cdb;
if (hdr->hlength) {
+ u16 ahslength;
+
ecdb_ahdr = (struct iscsi_ecdb_ahdr *) (hdr + 1);
if (ecdb_ahdr->ahstype != ISCSI_AHSTYPE_CDB) {
pr_err("Additional Header Segment type %d not supported!\n",
@@ -1108,14 +1110,19 @@ int iscsit_setup_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
ISCSI_REASON_CMD_NOT_SUPPORTED, buf);
}
- cdb = kmalloc(be16_to_cpu(ecdb_ahdr->ahslength) + 15,
- GFP_KERNEL);
+ ahslength = be16_to_cpu(ecdb_ahdr->ahslength);
+ if (!ahslength) {
+ pr_err("Extended CDB AHS with zero length, protocol error.\n");
+ return iscsit_add_reject_cmd(cmd,
+ ISCSI_REASON_PROTOCOL_ERROR, buf);
+ }
+
+ cdb = kmalloc(ahslength + 15, GFP_KERNEL);
if (cdb == NULL)
return iscsit_add_reject_cmd(cmd,
ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
memcpy(cdb, hdr->cdb, ISCSI_CDB_SIZE);
- memcpy(cdb + ISCSI_CDB_SIZE, ecdb_ahdr->ecdb,
- be16_to_cpu(ecdb_ahdr->ahslength) - 1);
+ memcpy(cdb + ISCSI_CDB_SIZE, ecdb_ahdr->ecdb, ahslength - 1);
}
data_direction = (hdr->flags & ISCSI_FLAG_CMD_WRITE) ? DMA_TO_DEVICE :
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH] scsi: target: iscsi: reject zero-length Extended CDB AHS 2026-04-04 1:44 [PATCH] scsi: target: iscsi: reject zero-length Extended CDB AHS carlos.bilbao @ 2026-04-07 9:23 ` Dmitry Bogdanov 2026-04-09 2:23 ` Carlos Bilbao 2026-04-09 2:42 ` [PATCH v2] scsi: target: iscsi: reject invalid size " carlos.bilbao 1 sibling, 1 reply; 10+ messages in thread From: Dmitry Bogdanov @ 2026-04-07 9:23 UTC (permalink / raw) To: carlos.bilbao Cc: martin.petersen, kees, pabeni, mlombard, kuniyu, michael.christie, linux-scsi, target-devel, linux-kernel, bilbao On Fri, Apr 03, 2026 at 06:44:29PM -0700, carlos.bilbao@kernel.org wrote: > From: Carlos Bilbao <carlos.bilbao@kernel.org> > > If ecdb_ahdr->ahslength is zero, two bugs follow: > > kmalloc(be16_to_cpu(ecdb_ahdr->ahslength) + 15, ...) > > allocates 15 bytes, but the immediately following memcpy writes > ISCSI_CDB_SIZE (16) bytes into it, a one-byte heap overflow. Also: > > memcpy(cdb + ISCSI_CDB_SIZE, ecdb_ahdr->ecdb, > be16_to_cpu(ecdb_ahdr->ahslength) - 1); > > (u16)0 - 1 promotes to (int)-1 which converts to SIZE_MAX as size_t, > causing a massive out-of-bounds write. > > Reject ahslength == 0 with ISCSI_REASON_PROTOCOL_ERROR before the kmalloc. > > Fixes: 8f1f7d297bce ("scsi: target: iscsi: Add support for extended CDB AHS") > Signed-off-by: Carlos Bilbao (Lambda) <carlos.bilbao@kernel.org> > --- > drivers/target/iscsi/iscsi_target.c | 15 +++++++++++---- > 1 file changed, 11 insertions(+), 4 deletions(-) > > diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c > index e80449f6ce15..8db24d35c762 100644 > --- a/drivers/target/iscsi/iscsi_target.c > +++ b/drivers/target/iscsi/iscsi_target.c > @@ -1100,6 +1100,8 @@ int iscsit_setup_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd, > cdb = hdr->cdb; > > if (hdr->hlength) { > + u16 ahslength; > + > ecdb_ahdr = (struct iscsi_ecdb_ahdr *) (hdr + 1); > if (ecdb_ahdr->ahstype != ISCSI_AHSTYPE_CDB) { > pr_err("Additional Header Segment type %d not supported!\n", > @@ -1108,14 +1110,19 @@ int iscsit_setup_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd, > ISCSI_REASON_CMD_NOT_SUPPORTED, buf); > } > > - cdb = kmalloc(be16_to_cpu(ecdb_ahdr->ahslength) + 15, > - GFP_KERNEL); > + ahslength = be16_to_cpu(ecdb_ahdr->ahslength); > + if (!ahslength) { > + pr_err("Extended CDB AHS with zero length, protocol error.\n"); > + return iscsit_add_reject_cmd(cmd, > + ISCSI_REASON_PROTOCOL_ERROR, buf); > + } > + For a complete solution please add a check that AHS fits in the buffer. ahslength must be less or equal than ((hdr->hlength * 4) - 3). > + cdb = kmalloc(ahslength + 15, GFP_KERNEL); It took some time to recall what did 15 mean. May be make it clear for everyone too? u16 cdb_length = ahslength - 1 + ISCSI_CDB_SIZE; cdb = kmalloc(cdb_length, GFP_KERNEL); memcpy(cdb, hdr->cdb, ISCSI_CDB_SIZE); memcpy(cdb + ISCSI_CDB_SIZE, ecdb_ahdr->ecdb, cdb_length - ISCSI_CDB_SIZE); > if (cdb == NULL) > return iscsit_add_reject_cmd(cmd, > ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); > memcpy(cdb, hdr->cdb, ISCSI_CDB_SIZE); > - memcpy(cdb + ISCSI_CDB_SIZE, ecdb_ahdr->ecdb, > - be16_to_cpu(ecdb_ahdr->ahslength) - 1); > + memcpy(cdb + ISCSI_CDB_SIZE, ecdb_ahdr->ecdb, ahslength - 1); > } > > data_direction = (hdr->flags & ISCSI_FLAG_CMD_WRITE) ? DMA_TO_DEVICE : > -- > 2.43.0 > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] scsi: target: iscsi: reject zero-length Extended CDB AHS 2026-04-07 9:23 ` Dmitry Bogdanov @ 2026-04-09 2:23 ` Carlos Bilbao 0 siblings, 0 replies; 10+ messages in thread From: Carlos Bilbao @ 2026-04-09 2:23 UTC (permalink / raw) To: Dmitry Bogdanov, carlos.bilbao Cc: martin.petersen, kees, pabeni, mlombard, kuniyu, michael.christie, linux-scsi, target-devel, linux-kernel, bilbao Hello, On 4/7/26 02:23, Dmitry Bogdanov wrote: > On Fri, Apr 03, 2026 at 06:44:29PM -0700, carlos.bilbao@kernel.org wrote: >> From: Carlos Bilbao <carlos.bilbao@kernel.org> >> >> If ecdb_ahdr->ahslength is zero, two bugs follow: >> >> kmalloc(be16_to_cpu(ecdb_ahdr->ahslength) + 15, ...) >> >> allocates 15 bytes, but the immediately following memcpy writes >> ISCSI_CDB_SIZE (16) bytes into it, a one-byte heap overflow. Also: >> >> memcpy(cdb + ISCSI_CDB_SIZE, ecdb_ahdr->ecdb, >> be16_to_cpu(ecdb_ahdr->ahslength) - 1); >> >> (u16)0 - 1 promotes to (int)-1 which converts to SIZE_MAX as size_t, >> causing a massive out-of-bounds write. >> >> Reject ahslength == 0 with ISCSI_REASON_PROTOCOL_ERROR before the kmalloc. >> >> Fixes: 8f1f7d297bce ("scsi: target: iscsi: Add support for extended CDB AHS") >> Signed-off-by: Carlos Bilbao (Lambda) <carlos.bilbao@kernel.org> >> --- >> drivers/target/iscsi/iscsi_target.c | 15 +++++++++++---- >> 1 file changed, 11 insertions(+), 4 deletions(-) >> >> diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c >> index e80449f6ce15..8db24d35c762 100644 >> --- a/drivers/target/iscsi/iscsi_target.c >> +++ b/drivers/target/iscsi/iscsi_target.c >> @@ -1100,6 +1100,8 @@ int iscsit_setup_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd, >> cdb = hdr->cdb; >> >> if (hdr->hlength) { >> + u16 ahslength; >> + >> ecdb_ahdr = (struct iscsi_ecdb_ahdr *) (hdr + 1); >> if (ecdb_ahdr->ahstype != ISCSI_AHSTYPE_CDB) { >> pr_err("Additional Header Segment type %d not supported!\n", >> @@ -1108,14 +1110,19 @@ int iscsit_setup_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd, >> ISCSI_REASON_CMD_NOT_SUPPORTED, buf); >> } >> >> - cdb = kmalloc(be16_to_cpu(ecdb_ahdr->ahslength) + 15, >> - GFP_KERNEL); >> + ahslength = be16_to_cpu(ecdb_ahdr->ahslength); >> + if (!ahslength) { >> + pr_err("Extended CDB AHS with zero length, protocol error.\n"); >> + return iscsit_add_reject_cmd(cmd, >> + ISCSI_REASON_PROTOCOL_ERROR, buf); >> + } >> + > For a complete solution please add a check that AHS fits in the buffer. > ahslength must be less or equal than ((hdr->hlength * 4) - 3). For sure, I'll send a v2 including that. > >> + cdb = kmalloc(ahslength + 15, GFP_KERNEL); > It took some time to recall what did 15 mean. May be make it clear for > everyone too? > > u16 cdb_length = ahslength - 1 + ISCSI_CDB_SIZE; > cdb = kmalloc(cdb_length, GFP_KERNEL); > memcpy(cdb, hdr->cdb, ISCSI_CDB_SIZE); > memcpy(cdb + ISCSI_CDB_SIZE, ecdb_ahdr->ecdb, cdb_length - ISCSI_CDB_SIZE); > Agreed! >> if (cdb == NULL) >> return iscsit_add_reject_cmd(cmd, >> ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); >> memcpy(cdb, hdr->cdb, ISCSI_CDB_SIZE); >> - memcpy(cdb + ISCSI_CDB_SIZE, ecdb_ahdr->ecdb, >> - be16_to_cpu(ecdb_ahdr->ahslength) - 1); >> + memcpy(cdb + ISCSI_CDB_SIZE, ecdb_ahdr->ecdb, ahslength - 1); >> } >> >> data_direction = (hdr->flags & ISCSI_FLAG_CMD_WRITE) ? DMA_TO_DEVICE : >> -- >> 2.43.0 >> Thanks, Carlos ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2] scsi: target: iscsi: reject invalid size Extended CDB AHS 2026-04-04 1:44 [PATCH] scsi: target: iscsi: reject zero-length Extended CDB AHS carlos.bilbao 2026-04-07 9:23 ` Dmitry Bogdanov @ 2026-04-09 2:42 ` carlos.bilbao 2026-04-09 9:31 ` Dmitry Bogdanov 1 sibling, 1 reply; 10+ messages in thread From: carlos.bilbao @ 2026-04-09 2:42 UTC (permalink / raw) To: d.bogdanov Cc: bilbao, martin.petersen, kees, linux-kernel, linux-scsi, Carlos Bilbao From: Carlos Bilbao <carlos.bilbao@kernel.org> If ecdb_ahdr->ahslength is zero, two bugs follow: kmalloc(be16_to_cpu(ecdb_ahdr->ahslength) + 15, ...) allocates 15 bytes, but the immediately following memcpy writes ISCSI_CDB_SIZE (16) bytes into it, a one-byte heap overflow. Also: memcpy(cdb + ISCSI_CDB_SIZE, ecdb_ahdr->ecdb, be16_to_cpu(ecdb_ahdr->ahslength) - 1); (u16)0 - 1 promotes to (int)-1 which converts to SIZE_MAX as size_t, causing a massive out-of-bounds write. Reject ahslength == 0 with ISCSI_REASON_PROTOCOL_ERROR before the kmalloc. Also reject ahslength values that exceed the actual AHS buffer advertised. Changes in v2: - Add bounds check: ahslength must not exceed (hdr->hlength * 4) - 3. - Replace opaque ahslength + 15 with explicit cdb_length variable. Fixes: 8f1f7d297bce ("scsi: target: iscsi: Add support for extended CDB AHS") Signed-off-by: Carlos Bilbao (Lambda) <carlos.bilbao@kernel.org> --- drivers/target/iscsi/iscsi_target.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index e80449f6ce15..1a492965ebdf 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -1100,6 +1100,8 @@ int iscsit_setup_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd, cdb = hdr->cdb; if (hdr->hlength) { + u16 ahslength; + ecdb_ahdr = (struct iscsi_ecdb_ahdr *) (hdr + 1); if (ecdb_ahdr->ahstype != ISCSI_AHSTYPE_CDB) { pr_err("Additional Header Segment type %d not supported!\n", @@ -1108,14 +1110,27 @@ int iscsit_setup_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd, ISCSI_REASON_CMD_NOT_SUPPORTED, buf); } - cdb = kmalloc(be16_to_cpu(ecdb_ahdr->ahslength) + 15, - GFP_KERNEL); + ahslength = be16_to_cpu(ecdb_ahdr->ahslength); + if (!ahslength) { + pr_err("Extended CDB AHS with zero length, protocol error.\n"); + return iscsit_add_reject_cmd(cmd, + ISCSI_REASON_PROTOCOL_ERROR, buf); + } + if (ahslength > (hdr->hlength * 4) - 3) { + pr_err("Extended CDB AHS length %u exceeds available buffer.\n", + ahslength); + return iscsit_add_reject_cmd(cmd, + ISCSI_REASON_PROTOCOL_ERROR, buf); + } + + u16 cdb_length = ahslength - 1 + ISCSI_CDB_SIZE; + + cdb = kmalloc(cdb_length, GFP_KERNEL); if (cdb == NULL) return iscsit_add_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); memcpy(cdb, hdr->cdb, ISCSI_CDB_SIZE); - memcpy(cdb + ISCSI_CDB_SIZE, ecdb_ahdr->ecdb, - be16_to_cpu(ecdb_ahdr->ahslength) - 1); + memcpy(cdb + ISCSI_CDB_SIZE, ecdb_ahdr->ecdb, cdb_length - ISCSI_CDB_SIZE); } data_direction = (hdr->flags & ISCSI_FLAG_CMD_WRITE) ? DMA_TO_DEVICE : -- 2.43.0 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v2] scsi: target: iscsi: reject invalid size Extended CDB AHS 2026-04-09 2:42 ` [PATCH v2] scsi: target: iscsi: reject invalid size " carlos.bilbao @ 2026-04-09 9:31 ` Dmitry Bogdanov 2026-04-10 2:49 ` Carlos Bilbao 0 siblings, 1 reply; 10+ messages in thread From: Dmitry Bogdanov @ 2026-04-09 9:31 UTC (permalink / raw) To: carlos.bilbao; +Cc: bilbao, martin.petersen, kees, linux-kernel, linux-scsi On Wed, Apr 08, 2026 at 07:42:53PM -0700, carlos.bilbao@kernel.org wrote: > > From: Carlos Bilbao <carlos.bilbao@kernel.org> > > If ecdb_ahdr->ahslength is zero, two bugs follow: > > kmalloc(be16_to_cpu(ecdb_ahdr->ahslength) + 15, ...) > > allocates 15 bytes, but the immediately following memcpy writes > ISCSI_CDB_SIZE (16) bytes into it, a one-byte heap overflow. Also: > > memcpy(cdb + ISCSI_CDB_SIZE, ecdb_ahdr->ecdb, > be16_to_cpu(ecdb_ahdr->ahslength) - 1); > > (u16)0 - 1 promotes to (int)-1 which converts to SIZE_MAX as size_t, > causing a massive out-of-bounds write. > > Reject ahslength == 0 with ISCSI_REASON_PROTOCOL_ERROR before the kmalloc. > Also reject ahslength values that exceed the actual AHS buffer advertised. > > Changes in v2: > > - Add bounds check: ahslength must not exceed (hdr->hlength * 4) - 3. > - Replace opaque ahslength + 15 with explicit cdb_length variable. > > Fixes: 8f1f7d297bce ("scsi: target: iscsi: Add support for extended CDB AHS") > Signed-off-by: Carlos Bilbao (Lambda) <carlos.bilbao@kernel.org> Reviewed-by: Dmitry Bogdanov <d.bogdanov@yadro.com> > --- > drivers/target/iscsi/iscsi_target.c | 23 +++++++++++++++++++---- > 1 file changed, 19 insertions(+), 4 deletions(-) > > diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c > index e80449f6ce15..1a492965ebdf 100644 > --- a/drivers/target/iscsi/iscsi_target.c > +++ b/drivers/target/iscsi/iscsi_target.c > @@ -1100,6 +1100,8 @@ int iscsit_setup_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd, > cdb = hdr->cdb; > > if (hdr->hlength) { > + u16 ahslength; > + > ecdb_ahdr = (struct iscsi_ecdb_ahdr *) (hdr + 1); > if (ecdb_ahdr->ahstype != ISCSI_AHSTYPE_CDB) { > pr_err("Additional Header Segment type %d not supported!\n", > @@ -1108,14 +1110,27 @@ int iscsit_setup_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd, > ISCSI_REASON_CMD_NOT_SUPPORTED, buf); > } > > - cdb = kmalloc(be16_to_cpu(ecdb_ahdr->ahslength) + 15, > - GFP_KERNEL); > + ahslength = be16_to_cpu(ecdb_ahdr->ahslength); > + if (!ahslength) { > + pr_err("Extended CDB AHS with zero length, protocol error.\n"); > + return iscsit_add_reject_cmd(cmd, > + ISCSI_REASON_PROTOCOL_ERROR, buf); > + } > + if (ahslength > (hdr->hlength * 4) - 3) { > + pr_err("Extended CDB AHS length %u exceeds available buffer.\n", > + ahslength); > + return iscsit_add_reject_cmd(cmd, > + ISCSI_REASON_PROTOCOL_ERROR, buf); > + } > + > + u16 cdb_length = ahslength - 1 + ISCSI_CDB_SIZE; AFAIK, a variable declarationis allowed to be in the beginning of code block only. > + > + cdb = kmalloc(cdb_length, GFP_KERNEL); > if (cdb == NULL) > return iscsit_add_reject_cmd(cmd, > ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); > memcpy(cdb, hdr->cdb, ISCSI_CDB_SIZE); > - memcpy(cdb + ISCSI_CDB_SIZE, ecdb_ahdr->ecdb, > - be16_to_cpu(ecdb_ahdr->ahslength) - 1); > + memcpy(cdb + ISCSI_CDB_SIZE, ecdb_ahdr->ecdb, cdb_length - ISCSI_CDB_SIZE); > } > > data_direction = (hdr->flags & ISCSI_FLAG_CMD_WRITE) ? DMA_TO_DEVICE : > -- > 2.43.0 > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2] scsi: target: iscsi: reject invalid size Extended CDB AHS 2026-04-09 9:31 ` Dmitry Bogdanov @ 2026-04-10 2:49 ` Carlos Bilbao 2026-04-14 2:36 ` Martin K. Petersen 0 siblings, 1 reply; 10+ messages in thread From: Carlos Bilbao @ 2026-04-10 2:49 UTC (permalink / raw) To: Dmitry Bogdanov, carlos.bilbao Cc: bilbao, martin.petersen, kees, linux-kernel, linux-scsi Hello, On 4/9/26 02:31, Dmitry Bogdanov wrote: > On Wed, Apr 08, 2026 at 07:42:53PM -0700, carlos.bilbao@kernel.org wrote: >> From: Carlos Bilbao <carlos.bilbao@kernel.org> >> >> If ecdb_ahdr->ahslength is zero, two bugs follow: >> >> kmalloc(be16_to_cpu(ecdb_ahdr->ahslength) + 15, ...) >> >> allocates 15 bytes, but the immediately following memcpy writes >> ISCSI_CDB_SIZE (16) bytes into it, a one-byte heap overflow. Also: >> >> memcpy(cdb + ISCSI_CDB_SIZE, ecdb_ahdr->ecdb, >> be16_to_cpu(ecdb_ahdr->ahslength) - 1); >> >> (u16)0 - 1 promotes to (int)-1 which converts to SIZE_MAX as size_t, >> causing a massive out-of-bounds write. >> >> Reject ahslength == 0 with ISCSI_REASON_PROTOCOL_ERROR before the kmalloc. >> Also reject ahslength values that exceed the actual AHS buffer advertised. >> >> Changes in v2: >> >> - Add bounds check: ahslength must not exceed (hdr->hlength * 4) - 3. >> - Replace opaque ahslength + 15 with explicit cdb_length variable. >> >> Fixes: 8f1f7d297bce ("scsi: target: iscsi: Add support for extended CDB AHS") >> Signed-off-by: Carlos Bilbao (Lambda) <carlos.bilbao@kernel.org> > Reviewed-by: Dmitry Bogdanov <d.bogdanov@yadro.com> > >> --- >> drivers/target/iscsi/iscsi_target.c | 23 +++++++++++++++++++---- >> 1 file changed, 19 insertions(+), 4 deletions(-) >> >> diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c >> index e80449f6ce15..1a492965ebdf 100644 >> --- a/drivers/target/iscsi/iscsi_target.c >> +++ b/drivers/target/iscsi/iscsi_target.c >> @@ -1100,6 +1100,8 @@ int iscsit_setup_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd, >> cdb = hdr->cdb; >> >> if (hdr->hlength) { >> + u16 ahslength; >> + >> ecdb_ahdr = (struct iscsi_ecdb_ahdr *) (hdr + 1); >> if (ecdb_ahdr->ahstype != ISCSI_AHSTYPE_CDB) { >> pr_err("Additional Header Segment type %d not supported!\n", >> @@ -1108,14 +1110,27 @@ int iscsit_setup_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd, >> ISCSI_REASON_CMD_NOT_SUPPORTED, buf); >> } >> >> - cdb = kmalloc(be16_to_cpu(ecdb_ahdr->ahslength) + 15, >> - GFP_KERNEL); >> + ahslength = be16_to_cpu(ecdb_ahdr->ahslength); >> + if (!ahslength) { >> + pr_err("Extended CDB AHS with zero length, protocol error.\n"); >> + return iscsit_add_reject_cmd(cmd, >> + ISCSI_REASON_PROTOCOL_ERROR, buf); >> + } >> + if (ahslength > (hdr->hlength * 4) - 3) { >> + pr_err("Extended CDB AHS length %u exceeds available buffer.\n", >> + ahslength); >> + return iscsit_add_reject_cmd(cmd, >> + ISCSI_REASON_PROTOCOL_ERROR, buf); >> + } >> + >> + u16 cdb_length = ahslength - 1 + ISCSI_CDB_SIZE; > AFAIK, a variable declarationis allowed to be in the beginning of code block only. You're absolutely right, happy to send v3 if the maintainer prefers. > >> + >> + cdb = kmalloc(cdb_length, GFP_KERNEL); >> if (cdb == NULL) >> return iscsit_add_reject_cmd(cmd, >> ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); >> memcpy(cdb, hdr->cdb, ISCSI_CDB_SIZE); >> - memcpy(cdb + ISCSI_CDB_SIZE, ecdb_ahdr->ecdb, >> - be16_to_cpu(ecdb_ahdr->ahslength) - 1); >> + memcpy(cdb + ISCSI_CDB_SIZE, ecdb_ahdr->ecdb, cdb_length - ISCSI_CDB_SIZE); >> } >> >> data_direction = (hdr->flags & ISCSI_FLAG_CMD_WRITE) ? DMA_TO_DEVICE : >> -- >> 2.43.0 >> Thanks, Carlos ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2] scsi: target: iscsi: reject invalid size Extended CDB AHS 2026-04-10 2:49 ` Carlos Bilbao @ 2026-04-14 2:36 ` Martin K. Petersen 2026-04-15 4:07 ` [PATCH v3] " Carlos Bilbao (Lambda) 2026-04-15 4:08 ` [PATCH v2] " Carlos Bilbao 0 siblings, 2 replies; 10+ messages in thread From: Martin K. Petersen @ 2026-04-14 2:36 UTC (permalink / raw) To: Carlos Bilbao Cc: Dmitry Bogdanov, carlos.bilbao, bilbao, martin.petersen, kees, linux-kernel, linux-scsi Carlos, >>> + u16 cdb_length = ahslength - 1 + ISCSI_CDB_SIZE; >> AFAIK, a variable declarationis allowed to be in the beginning of code block only. > > You're absolutely right, happy to send v3 if the maintainer prefers. Yes, please. Best to stay consistent with the existing coding style in a given file. -- Martin K. Petersen ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3] scsi: target: iscsi: reject invalid size Extended CDB AHS 2026-04-14 2:36 ` Martin K. Petersen @ 2026-04-15 4:07 ` Carlos Bilbao (Lambda) 2026-04-22 1:11 ` Martin K. Petersen 2026-04-15 4:08 ` [PATCH v2] " Carlos Bilbao 1 sibling, 1 reply; 10+ messages in thread From: Carlos Bilbao (Lambda) @ 2026-04-15 4:07 UTC (permalink / raw) To: martin.petersen, kees, d.bogdanov Cc: pabeni, mlombard, kuniyu, michael.christie, linux-scsi, target-devel, linux-kernel, bilbao, Carlos Bilbao From: Carlos Bilbao <carlos.bilbao@kernel.org> If ecdb_ahdr->ahslength is zero, two bugs follow: kmalloc(be16_to_cpu(ecdb_ahdr->ahslength) + 15, ...) allocates 15 bytes, but the immediately following memcpy writes ISCSI_CDB_SIZE (16) bytes into it, a one-byte heap overflow. Also: memcpy(cdb + ISCSI_CDB_SIZE, ecdb_ahdr->ecdb, be16_to_cpu(ecdb_ahdr->ahslength) - 1); (u16)0 - 1 promotes to (int)-1 which converts to SIZE_MAX as size_t, causing a massive out-of-bounds write. Reject ahslength == 0 with ISCSI_REASON_PROTOCOL_ERROR before the kmalloc. Also reject ahslength values that exceed the actual AHS buffer advertised. Fixes: 8f1f7d297bce ("scsi: target: iscsi: Add support for extended CDB AHS") Signed-off-by: Carlos Bilbao (Lambda) <carlos.bilbao@kernel.org> Reviewed-by: Dmitry Bogdanov <d.bogdanov@yadro.com> Changes in v3: - Move ahslength and cdb_length declarations to function scope following the reverse christmas tree ordering of existing locals. Changes in v2: - Add bounds check: ahslength must not exceed (hdr->hlength * 4) - 3. - Replace opaque ahslength + 15 with explicit cdb_length variable. --- drivers/target/iscsi/iscsi_target.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index e80449f6ce15..cb832fd523af 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -995,6 +995,7 @@ int iscsit_setup_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd, int data_direction, payload_length; struct iscsi_ecdb_ahdr *ecdb_ahdr; struct iscsi_scsi_req *hdr; + u16 ahslength, cdb_length; int iscsi_task_attr; unsigned char *cdb; int sam_task_attr; @@ -1108,14 +1109,27 @@ int iscsit_setup_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd, ISCSI_REASON_CMD_NOT_SUPPORTED, buf); } - cdb = kmalloc(be16_to_cpu(ecdb_ahdr->ahslength) + 15, - GFP_KERNEL); + ahslength = be16_to_cpu(ecdb_ahdr->ahslength); + if (!ahslength) { + pr_err("Extended CDB AHS with zero length, protocol error.\n"); + return iscsit_add_reject_cmd(cmd, + ISCSI_REASON_PROTOCOL_ERROR, buf); + } + if (ahslength > (hdr->hlength * 4) - 3) { + pr_err("Extended CDB AHS length %u exceeds available PDU buffer.\n", + ahslength); + return iscsit_add_reject_cmd(cmd, + ISCSI_REASON_PROTOCOL_ERROR, buf); + } + + cdb_length = ahslength - 1 + ISCSI_CDB_SIZE; + + cdb = kmalloc(cdb_length, GFP_KERNEL); if (cdb == NULL) return iscsit_add_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf); memcpy(cdb, hdr->cdb, ISCSI_CDB_SIZE); - memcpy(cdb + ISCSI_CDB_SIZE, ecdb_ahdr->ecdb, - be16_to_cpu(ecdb_ahdr->ahslength) - 1); + memcpy(cdb + ISCSI_CDB_SIZE, ecdb_ahdr->ecdb, cdb_length - ISCSI_CDB_SIZE); } data_direction = (hdr->flags & ISCSI_FLAG_CMD_WRITE) ? DMA_TO_DEVICE : -- 2.43.0 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v3] scsi: target: iscsi: reject invalid size Extended CDB AHS 2026-04-15 4:07 ` [PATCH v3] " Carlos Bilbao (Lambda) @ 2026-04-22 1:11 ` Martin K. Petersen 0 siblings, 0 replies; 10+ messages in thread From: Martin K. Petersen @ 2026-04-22 1:11 UTC (permalink / raw) To: Carlos Bilbao (Lambda) Cc: martin.petersen, kees, pabeni, mlombard, kuniyu, michael.christie, linux-scsi, target-devel, linux-kernel, bilbao Carlos, > If ecdb_ahdr->ahslength is zero, two bugs follow: > > kmalloc(be16_to_cpu(ecdb_ahdr->ahslength) + 15, ...) > > allocates 15 bytes, but the immediately following memcpy writes > ISCSI_CDB_SIZE (16) bytes into it, a one-byte heap overflow. Also: Applied to 7.1/scsi-staging, thanks! -- Martin K. Petersen ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2] scsi: target: iscsi: reject invalid size Extended CDB AHS 2026-04-14 2:36 ` Martin K. Petersen 2026-04-15 4:07 ` [PATCH v3] " Carlos Bilbao (Lambda) @ 2026-04-15 4:08 ` Carlos Bilbao 1 sibling, 0 replies; 10+ messages in thread From: Carlos Bilbao @ 2026-04-15 4:08 UTC (permalink / raw) To: Martin K. Petersen, Carlos Bilbao Cc: Dmitry Bogdanov, carlos.bilbao, kees, linux-kernel, linux-scsi On 4/13/26 19:36, Martin K. Petersen wrote: > Carlos, > >>>> + u16 cdb_length = ahslength - 1 + ISCSI_CDB_SIZE; >>> AFAIK, a variable declarationis allowed to be in the beginning of code block only. >> You're absolutely right, happy to send v3 if the maintainer prefers. > Yes, please. Best to stay consistent with the existing coding style in a > given file. Sure, v3 sent! > Thanks, Carlos ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-04-22 1:11 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-04-04 1:44 [PATCH] scsi: target: iscsi: reject zero-length Extended CDB AHS carlos.bilbao 2026-04-07 9:23 ` Dmitry Bogdanov 2026-04-09 2:23 ` Carlos Bilbao 2026-04-09 2:42 ` [PATCH v2] scsi: target: iscsi: reject invalid size " carlos.bilbao 2026-04-09 9:31 ` Dmitry Bogdanov 2026-04-10 2:49 ` Carlos Bilbao 2026-04-14 2:36 ` Martin K. Petersen 2026-04-15 4:07 ` [PATCH v3] " Carlos Bilbao (Lambda) 2026-04-22 1:11 ` Martin K. Petersen 2026-04-15 4:08 ` [PATCH v2] " Carlos Bilbao
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox