aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalph Campbell <ralph.campbell@qlogic.com>2007-06-18 14:24:44 -0700
committerRoland Dreier <rolandd@cisco.com>2007-07-09 20:12:26 -0700
commit30d149ab58cc3ed8e4bc9c4dc45bebbed0e84b6e (patch)
treef85f47458efb9e98f01b490a539dbf873bbaddd9
parentdb5518cd09c21f0fa70af0a4ca38badd90622c9e (diff)
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 <ralph.campbell@qlogic.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r--drivers/infiniband/hw/ipath/ipath_ruc.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_ud.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.c8
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 837118676cc..1b0e62b761b 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 a518f7c8fa8..0b5a6ac1bb8 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 cd79a8ca510..35241b76d76 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;