In the Linux kernel, the following vulnerability has been resolved: nvmet-tcp: fix race between ICReq handling and queue teardown nvmet_tcp_handle_icreq() updates queue->state after sending an Initialization Connection Response (ICResp), but it does so without serializing against target-side queue teardown. If an NVMe/TCP host sends an Initialization Connection Request (ICReq) and immediately closes the connection, target-side teardown may start in softirq context before io_work drains the already buffered ICReq. In that case, nvmet_tcp_schedule_release_queue() sets queue->state to NVMET_TCP_Q_DISCONNECTING and drops the queue reference under state_lock. If io_work later processes that ICReq, nvmet_tcp_handle_icreq() can still overwrite the state back to NVMET_TCP_Q_LIVE. That defeats the DISCONNECTING-state guard in nvmet_tcp_schedule_release_queue() and allows a later socket state change to re-enter teardown and issue a second kref_put() on an already released queue. The ICResp send failure path has the same problem. If teardown has already moved the queue to DISCONNECTING, a send error can still overwrite the state with NVMET_TCP_Q_FAILED, again reopening the window for a second teardown path to drop the queue reference. Fix this by serializing both post-send state transitions with state_lock and bailing out if teardown has already started. Use -ESHUTDOWN as an internal sentinel for that bail-out path rather than propagating it as a transport error like -ECONNRESET. Keep nvmet_tcp_socket_error() setting rcv_state to NVMET_TCP_RECV_ERR before honoring that sentinel so receive-side parsing stays quiesced until the existing release path completes.
When an NVMe/TCP host sends a connection initialization request (ICReq) and immediately closes the connection, queue destruction may begin in the softirq context on the server side before io_work has time to process the buffered ICReq. The function nvmet_tcp_schedule_release_queue() then sets the queue state to NVMET_TCP_Q_DISCONNECTING and releases the reference under state_lock. If io_work subsequently processes the ICReq, the function nvmet_tcp_handle_icreq() may overwrite the state back to NVMET_TCP_Q_LIVE, bypassing the DISCONNECTING state protection. A similar issue occurs in the ICResp sending error path — a transmission error may overwrite the state to NVMET_TCP_Q_FAILED, again opening a window to execute the second queue destruction path and invoke a second kref_put() on an already freed queue. The fix serializes both state changes after sending using state_lock and aborts the operation if destruction has already begun.
An attacker or malicious NVMe/TCP host can cause a double free of a reference to a queue object, which may result in kernel memory corruption, system instability, or potential arbitrary code execution in the kernel context (privilege escalation or RCE).
Apply patches available in the kernel.org repository according to the references: commits 49891c8fe0cb, 5293a8882c54, 67e1aaf93b49, dcfe4d1f7960. It is recommended to update the Linux kernel to a version containing the mentioned fixes.
Linux kernel containing the nvmet-tcp module — specific versions indicated in the vendor references (patches available in stable kernel.org repositories).
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:HLinux Kernel
OSLinux7.15.0 – 6.12.88 (excl.)6.13 – 6.18.30 (excl.)6.19 – 7.0.7 (excl.)
Related vulnerabilities
Type confusion w V8 (Google Chrome) — zdalne uszkodzenie sterty
Commvault Command Center – nieuwierzytelniony RCE przez path traversal w ZIP
RCE przez YAML deserialization w IBM Aspera Faspex
RCE w VMware Workspace ONE Access i Identity Manager poprzez server-side template injection
Command Injection w VMware Workspace One Access i Identity Manager