From d8a105742f472ac2f09c3057cc7e41dcddad1a8f Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Tue, 8 Mar 2022 18:10:16 +0900 Subject: [PATCH] nvmf/rdma: Fix overflow of RB tree comparison when qp_num is very big If 0 - UINT32_MAX or UINT32_MAX - 0 is substituted into a int variable, we cannot get any expected result. Fix the bug and add unit test case to verify the fix. Signed-off-by: Shuhei Matsumoto Change-Id: Iad2ea681ad8ad234e70c7310b58785a999612156 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/11837 Tested-by: SPDK CI Jenkins Reviewed-by: Aleksey Marchuk Reviewed-by: Jim Harris Community-CI: Broadcom CI --- lib/nvmf/rdma.c | 2 +- test/unit/lib/nvmf/rdma.c/rdma_ut.c | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/nvmf/rdma.c b/lib/nvmf/rdma.c index 243da2d90..35ec1e718 100644 --- a/lib/nvmf/rdma.c +++ b/lib/nvmf/rdma.c @@ -524,7 +524,7 @@ static const struct spdk_json_object_decoder rdma_transport_opts_decoder[] = { static int nvmf_rdma_qpair_compare(struct spdk_nvmf_rdma_qpair *rqpair1, struct spdk_nvmf_rdma_qpair *rqpair2) { - return rqpair1->qp_num - rqpair2->qp_num; + return rqpair1->qp_num < rqpair2->qp_num ? -1 : rqpair1->qp_num > rqpair2->qp_num; } RB_GENERATE_STATIC(qpairs_tree, spdk_nvmf_rdma_qpair, node, nvmf_rdma_qpair_compare); diff --git a/test/unit/lib/nvmf/rdma.c/rdma_ut.c b/test/unit/lib/nvmf/rdma.c/rdma_ut.c index 85d1ce677..e20788311 100644 --- a/test/unit/lib/nvmf/rdma.c/rdma_ut.c +++ b/test/unit/lib/nvmf/rdma.c/rdma_ut.c @@ -1442,6 +1442,18 @@ test_nvmf_rdma_resources_create(void) nvmf_rdma_resources_destroy(rdma_resource); } +static void +test_nvmf_rdma_qpair_compare(void) +{ + struct spdk_nvmf_rdma_qpair rqpair1 = {}, rqpair2 = {}; + + rqpair1.qp_num = 0; + rqpair2.qp_num = UINT32_MAX; + + CU_ASSERT(nvmf_rdma_qpair_compare(&rqpair1, &rqpair2) < 0); + CU_ASSERT(nvmf_rdma_qpair_compare(&rqpair2, &rqpair1) > 0); +} + int main(int argc, char **argv) { CU_pSuite suite = NULL; @@ -1460,6 +1472,7 @@ int main(int argc, char **argv) CU_ADD_TEST(suite, test_nvmf_rdma_request_free_data); CU_ADD_TEST(suite, test_nvmf_rdma_update_ibv_state); CU_ADD_TEST(suite, test_nvmf_rdma_resources_create); + CU_ADD_TEST(suite, test_nvmf_rdma_qpair_compare); CU_basic_set_mode(CU_BRM_VERBOSE); CU_basic_run_tests();