Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=30d149ab58cc3ed8e4bc9c4dc45bebbed0e84b6e
Commit:     30d149ab58cc3ed8e4bc9c4dc45bebbed0e84b6e
Parent:     db5518cd09c21f0fa70af0a4ca38badd90622c9e
Author:     Ralph Campbell <[EMAIL PROTECTED]>
AuthorDate: Mon Jun 18 14:24:44 2007 -0700
Committer:  Roland Dreier <[EMAIL PROTECTED]>
CommitDate: Mon Jul 9 20:12:26 2007 -0700

    IB/ipath: Fix possible data corruption if multiple SGEs used for receive
    
    The code to copy data from the receive queue buffers to the IB SGEs
    doesn't check the SGE length, only the memory region/page length when
    copying data.  This could overwrite parts of the user's memory that
    were not intended to be written.  It can only happen if multiple SGEs
    are used to describe a receive buffer which almost never happens in
    practice.
    
    Signed-off-by: Ralph Campbell <[EMAIL PROTECTED]>
    Signed-off-by: Roland Dreier <[EMAIL PROTECTED]>
---
 drivers/infiniband/hw/ipath/ipath_ruc.c   |    2 ++
 drivers/infiniband/hw/ipath/ipath_ud.c    |    2 ++
 drivers/infiniband/hw/ipath/ipath_verbs.c |    8 ++++++--
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/hw/ipath/ipath_ruc.c 
b/drivers/infiniband/hw/ipath/ipath_ruc.c
index 8371186..1b0e62b 100644
--- a/drivers/infiniband/hw/ipath/ipath_ruc.c
+++ b/drivers/infiniband/hw/ipath/ipath_ruc.c
@@ -396,6 +396,8 @@ again:
 
                if (len > sge->length)
                        len = sge->length;
+               if (len > sge->sge_length)
+                       len = sge->sge_length;
                BUG_ON(len == 0);
                ipath_copy_sge(&qp->r_sge, sge->vaddr, len);
                sge->vaddr += len;
diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c 
b/drivers/infiniband/hw/ipath/ipath_ud.c
index a518f7c..0b5a6ac 100644
--- a/drivers/infiniband/hw/ipath/ipath_ud.c
+++ b/drivers/infiniband/hw/ipath/ipath_ud.c
@@ -231,6 +231,8 @@ static void ipath_ud_loopback(struct ipath_qp *sqp,
 
                if (len > length)
                        len = length;
+               if (len > sge->sge_length)
+                       len = sge->sge_length;
                BUG_ON(len == 0);
                ipath_copy_sge(&rsge, sge->vaddr, len);
                sge->vaddr += len;
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c 
b/drivers/infiniband/hw/ipath/ipath_verbs.c
index cd79a8c..35241b7 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.c
@@ -164,9 +164,11 @@ void ipath_copy_sge(struct ipath_sge_state *ss, void 
*data, u32 length)
        while (length) {
                u32 len = sge->length;
 
-               BUG_ON(len == 0);
                if (len > length)
                        len = length;
+               if (len > sge->sge_length)
+                       len = sge->sge_length;
+               BUG_ON(len == 0);
                memcpy(sge->vaddr, data, len);
                sge->vaddr += len;
                sge->length -= len;
@@ -202,9 +204,11 @@ void ipath_skip_sge(struct ipath_sge_state *ss, u32 length)
        while (length) {
                u32 len = sge->length;
 
-               BUG_ON(len == 0);
                if (len > length)
                        len = length;
+               if (len > sge->sge_length)
+                       len = sge->sge_length;
+               BUG_ON(len == 0);
                sge->vaddr += len;
                sge->length -= len;
                sge->sge_length -= len;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to