[DRBD-cvs] svn commit by lars - r2414 - trunk/drbd - just hit a NULL dereference in drbd_send_dblock uppon c

drbd-cvs at lists.linbit.com drbd-cvs at lists.linbit.com
Wed Sep 13 15:15:52 CEST 2006


Author: lars
Date: 2006-09-13 15:15:51 +0200 (Wed, 13 Sep 2006)
New Revision: 2414

Modified:
   trunk/drbd/drbd_int.h
   trunk/drbd/drbd_main.c
   trunk/drbd/drbd_receiver.c
   trunk/drbd/drbd_worker.c
Log:

just hit a NULL dereference in drbd_send_dblock
uppon connection loss... oh well.



Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h	2006-09-13 12:34:25 UTC (rev 2413)
+++ trunk/drbd/drbd_int.h	2006-09-13 13:15:51 UTC (rev 2414)
@@ -868,7 +868,32 @@
 	return mdev->minor;
 }
 
+/* returns 1 if it was successfull,
+ * returns 0 if there was no data socket.
+ * so wherever you are going to use the data.socket, e.g. do
+ * if (!drbd_get_data_sock(mdev))
+ *	return 0;
+ *	CODE();
+ * drbd_put_data_sock(mdev);
+ */
+static inline int drbd_get_data_sock(drbd_dev *mdev)
+{
+	down(&mdev->data.mutex);
+	/* drbd_disconnect() could have called drbd_free_sock()
+	 * while we were waiting in down()... */
+	if (unlikely(mdev->data.socket == NULL)) {
+		up(&mdev->data.mutex);
+		return 0;
+	}
+	return 1;
+}
 
+static inline void drbd_put_data_sock(drbd_dev *mdev)
+{
+	up(&mdev->data.mutex);
+}
+
+
 /*
  * function declarations
  *************************/

Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2006-09-13 12:34:25 UTC (rev 2413)
+++ trunk/drbd/drbd_main.c	2006-09-13 13:15:51 UTC (rev 2414)
@@ -1155,14 +1155,15 @@
 	h.command = cpu_to_be16(cmd);
 	h.length  = cpu_to_be16(size);
 
-	down(&mdev->data.mutex);
+	if (!drbd_get_data_sock(mdev))
+		return 0;
 
 	dump_packet(mdev,mdev->data.socket,0,(void*)&h, __FILE__, __LINE__);
 
 	ok = ( sizeof(h) == drbd_send(mdev,mdev->data.socket,&h,sizeof(h),0) );
 	ok = ok && ( size == drbd_send(mdev,mdev->data.socket,data,size,0) );
 
-	up(&mdev->data.mutex);
+	drbd_put_data_sock(mdev);
 
 	return ok;
 }
@@ -1340,9 +1341,10 @@
 {
 	int ok;
 
-	down(&mdev->data.mutex);
+	if (!drbd_get_data_sock(mdev))
+		return 0;
 	ok=_drbd_send_bitmap(mdev);
-	up(&mdev->data.mutex);
+	drbd_put_data_sock(mdev);
 	return ok;
 }
 
@@ -1572,7 +1574,8 @@
 	Drbd_Data_Packet p;
 	unsigned int dp_flags=0;
 
-	down(&mdev->data.mutex);
+	if (!drbd_get_data_sock(mdev))
+		return 0;
 
 	p.head.magic   = BE_DRBD_MAGIC;
 	p.head.command = cpu_to_be16(Data);
@@ -1599,7 +1602,7 @@
 		}
 	}
 
-	up(&mdev->data.mutex);
+	drbd_put_data_sock(mdev);
 	return ok;
 }
 
@@ -1625,13 +1628,14 @@
 	 * This one may be interupted by DRBD_SIG and/or DRBD_SIGKILL
 	 * in response to ioctl or module unload.
 	 */
-	down(&mdev->data.mutex);
+	if (!drbd_get_data_sock(mdev))
+		return 0;
 
 	dump_packet(mdev,mdev->data.socket,0,(void*)&p, __FILE__, __LINE__);
 	ok = sizeof(p) == drbd_send(mdev,mdev->data.socket,&p,sizeof(p),MSG_MORE);
 	if (ok) ok = _drbd_send_zc_bio(mdev,e->private_bio);
 
-	up(&mdev->data.mutex);
+	drbd_put_data_sock(mdev);
 	return ok;
 }
 

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2006-09-13 12:34:25 UTC (rev 2413)
+++ trunk/drbd/drbd_receiver.c	2006-09-13 13:15:51 UTC (rev 2414)
@@ -2492,6 +2492,12 @@
 		ERR("interrupted during initial handshake\n");
 		return 0; /* interrupted. not ok. */
 	}
+	/* FIXME do we need to verify this here? */
+	if (mdev->data.socket == NULL) {
+		up(&mdev->data.mutex);
+		return 0;
+	}
+
 	memset(p,0,sizeof(*p));
 	p->protocol_version = cpu_to_be32(PRO_VERSION);
 	ok = _drbd_send_cmd( mdev, mdev->data.socket, HandShake,

Modified: trunk/drbd/drbd_worker.c
===================================================================
--- trunk/drbd/drbd_worker.c	2006-09-13 12:34:25 UTC (rev 2413)
+++ trunk/drbd/drbd_worker.c	2006-09-13 13:15:51 UTC (rev 2414)
@@ -511,11 +511,12 @@
 
 	if(unlikely(cancel)) return ok;
 
-	down(&mdev->data.mutex);
+	if (!drbd_get_data_sock(mdev))
+		return 0;
 	p->barrier = b->br_number;
 	inc_ap_pending(mdev);
 	ok = _drbd_send_cmd(mdev,mdev->data.socket,Barrier,(Drbd_Header*)p,sizeof(*p),0);
-	up(&mdev->data.mutex);
+	drbd_put_data_sock(mdev);
 
 	/* pairing dec_ap_pending() happens in got_BarrierAck,
 	 * or (on connection loss) in tl_clear.  */



More information about the drbd-cvs mailing list