Skip to content

Commit d920abd

Browse files
sagigrimbergkeithbusch
authored andcommitted
nvmet-tcp: Fix a possible UAF in queue intialization setup
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]>
1 parent 3820c4f commit d920abd

File tree

1 file changed

+2
-5
lines changed

1 file changed

+2
-5
lines changed

drivers/nvme/target/tcp.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ static void nvmet_tcp_fatal_error(struct nvmet_tcp_queue *queue)
372372

373373
static void nvmet_tcp_socket_error(struct nvmet_tcp_queue *queue, int status)
374374
{
375+
queue->rcv_state = NVMET_TCP_RECV_ERR;
375376
if (status == -EPIPE || status == -ECONNRESET)
376377
kernel_sock_shutdown(queue->sock, SHUT_RDWR);
377378
else
@@ -910,15 +911,11 @@ static int nvmet_tcp_handle_icreq(struct nvmet_tcp_queue *queue)
910911
iov.iov_len = sizeof(*icresp);
911912
ret = kernel_sendmsg(queue->sock, &msg, &iov, 1, iov.iov_len);
912913
if (ret < 0)
913-
goto free_crypto;
914+
return ret; /* queue removal will cleanup */
914915

915916
queue->state = NVMET_TCP_Q_LIVE;
916917
nvmet_prepare_receive_pdu(queue);
917918
return 0;
918-
free_crypto:
919-
if (queue->hdr_digest || queue->data_digest)
920-
nvmet_tcp_free_crypto(queue);
921-
return ret;
922919
}
923920

924921
static void nvmet_tcp_handle_req_failure(struct nvmet_tcp_queue *queue,

0 commit comments

Comments
 (0)