CVE-2026-63888

Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
19/07/2026
Last modified:
27/07/2026

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> scsi: target: iscsi: Fix CRC overread and double-free in iscsit_handle_text_cmd()<br /> <br /> Two latent bugs in the Text-phase handler, both present since the<br /> original LIO integration in commit e48354ce078c ("iscsi-target: Add<br /> iSCSI fabric support for target v4.1"):<br /> <br /> 1) DataDigest CRC buffer overread (4 bytes past text_in).<br /> <br /> text_in is kzalloc()&amp;#39;d at ALIGN(payload_length, 4). rx_size is then<br /> incremented by ISCSI_CRC_LEN to make room for the received DataDigest<br /> in the iovec, but the same (now-bumped) rx_size is passed as the<br /> buffer length to iscsit_crc_buf():<br /> <br /> if (conn-&gt;conn_ops-&gt;DataDigest) {<br /> ...<br /> rx_size += ISCSI_CRC_LEN;<br /> }<br /> ...<br /> if (conn-&gt;conn_ops-&gt;DataDigest) {<br /> data_crc = iscsit_crc_buf(text_in, rx_size, 0, NULL);<br /> <br /> iscsit_crc_buf() walks rx_size bytes of text_in with crc32c(), so<br /> when DataDigest is negotiated it reads 4 bytes past the end of the<br /> text_in allocation. KASAN reproduces this directly on the unpatched<br /> mainline tree as slab-out-of-bounds in crc32c() called from the Text<br /> PDU path. The OOB bytes feed crc32c() and are then compared against<br /> the initiator-supplied checksum, so the value does not flow back to<br /> the attacker, but the kernel does read past the buffer on every Text<br /> PDU with DataDigest=CRC32C.<br /> <br /> Fix by passing the actual padded payload length<br /> (ALIGN(payload_length, 4)) that was used for the kzalloc().<br /> <br /> 2) Stale cmd-&gt;text_in_ptr re-free (double-free) on ERL&gt;0 bad DataDigest<br /> drop.<br /> <br /> On DataDigest mismatch with ErrorRecoveryLevel &gt; 0 the handler<br /> silently drops the PDU and lets the initiator plug the CmdSN gap:<br /> <br /> kfree(text_in);<br /> return 0;<br /> <br /> cmd-&gt;text_in_ptr still points at the freed buffer. The next Text<br /> Request on the same ITT re-enters iscsit_setup_text_cmd(), which<br /> unconditionally does<br /> <br /> kfree(cmd-&gt;text_in_ptr);<br /> cmd-&gt;text_in_ptr = NULL;<br /> <br /> freeing the same pointer a second time. Session teardown via<br /> iscsit_release_cmd() has the same shape and hits the same double-free<br /> if the connection is dropped before a second Text Request arrives.<br /> <br /> On an unmodified mainline tree the bug-1 CRC overread fires first on<br /> the initial valid Text Request and perturbs the subsequent state, so<br /> #4 was isolated by building a kernel with only the bug-1 hunk of this<br /> patch applied plus temporary printk() observability around the three<br /> relevant kfree() sites. The observability prints are not part of<br /> this patch. On that build, a three-PDU Text Request sequence after<br /> login produces two back-to-back splats:<br /> <br /> BUG: KASAN: double-free in iscsit_setup_text_cmd+0x??<br /> BUG: KASAN: double-free in iscsit_release_cmd+0x??<br /> <br /> showing the same pointer freed in the ERL&gt;0 drop path and again in<br /> iscsit_setup_text_cmd() (next Text Request on the same ITT) and once<br /> more in iscsit_release_cmd() (session teardown). On distro kernels<br /> with CONFIG_SLAB_FREELIST_HARDENED=y (default) the double-free<br /> becomes a remote kernel BUG(); on non-hardened kernels it corrupts<br /> the slab freelist.<br /> <br /> Fix by clearing cmd-&gt;text_in_ptr after the kfree() in the ERL&gt;0 drop<br /> path. With both hunks applied #4 is directly observable on the stock<br /> tree without observability printks; fixing bug-1 alone would mask #4<br /> less, not more, so the hunks are submitted together.<br /> <br /> Both fixes are one-liners. The Text PDU state machine is unchanged and<br /> the wire protocol is unaffected.