[openib-general] [PATCH] uMAD: fix copying MAD data when reporting a send failure

Sean Hefty sean.hefty at intel.com
Mon Feb 27 16:36:07 PST 2006


Fix a bug where the size of the data copied to userspace is larger
than the reported size.  Re-use the failed send packet when reporting
the failure, versus copying the send information to a new packet.

Signed-off-by: Sean Hefty <sean.hefty at intel.com>

---

NOTE: I don't have a way to test that this fix actually works.


Index: user_mad.c
===================================================================
--- user_mad.c	(revision 5514)
+++ user_mad.c	(working copy)
@@ -248,28 +248,17 @@ static void send_handler(struct ib_mad_a
 			 struct ib_mad_send_wc *send_wc)
 {
 	struct ib_umad_file *file = agent->context;
-	struct ib_umad_packet *timeout;
 	struct ib_umad_packet *packet = send_wc->send_buf->context[0];
 
 	ib_destroy_ah(packet->msg->ah);
 	ib_free_send_mad(packet->msg);
 
 	if (send_wc->status == IB_WC_RESP_TIMEOUT_ERR) {
-		timeout = kzalloc(sizeof *timeout + sizeof(struct ib_mad),
-				  GFP_KERNEL);
-		if (!timeout)
-			goto out;
-		INIT_LIST_HEAD(&timeout->seg_list);
-		timeout->length 	= IB_MGMT_MAD_HDR;
-		timeout->mad.hdr.id 	= packet->mad.hdr.id;
-		timeout->mad.hdr.status = ETIMEDOUT;
-		memcpy(timeout->mad.data, packet->mad.data,
-		       sizeof (struct ib_mad_hdr));
-
-		if (queue_packet(file, agent, timeout))
-			free_packet(timeout);
+		packet->length = IB_MGMT_MAD_HDR;
+		packet->mad.hdr.status = ETIMEDOUT;
+		if (!queue_packet(file, agent, packet))
+			return;
 	}
-out:
 	kfree(packet);
 }
 
@@ -324,7 +313,7 @@ static ssize_t ib_umad_read(struct file 
 	struct ib_umad_file *file = filp->private_data;
 	struct ib_rmpp_segment *seg;
 	struct ib_umad_packet *packet;
-	ssize_t ret;
+	ssize_t ret, size;
 
 	if (count < sizeof (struct ib_user_mad) + sizeof (struct ib_mad))
 		return -EINVAL;
@@ -349,8 +338,9 @@ static ssize_t ib_umad_read(struct file 
 
 	spin_unlock_irq(&file->recv_lock);
 
+	size = min_t(int, sizeof (struct ib_mad), packet->length);
 	if (copy_to_user(buf, &packet->mad,
-			 sizeof(struct ib_user_mad) + sizeof(struct ib_mad))) {
+			 sizeof(struct ib_user_mad) + size)) {
 		ret = -EFAULT;
 		goto err;
 	}






More information about the general mailing list