Skip to contentSkip to conversation

Patch "staging: lustre: separate a connection destroy from free struct kib_conn" has been added to the 4.15-stable tree

PATCH [email protected] 1 participant 1 message Feb 2, 2018

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

staging: lustre: separate a connection destroy from free struct kib_conn

to the 4.15-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
staging-lustre-separate-a-connection-destroy-from-free-struct-kib_conn.patch
and it can be found in the queue-4.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From 9b046013e5837f8a58453d1e9f8e01d03adb7fe7 Mon Sep 17 00:00:00 2001

From: Dmitry Eremin <[email protected]>
Date: Thu, 25 Jan 2018 16:51:04 +0300
Subject: staging: lustre: separate a connection destroy from free struct kib_conn

From: Dmitry Eremin <[email protected]>

commit 9b046013e5837f8a58453d1e9f8e01d03adb7fe7 upstream.

The logic of the original commit 4d99b2581eff ("staging: lustre: avoid intensive reconnecting for ko2iblnd") was assumed conditional free of struct kib_conn if the second argument free_conn in function kiblnd_destroy_conn(struct kib_conn *conn, bool free_conn) is true. But this hunk of code was dropped from original commit. As result the logic works wrong and current code use struct kib_conn after free.

Quoted 17 lines

drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
3317 kiblnd_destroy_conn(conn, !peer);
^^^^ Freed always (but should be conditionally)
3318
3319 spin_lock_irqsave(lock, flags);
3320 if (!peer)
3321 continue;
3322

3323  conn->ibc_peer = peer;
      ^^^^^^^^^^^^^^ Use after free
3324  if (peer->ibp_reconnected < KIB_RECONN_HIGH_RACE)
3325      list_add_tail(&conn->ibc_list,
                         ^^^^^^^^^^^^^^ Use after free
3326                    &kiblnd_data.kib_reconn_list);
3327  else
3328      list_add_tail(&conn->ibc_list,
                         ^^^^^^^^^^^^^^ Use after free
Quoted 1 line

3329 &kiblnd_data.kib_reconn_wait);

To avoid confusion this fix moved the freeing a struct kib_conn outside of the function kiblnd_destroy_conn() and free as it was intended in original commit.

Fixes 4d99b2581eff ("staging: lustre: avoid intensive reconnecting for ko2iblnd")
---
 drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c    |    7 +++----
 drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h    |    2 +-
 drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c |    6 ++++--
 3 files changed, 8 insertions(+), 7 deletions(-)
drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +3 -4
@@ -826,14 +826,15 @@ struct kib_conn *kiblnd_create_conn(stru
 	return conn;
 
  failed_2:
-	kiblnd_destroy_conn(conn, true);
+	kiblnd_destroy_conn(conn);
+	LIBCFS_FREE(conn, sizeof(*conn));
  failed_1:
 	LIBCFS_FREE(init_qp_attr, sizeof(*init_qp_attr));
  failed_0:
 	return NULL;
 }
 
-void kiblnd_destroy_conn(struct kib_conn *conn, bool free_conn)
+void kiblnd_destroy_conn(struct kib_conn *conn)
 {
 	struct rdma_cm_id *cmid = conn->ibc_cmid;
 	struct kib_peer *peer = conn->ibc_peer;
@@ -896,8 +897,6 @@ void kiblnd_destroy_conn(struct kib_conn
 		rdma_destroy_id(cmid);
 		atomic_dec(&net->ibn_nconns);
 	}
-
-	LIBCFS_FREE(conn, sizeof(*conn));
 }
 
 int kiblnd_close_peer_conns_locked(struct kib_peer *peer, int why)
drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h +1 -1
@@ -1016,7 +1016,7 @@ int  kiblnd_close_peer_conns_locked(stru
 struct kib_conn *kiblnd_create_conn(struct kib_peer *peer,
 				    struct rdma_cm_id *cmid,
 				    int state, int version);
-void kiblnd_destroy_conn(struct kib_conn *conn, bool free_conn);
+void kiblnd_destroy_conn(struct kib_conn *conn);
 void kiblnd_close_conn(struct kib_conn *conn, int error);
 void kiblnd_close_conn_locked(struct kib_conn *conn, int error);
 
drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +4 -2
@@ -3314,11 +3314,13 @@ kiblnd_connd(void *arg)
 			spin_unlock_irqrestore(lock, flags);
 			dropped_lock = 1;
 
-			kiblnd_destroy_conn(conn, !peer);
+			kiblnd_destroy_conn(conn);
 
 			spin_lock_irqsave(lock, flags);
-			if (!peer)
+			if (!peer) {
+				kfree(conn);
 				continue;
+			}
 
 			conn->ibc_peer = peer;
 			if (peer->ibp_reconnected < KIB_RECONN_HIGH_RACE)

Patches currently in stable-queue which might be from [email protected] are

queue-4.15/staging-lustre-separate-a-connection-destroy-from-free-struct-kib_conn.patch