[PATCH v2] RDMA/erdma: Fix exception handling in erdma_accept_newconn()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Markus Elfring <elfring@xxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 13 Mar 2025 11:44:50 +0100

The label “error” was used to jump to another pointer check despite of
the detail in the implementation of the function “erdma_accept_newconn”
that it was determined already that corresponding variables contained
still null pointers.

1. Thus return directly if
   * the cep state is not the value “ERDMA_EPSTATE_LISTENING”
     or
   * a call of the function “erdma_cep_alloc” failed.

2. Use more appropriate labels instead.

3. Delete two questionable checks.

4. Omit extra initialisations (for the variables “new_cep”, “new_s” and “ret”)
   which became unnecessary with this refactoring.


This issue was detected by using the Coccinelle software.

Fixes: 920d93eac8b9 ("RDMA/erdma: Add connection management (CM) support")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Markus Elfring <elfring@xxxxxxxxxxxxxxxxxxxxx>
---

See also:
* https://lore.kernel.org/cocci/167179d0-e1ea-39a8-4143-949ad57294c2@xxxxxxxxxxxxxxxxx/
* https://lkml.org/lkml/2023/3/19/191


V2:
The change suggestion was rebased on source files of the software “Linux next-20250313”.
A corresponding implementation detail was improved by the commit 83437689249e6a17b25e27712fbee292e42e7855
("RDMA/erdma: Prevent use-after-free in erdma_accept_newconn()") on 2025-03-06.


 drivers/infiniband/hw/erdma/erdma_cm.c | 37 +++++++++++---------------
 1 file changed, 16 insertions(+), 21 deletions(-)

diff --git a/drivers/infiniband/hw/erdma/erdma_cm.c b/drivers/infiniband/hw/erdma/erdma_cm.c
index e0acc185e719..a7a79722e940 100644
--- a/drivers/infiniband/hw/erdma/erdma_cm.c
+++ b/drivers/infiniband/hw/erdma/erdma_cm.c
@@ -642,16 +642,16 @@ static int erdma_proc_mpareply(struct erdma_cep *cep)
 static void erdma_accept_newconn(struct erdma_cep *cep)
 {
 	struct socket *s = cep->sock;
-	struct socket *new_s = NULL;
-	struct erdma_cep *new_cep = NULL;
-	int ret = 0;
+	struct socket *new_s;
+	struct erdma_cep *new_cep;
+	int ret;

 	if (cep->state != ERDMA_EPSTATE_LISTENING)
-		goto error;
+		return;

 	new_cep = erdma_cep_alloc(cep->dev);
 	if (!new_cep)
-		goto error;
+		return;

 	/*
 	 * 4: Allocate a sufficient number of work elements
@@ -659,7 +659,7 @@ static void erdma_accept_newconn(struct erdma_cep *cep)
 	 * events, MPA header processing + MPA timeout.
 	 */
 	if (erdma_cm_alloc_work(new_cep, 4) != 0)
-		goto error;
+		goto put_cep;

 	/*
 	 * Copy saved socket callbacks from listening CEP
@@ -671,7 +671,7 @@ static void erdma_accept_newconn(struct erdma_cep *cep)

 	ret = kernel_accept(s, &new_s, O_NONBLOCK);
 	if (ret != 0)
-		goto error;
+		goto put_cep;

 	new_cep->sock = new_s;
 	erdma_cep_get(new_cep);
@@ -682,7 +682,7 @@ static void erdma_accept_newconn(struct erdma_cep *cep)

 	ret = erdma_cm_queue_work(new_cep, ERDMA_CM_WORK_MPATIMEOUT);
 	if (ret)
-		goto error;
+		goto disassoc_socket;

 	new_cep->listen_cep = cep;
 	erdma_cep_get(cep);
@@ -696,25 +696,20 @@ static void erdma_accept_newconn(struct erdma_cep *cep)
 			new_cep->listen_cep = NULL;
 			if (ret) {
 				erdma_cep_set_free(new_cep);
-				goto error;
+				goto disassoc_socket;
 			}
 		}
 		erdma_cep_set_free(new_cep);
 	}
 	return;

-error:
-	if (new_cep) {
-		new_cep->state = ERDMA_EPSTATE_CLOSED;
-		erdma_cancel_mpatimer(new_cep);
-
-		erdma_cep_put(new_cep);
-	}
-
-	if (new_s) {
-		erdma_socket_disassoc(new_s);
-		sock_release(new_s);
-	}
+disassoc_socket:
+	erdma_socket_disassoc(new_s);
+	sock_release(new_s);
+	new_cep->state = ERDMA_EPSTATE_CLOSED;
+	erdma_cancel_mpatimer(new_cep);
+put_cep:
+	erdma_cep_put(new_cep);
 }

 static int erdma_newconn_connected(struct erdma_cep *cep)
--
2.48.1






[Index of Archives]     [Kernel Development]     [Kernel Announce]     [Kernel Newbies]     [Linux Networking Development]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Device Mapper]

  Powered by Linux