Look up another CVE · open CVE-2026-90414 in the interactive tracker
CVE-2026-90414
IB/isert: reject PDUs declaring more data than was received
Published 2026-09-17 (31 days ago) by the Linux kernel CNA. Subsystem drivers/infiniband. Debian urgency: not yet assigned.
What to do, per Debian release
Debian's own status for CVE-2026-90414 in every release this site tracks, and what each one means in practice. Every status below is the one the Debian Security Team publishes for this CVE. source
| Release | Status | Version | What this means |
|---|---|---|---|
| Debian 12bookworm | fixedDLA-4841-1 · 2026-10-17 · text | 6.1.190-1 | Update the kernel and reboot. DLA-4841-1 shipped the fix on 2026-10-17, in 6.1.190-1. A running kernel keeps the old code until the machine restarts. |
| Debian 13trixie | fixedDSA-6528-1 · 2026-09-29 · text | 6.12.111-1 | Update the kernel and reboot. DSA-6528-1 shipped the fix on 2026-09-29, in 6.12.111-1. A running kernel keeps the old code until the machine restarts. |
| Debian 14forky | fixed | 7.2.6-1 | Update the kernel and reboot. Fixed in 7.2.6-1. A running kernel keeps the old code until the machine restarts. |
| Debian unstablesid | fixed | 7.2.6-1 | Update the kernel and reboot. Fixed in 7.2.6-1. A running kernel keeps the old code until the machine restarts. |
| Debian 12bookworm · linux-6.12 | fixedDLA-4817-1 · 2026-10-04 · text | 6.12.111-1~deb12u1 | Update the kernel and reboot. DLA-4817-1 shipped the fix on 2026-10-04, in 6.12.111-1~deb12u1. A running kernel keeps the old code until the machine restarts. |
The vulnerability
What the bug is
isert_recv_done() hands each received PDU to the opcode handlers without ever looking at wc->byte_len, the number of bytes the HCA actually placed in the receive descriptor. The handlers then copy that many bytes - the data-segment length the initiator declared in the BHS (ntoh24(hdr->dlength), via the derived unsol_data_len / imm_data_len) - out of the fixed-size descriptor: isert_handle_iscsi_dataout(): sg_copy_from_buffer(sg_start, sg_nents, isert_get_data(rx_desc), unsol_data_len); isert_handle_scsi_cmd(): sg_copy_from_buffer(cmd->se_cmd.t_data_sg, sg_nents, isert_get_data(rx_desc), imm_data_len); Because the declared length is never checked against wc->byte_len, an initiator can declare a data segment larger than the bytes it actually sent (and larger than the descriptor) and cause an out-of-bounds read of the receive buffer. Nothing upstream of isert closes this door: - __iscsit_check_dataout_hdr() bounds the inbound payload against conn_ops->MaxXmitDataSegmentLength (MXDSL) - a transmit parameter, used here for the inbound check. - iscsi_set_connection_parameters() sets ops->MaxXmitDataSegmentLength = ops->TargetRecvDataSegmentLength; and TARGETRECVDATASEGMENTLENGTH is absent from the min()-clamp list in iscsi_check_acceptor_state(), so the value the initiator declares is adopted verbatim (type range 512..16777215). The initiator effectively raises its own ceiling. - isert never clamps the negotiated value to its own fixed receive descriptor (ISER_RX_SIZE, 9216 bytes), so the target core's bound and the descriptor size are unrelated. The imm_data_len == data_len path is more than an over-read: it aliases the receive descriptor via sg_set_buf() and passes it to the backend as the data source for the SCSI WRITE, so an over-declared length causes heap contents past the descriptor to be written through the backend to the backing store. The backend is the victim of the oversized scatterlist isert hands it, not the cause; no read-back of the written bytes was demonstrated. Trigger: after login completes (full feature phase), an initiator that has declared a large TargetRecvDataSegmentLength and a FirstBurstLength that permits unsolicited/immediate data sends a PDU whose declared data-segment length exceeds what was received. With KASAN: BUG: KASAN: slab-out-of-bounds in sg_copy_buffer+0x150/0x1c0 Read of size 4096 at addr ffff888109720800 by task kworker/1:0H/25 Workqueue: ib-comp-wq ib_cq_poll_work Call Trace: sg_copy_buffer+0x150/0x1c0 isert_recv_done+0xba6/0x2390 __ib_process_cq+0xe1/0x390 ib_cq_poll_work+0x46/0x150 isert_recv_done+0xba6 resolves to isert_handle_iscsi_dataout() (ib_isert.c:1160), inlined through isert_rx_opcode(). Validate wc->byte_len against the framing in isert_recv_done() before the PDU reaches any handler, and reinstate the connection if it is short. Because the test compares without subtracting the header length, it also rejects PDUs shorter than the iSER and iSCSI headers, which would otherwise be parsed out of stale descriptor contents. The login handler rejects PDUs shorter than ISER_HEADERS_LEN (commit 29e7b925ae6d ("IB/isert: Reject login PDUs shorter than ISER_HEADERS_LEN")) but does not bound the declared length either; that is fixed in the next patch. The data handlers had no length check at all. isert reads the data segment from a fixed offset: isert_get_data() returns the iSER header plus ISER_HEADERS_LEN and makes no adjustment for an AHS. The bytes the handlers touch are therefore exactly [ISER_HEADERS_LEN, ISER_HEADERS_LEN + dlength), and comparing that sum against wc->byte_len bounds precisely the region that is read. An AHS term would only make the test stricter without bounding anything furth ---truncated---
Where it lives
The fix touches these files. If the subsystem is one you do not use, the practical exposure is lower, though the package is still the vulnerable one.
drivers/infiniband/ulp/isert/ib_isert.c
- What this is
- ISCSI EXTENSIONS FOR RDMA (ISER) TARGETMAINTAINERS section matched on drivers/infiniband/ulp/isert · linux-rdma@vger.kernel.org · Supported
- Kernel module
- ib_isert
Check it on the machine
grep -wE 'CONFIG_INFINIBAND|CONFIG_INFINIBAND_ISERT' /boot/config-$(uname -r)Reads the booted kernel's own configuration, on the machine and nowhere else. =y is built in, =m is a module, and an is not set line means the code is not there.
lsmod | grep -w ib_isertPrints a line if that module is loaded right now, and nothing if it is not. One that is not loaded can still be loaded later by anything that needs it.
Show whether Debian builds this, per release
Debian builds this, but not on every flavour. At least one release below builds the code on some of its kernel flavours and not on others, so the answer depends on the architecture and flavour installed.
- bookworm, trixie, forky, sid, bookworm · linux-6.12Mnot built on amd64/cloud-amd64, arm64/cloud-arm64
- M
- a module where it is built at all; some flavours do not build it
- Build switches
- CONFIG_INFINIBAND, CONFIG_INFINIBAND_ISERT
- Reads as
- all on means the file is compiled; any one off means it is not.
From the configuration Debian publishes for every kernel flavour it builds. It covers only the architectures Debian ships a linux-config package for, and nothing about a kernel you built yourself. Debian's own status above stays authoritative about the source package.MAINTAINERS kbuild Makefiles Debian linux-config packages
Signals
- Published
- 2026-09-17 (31 days ago)source
- CVSS
- 9.1 critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:Hsource recompute it - Attack vector
- network (AV:N)source
- EPSS
- 0.51%, higher than 42.5% of all CVEssource
- CISA KEV
- not listedthe KEV catalogue
- Debian urgency
- not yet assignedsource
- Subsystem
- drivers/infiniband
Upstream fixes
The versions the CNA records as introducing and fixing this, and the commit for each. source
| Introduced | Fixed in | Commit |
|---|---|---|
| 3.10 | 5.10.270 | b4706722ed3e |
| 3.10 | 5.15.221 | bc58e9d3dc56 |
| 3.10 | 6.1.188 | 274b1ad7e783 |
| 3.10 | 6.6.157 | 2a6b8f88fb7e |
| 3.10 | 6.12.110 | 39da0b7e1f53 |
| 3.10 | 6.18.52 | cf36fa5357a2 |
| 3.10 | 7.2.6 | 352dc85324b2 |
| 3.10 | 7.3 | 957f92ea4022 |
Debian advisories
| Advisory | Date | Shipped to | Debian |
|---|---|---|---|
| DLA-4841-1 | 2026-10-17 | bookworm 6.1.190-1 | tracker |
| DLA-4817-1 | 2026-10-04 | bookworm 6.12.111-1~deb12u1 | tracker |
| DSA-6528-1 | 2026-09-29 | trixie 6.12.111-1 | tracker |
Why the CNA scored it this way
Quoted from the kernel CNA's own scoring file, word for word. A highlighted metric carries the most severe value CVSS v3.1 defines for it, which is what pushes the score up. source
- AV:NAttack vector, network
- The attacker-controlled length is ntoh24(hdr->dlength) in the iSCSI BHS of an RDMA SEND consumed by isert_recv_done(); isert_handle_iscsi_dataout(), isert_handle_scsi_cmd() and isert_handle_text_cmd() then copy that many bytes from the receive descriptor. ib_isert listens via rdma_bind_addr()/rdma_listen() on RDMA_PS_TCP (RoCEv2/iWARP), so that PDU is supplied by a remote initiator on a routable IP fabric.
- AC:LAttack complexity, low
- After login the initiator sends a PDU whose BHS dlength exceeds wc->byte_len. isert_handle_text_cmd() memcpy()s that length from isert_get_data(rx_desc), and isert_handle_iscsi_dataout()/isert_handle_scsi_cmd() pass it to sg_copy_from_buffer(); on a Normal session the initiator also raises TargetRecvDataSegmentLength, which iscsi_check_acceptor_state() adopts as MaxXmitDataSegmentLength. No race is involved.
- PR:NPrivileges required, none
- isert_recv_done() runs in full-feature phase, but iscsit_load_discovery_tpg() defaults discovery_tpg authentication=0 (AuthMethod=CHAP,None). iscsi_target_locate_portal() attaches that TPG for SessionType=Discovery on the isert NP, and isert_rx_opcode() then delivers ISCSI_OP_TEXT to isert_handle_text_cmd() with no credentials.
- UI:NUser interaction, none
- The remote initiator completes iSER login and posts the malformed PDU; ib_cq_poll_work on ib-comp-wq invokes isert_recv_done() with no local user or administrator action.
- S:UScope, unchanged
- The heap over-read and oops stay in the host kernel that implements ib_isert and LIO; this is not a guest-to-host, IOMMU, or other cross-authority impact.
- C:HConfidentiality impact, high
- isert_handle_text_cmd() memcpy()s ntoh24(dlength) bytes from isert_get_data() inside the 9216-byte iser_rx_desc.buf; discovery MaxXmitDataSegmentLength defaults to 262144 and a Normal session can raise TargetRecvDataSegmentLength to 16MB, so the copy over-reads far past the descriptor. isert_handle_scsi_cmd() sg_set_buf() can also feed those heap bytes to a SCSI WRITE.
- I:NIntegrity impact, none
- sg_copy_from_buffer() and the text memcpy read from the receive descriptor into a destination sized for the declared length (t_data_sg from transport_generic_new_cmd(), or kzalloc(payload_length)); they do not write past kernel objects. sg_set_buf() only over-reads heap as the SCSI WRITE source.
- A:HAvailability impact, high
- Copying 256KB or more from a fixed ISER_RX_SIZE (9216) descriptor is a slab-out-of-bounds read; the commit's KASAN report is BUG in sg_copy_buffer from isert_handle_iscsi_dataout(), and an over-read that leaves the rx_descs allocation oopses the target.