Skip to contentSkip to conversation

libceph: fix NULL dereference in reset_connection()

PATCH In review Dan Carpenter 2 participants 4 messages Jun 19, 2012

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 libceph: fix NULL dereference in reset_connection()

We dereference "con->in_msg" on the line after it was set to NULL.

net/ceph/messenger.c +1 -1
index 5e9f61d..6aa671c 100644
@@ -437,10 +437,10 @@ static void reset_connection(struct ceph_connection *con)
 
 	if (con->in_msg) {
 		BUG_ON(con->in_msg->con != con);
+		ceph_con_put(con->in_msg->con);
 		con->in_msg->con = NULL;
 		ceph_msg_put(con->in_msg);
 		con->in_msg = NULL;
-		ceph_con_put(con->in_msg->con);
 	}
 
 	con->connect_seq = 0;
#1 lore raw
Quoted 3 lines · Dan Carpenter

We dereference "con->in_msg" on the line after it was set to NULL.

Yikes.

Actually I think I prefer a different fix, which is simply to call ceph_con_put(con) in the same spot it was called with con->in_msg->con before. I'd rather drop the message reference before dropping the connection reference. I.e.:

@@ -440,7 +440,7 @@ static void reset_connection(struct ceph_connection *con)
con->in_msg->con = NULL; ceph_msg_put(con->in_msg);
con->in_msg = NULL;
- ceph_con_put(con->in_msg->con);
+ ceph_con_put(con);
}

con->connect_seq = 0;

(I crafted that manually--it may not work...)

I will re-post that fix and will credit you with it. Please acknowledge it's OK with you though. Thanks a lot.

-Alex

Quoted 17 lines
net/ceph/messenger.c +1 -1
index 5e9f61d..6aa671c 100644
@@ -437,10 +437,10 @@ static void reset_connection(struct ceph_connection *con)
 
 	if (con->in_msg) {
 		BUG_ON(con->in_msg->con != con);
+		ceph_con_put(con->in_msg->con);
 		con->in_msg->con = NULL;
 		ceph_msg_put(con->in_msg);
 		con->in_msg = NULL;
-		ceph_con_put(con->in_msg->con);
 	}
 
 	con->connect_seq = 0;
#2 lore raw
Quoted 24 lines · Alex Elder
Quoted 3 lines · Dan Carpenter

We dereference "con->in_msg" on the line after it was set to NULL.

Yikes.

Actually I think I prefer a different fix, which is simply to call ceph_con_put(con) in the same spot it was called with con->in_msg->con before. I'd rather drop the message reference before dropping the connection reference. I.e.:

net/ceph/messenger.c +1 -1
@@ -440,7 +440,7 @@ static void reset_connection(struct ceph_connection
 *con)
 		con->in_msg->con = NULL;
 		ceph_msg_put(con->in_msg);
 		con->in_msg = NULL;
-		ceph_con_put(con->in_msg->con);
+		ceph_con_put(con);
 	}
 

con->connect_seq = 0;

Quoted 5 lines

(I crafted that manually--it may not work...)

I will re-post that fix and will credit you with it. Please acknowledge it's OK with you though. Thanks a lot.

Yep. We already know that con->in_msg->con and con are the same from the BUG_ON() so this works. Thanks.

regards,
dan carpenter

#3 lore raw

PATCH 1/1 libceph: fix NULL dereference in reset_connection()

I have already incorporated the following in the Ceph master branch (which is used for the -next build). We will also send this to Linus soon.

-Alex
====
We dereference "con->in_msg" on the line after it was set to NULL.

---
 net/ceph/messenger.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
net/ceph/messenger.c +0 -0
index 5e9f61d..23073cf 100644
@@ -440,7 +440,7 @@ static void reset_connection(struct ceph_connection

*con)
con->in_msg->con = NULL;
ceph_msg_put(con->in_msg);
con->in_msg = NULL;
- ceph_con_put(con->in_msg->con);
+ ceph_con_put(con);
}

con->connect_seq = 0;