aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ipath
diff options
context:
space:
mode:
authorRalph Campbell <ralph.campbell@qlogic.com>2007-06-18 17:24:44 -0400
committerRoland Dreier <rolandd@cisco.com>2007-07-09 23:12:26 -0400
commit30d149ab58cc3ed8e4bc9c4dc45bebbed0e84b6e (patch)
treef85f47458efb9e98f01b490a539dbf873bbaddd9 /drivers/infiniband/hw/ipath
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>
Diffstat (limited to 'drivers/infiniband/hw/ipath')
-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 837118676cc7..1b0e62b761bb 100644
--- a/drivers/infiniband/hw/ipath/ipath_ruc.c
+++ b/drivers/infiniband/hw/ipath/ipath_ruc.c
@@ -396,6 +396,8 @@ again:
396 396
397 if (len > sge->length) 397 if (len > sge->length)
398 len = sge->length; 398 len = sge->length;
399 if (len > sge->sge_length)
400 len = sge->sge_length;
399 BUG_ON(len == 0); 401 BUG_ON(len == 0);
400 ipath_copy_sge(&qp->r_sge, sge->vaddr, len); 402 ipath_copy_sge(&qp->r_sge, sge->vaddr, len);
401 sge->vaddr += len; 403 sge->vaddr += len;
diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c
index a518f7c8fa83..0b5a6ac1bb83 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,
231 231
232 if (len > length) 232 if (len > length)
233 len = length; 233 len = length;
234 if (len > sge->sge_length)
235 len = sge->sge_length;
234 BUG_ON(len == 0); 236 BUG_ON(len == 0);
235 ipath_copy_sge(&rsge, sge->vaddr, len); 237 ipath_copy_sge(&rsge, sge->vaddr, len);
236 sge->vaddr += len; 238 sge->vaddr += len;
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c
index cd79a8ca5104..35241b76d766 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)
164 while (length) { 164 while (length) {
165 u32 len = sge->length; 165 u32 len = sge->length;
166 166
167 BUG_ON(len == 0);
168 if (len > length) 167 if (len > length)
169 len = length; 168 len = length;
169 if (len > sge->sge_length)
170 len = sge->sge_length;
171 BUG_ON(len == 0);
170 memcpy(sge->vaddr, data, len); 172 memcpy(sge->vaddr, data, len);
171 sge->vaddr += len; 173 sge->vaddr += len;
172 sge->length -= len; 174 sge->length -= len;
@@ -202,9 +204,11 @@ void ipath_skip_sge(struct ipath_sge_state *ss, u32 length)
202 while (length) { 204 while (length) {
203 u32 len = sge->length; 205 u32 len = sge->length;
204 206
205 BUG_ON(len == 0);
206 if (len > length) 207 if (len > length)
207 len = length; 208 len = length;
209 if (len > sge->sge_length)
210 len = sge->sge_length;
211 BUG_ON(len == 0);
208 sge->vaddr += len; 212 sge->vaddr += len;
209 sge->length -= len; 213 sge->length -= len;
210 sge->sge_length -= len; 214 sge->sge_length -= len;