diff --git a/include/spdk/nvmf_spec.h b/include/spdk/nvmf_spec.h index f00adf3bb..bbb676056 100644 --- a/include/spdk/nvmf_spec.h +++ b/include/spdk/nvmf_spec.h @@ -550,6 +550,7 @@ SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_ic_req, pfv) == 8, "Incorrect o SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_ic_req, hpda) == 10, "Incorrect offset"); SPDK_STATIC_ASSERT(offsetof(struct spdk_nvme_tcp_ic_req, maxr2t) == 12, "Incorrect offset"); +#define SPDK_NVME_TCP_HPDA_MAX 31 #define SPDK_NVME_TCP_CPDA_MAX 31 #define SPDK_NVME_TCP_PDU_PDO_MAX_OFFSET ((SPDK_NVME_TCP_CPDA_MAX + 1) << 2) diff --git a/lib/nvmf/tcp.c b/lib/nvmf/tcp.c index aefb00bd5..8c11cdd51 100644 --- a/lib/nvmf/tcp.c +++ b/lib/nvmf/tcp.c @@ -1906,6 +1906,14 @@ nvmf_tcp_icreq_handle(struct spdk_nvmf_tcp_transport *ttransport, goto end; } + /* This value is 0’s based value in units of dwords should not be larger than SPDK_NVME_TCP_HPDA_MAX */ + if (ic_req->hpda > SPDK_NVME_TCP_HPDA_MAX) { + SPDK_ERRLOG("ICReq HPDA out of range 0 to 31, got %u\n", ic_req->hpda); + fes = SPDK_NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD; + error_offset = offsetof(struct spdk_nvme_tcp_ic_req, hpda); + goto end; + } + /* MAXR2T is 0's based */ SPDK_DEBUGLOG(nvmf_tcp, "maxr2t =%u\n", (ic_req->maxr2t + 1u)); diff --git a/test/unit/lib/nvmf/tcp.c/tcp_ut.c b/test/unit/lib/nvmf/tcp.c/tcp_ut.c index d304a03d0..c9ee23494 100644 --- a/test/unit/lib/nvmf/tcp.c/tcp_ut.c +++ b/test/unit/lib/nvmf/tcp.c/tcp_ut.c @@ -897,7 +897,14 @@ test_nvmf_tcp_icreq_handle(void) CU_ASSERT(tqpair.recv_state == NVME_TCP_PDU_RECV_STATE_ERROR); - /* case 2: Expect: PASS. */ + /* case 2: Expected ICReq HPDA in range 0-31 and got are different. */ + pdu.hdr.ic_req.hpda = SPDK_NVME_TCP_HPDA_MAX + 1; + + nvmf_tcp_icreq_handle(&ttransport, &tqpair, &pdu); + + CU_ASSERT(tqpair.recv_state == NVME_TCP_PDU_RECV_STATE_ERROR); + + /* case 3: Expect: PASS. */ ttransport.transport.opts.max_io_size = 32; pdu.hdr.ic_req.pfv = 0; tqpair.host_hdgst_enable = false;