Skip to content

Commit

Permalink
nvmet-tcp: Fix a possible UAF in queue intialization setup
Browse files Browse the repository at this point in the history
jira VULN-6747
cve CVE-2023-5178
commit-author Sagi Grimberg <[email protected]>
commit d920abd

From Alon:
"Due to a logical bug in the NVMe-oF/TCP subsystem in the Linux kernel,
a malicious user can cause a UAF and a double free, which may lead to
RCE (may also lead to an LPE in case the attacker already has local
privileges)."

Hence, when a queue initialization fails after the ahash requests are
allocated, it is guaranteed that the queue removal async work will be
called, hence leave the deallocation to the queue removal.

Also, be extra careful not to continue processing the socket, so set
queue rcv_state to NVMET_TCP_RECV_ERR upon a socket error.

	Cc: [email protected]
	Reported-by: Alon Zahavi <[email protected]>
	Tested-by: Alon Zahavi <[email protected]>
	Signed-off-by: Sagi Grimberg <[email protected]>
	Reviewed-by: Christoph Hellwig <[email protected]>
	Reviewed-by: Chaitanya Kulkarni <[email protected]>
	Signed-off-by: Keith Busch <[email protected]>
(cherry picked from commit d920abd)
	Signed-off-by: Greg Rose <[email protected]>
  • Loading branch information
gvrose8192 committed Nov 20, 2024
1 parent 9be1540 commit ffed171
Showing 1 changed file with 2 additions and 5 deletions.
7 changes: 2 additions & 5 deletions drivers/nvme/target/tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ static void nvmet_tcp_fatal_error(struct nvmet_tcp_queue *queue)

static void nvmet_tcp_socket_error(struct nvmet_tcp_queue *queue, int status)
{
queue->rcv_state = NVMET_TCP_RECV_ERR;
if (status == -EPIPE || status == -ECONNRESET)
kernel_sock_shutdown(queue->sock, SHUT_RDWR);
else
Expand Down Expand Up @@ -872,15 +873,11 @@ static int nvmet_tcp_handle_icreq(struct nvmet_tcp_queue *queue)
iov.iov_len = sizeof(*icresp);
ret = kernel_sendmsg(queue->sock, &msg, &iov, 1, iov.iov_len);
if (ret < 0)
goto free_crypto;
return ret; /* queue removal will cleanup */

queue->state = NVMET_TCP_Q_LIVE;
nvmet_prepare_receive_pdu(queue);
return 0;
free_crypto:
if (queue->hdr_digest || queue->data_digest)
nvmet_tcp_free_crypto(queue);
return ret;
}

static void nvmet_tcp_handle_req_failure(struct nvmet_tcp_queue *queue,
Expand Down

0 comments on commit ffed171

Please sign in to comment.