[PATCH] scsi: target: bound VPD identifier formatting
Mark Amirkan via B4 Relay <[email protected]>
| Newsgroups | org.kernel.vger.target-devel,org.kernel.feeds.b4-sent,org.kernel.vger.linux-kernel,org.kernel.vger.linux-scsi |
|---|---|
| Message-ID | <[email protected]> |
From: Mark Amirkan <[email protected]> transport_set_vpd_ident() formats device-provided VPD page 0x83 identifiers into the 254-byte t10_vpd::device_identifier array without checking whether the result fits. A binary identifier emits one type character followed by two hexadecimal characters per input byte. A 148-byte identifier therefore emits 297 characters, eventually writing beyond the 296-byte t10_vpd allocation. Reject binary identifiers longer than 126 bytes and apply the equivalent destination bound to ASCII and UTF-8 identifiers. Explicitly terminate accepted identifiers. Rejecting instead of truncating avoids creating a false device identity. The write was reproduced with generic KASAN on arm64 Linux 7.2-rc7 using a complete 168-byte VPD response. With the same input, the fixed kernel retains the valid NAA descriptor, skips the 148-byte vendor-specific descriptor, enables the pSCSI backstore, and produces no KASAN report. Seven boundary tests pass. The demonstrated path requires a device-provided response and privileged pSCSI configuration. No claim is made about exploitability or unprivileged reachability. The tested source reproducer is available privately on request. Fixes: c66ac9db8d4a ("[SCSI] target: Add LIO target core v4.0.0-rc6") Cc: [email protected] Assisted-by: Codex:gpt-5.6 Signed-off-by: Mark Amirkan <[email protected]> --- drivers/target/target_core_transport.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index dcfe9459..26a0bb66 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1335,6 +1335,14 @@ transport_set_vpd_ident(struct t10_vpd *vpd, unsigned char *page_83) vpd->device_identifier_code_set = (page_83[0] & 0x0f); switch (vpd->device_identifier_code_set) { case 0x01: /* Binary */ + /* + * Reserve one character for the type and one for the NUL; + * each binary byte expands to two hex characters. + */ + if (page_83[3] > + (sizeof(vpd->device_identifier) - 2) / 2) + return -EINVAL; + vpd->device_identifier[j++] = hex_str[vpd->device_identifier_type]; while (i < (4 + page_83[3])) { @@ -1344,11 +1352,16 @@ transport_set_vpd_ident(struct t10_vpd *vpd, unsigned char *page_83) hex_str[page_83[i] & 0x0f]; i++; } + vpd->device_identifier[j] = '\0'; break; case 0x02: /* ASCII */ case 0x03: /* UTF-8 */ + if (page_83[3] >= sizeof(vpd->device_identifier)) + return -EINVAL; + while (i < (4 + page_83[3])) vpd->device_identifier[j++] = page_83[i++]; + vpd->device_identifier[j] = '\0'; break; default: break; --- base-commit: 3a0dd7ba4f44cdc116d83712f61e7c1a95be3588 change-id: 20260818-pscsi-vpd-ident-bounds-b5ffb129754d Best regards, -- Mark Amirkan <[email protected]>