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 <[EMAIL PROTECTED]>

---

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;
        }



_______________________________________________
openib-general mailing list
[email protected]
http://openib.org/mailman/listinfo/openib-general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to