Commit 8cd4cc63 authored by Artur Paszkiewicz's avatar Artur Paszkiewicz Committed by Tomasz Zawadzki
Browse files

nvmf/tcp: fix tgroup->qpairs use after free



During qpair destruction, if recv_state ==
NVME_TCP_PDU_RECV_STATE_AWAIT_REQ, and nvmf_tcp_qpair_set_recv_state()
is called after nvmf_tcp_poll_group_remove(), the tqpair is incorrectly
removed (again) from the await req list and added to the
spdk_nvmf_tcp_poll_group qpairs list before being freed. Later, adding a
new qpair to the list causes dereferencing a pointer to the freed item.
Prevent this by ensuring the recv_state is not
NVME_TCP_PDU_RECV_STATE_AWAIT_REQ before removing the qpair from the
poll group.

Fixes #3208

Change-Id: I945b5f3993ca0c81a065aa6dc99e3f80d0cf88a2
Signed-off-by: default avatarArtur Paszkiewicz <artur.paszkiewicz@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/21072


Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarVasuki Manikarnike <vasuki.manikarnike@hpe.com>
Reviewed-by: default avatarBen Walker <ben@nvidia.com>
Community-CI: Mellanox Build Bot
parent 0ace905f
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -3266,10 +3266,11 @@ nvmf_tcp_poll_group_remove(struct spdk_nvmf_transport_poll_group *group,

	SPDK_DEBUGLOG(nvmf_tcp, "remove tqpair=%p from the tgroup=%p\n", tqpair, tgroup);
	if (tqpair->recv_state == NVME_TCP_PDU_RECV_STATE_AWAIT_REQ) {
		TAILQ_REMOVE(&tgroup->await_req, tqpair, link);
	} else {
		TAILQ_REMOVE(&tgroup->qpairs, tqpair, link);
		/* Change the state to move the qpair from the await_req list to the main list
		 * and prevent adding it again later by nvmf_tcp_qpair_set_recv_state() */
		nvmf_tcp_qpair_set_recv_state(tqpair, NVME_TCP_PDU_RECV_STATE_QUIESCING);
	}
	TAILQ_REMOVE(&tgroup->qpairs, tqpair, link);

	rc = spdk_sock_group_remove_sock(tgroup->sock_group, tqpair->sock);
	if (rc != 0) {