3.6.11.9-rc1 stable review patch.
If anyone has any objections, please let me know.

------------------

From: Dan Carpenter <dan.carpen...@oracle.com>

[ Upstream commit b2781e1021525649c0b33fffd005ef219da33926 ]

My static checker marks everything from ntohl() as untrusted and it
complains we could have an underflow problem doing:

        return (u32 *)&ary->wc_array[nchunks];

Also on 32 bit systems the upper bound check could overflow.

Cc: sta...@vger.kernel.org
Signed-off-by: Dan Carpenter <dan.carpen...@oracle.com>
Signed-off-by: J. Bruce Fields <bfie...@redhat.com>
Signed-off-by: Steven Rostedt <rost...@goodmis.org>
---
 net/sunrpc/xprtrdma/svc_rdma_marshal.c |   20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/net/sunrpc/xprtrdma/svc_rdma_marshal.c 
b/net/sunrpc/xprtrdma/svc_rdma_marshal.c
index 8d2eddd..65b1462 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_marshal.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_marshal.c
@@ -98,6 +98,7 @@ void svc_rdma_rcl_chunk_counts(struct rpcrdma_read_chunk *ch,
  */
 static u32 *decode_write_list(u32 *va, u32 *vaend)
 {
+       unsigned long start, end;
        int nchunks;
 
        struct rpcrdma_write_array *ary =
@@ -113,9 +114,12 @@ static u32 *decode_write_list(u32 *va, u32 *vaend)
                return NULL;
        }
        nchunks = ntohl(ary->wc_nchunks);
-       if (((unsigned long)&ary->wc_array[0] +
-            (sizeof(struct rpcrdma_write_chunk) * nchunks)) >
-           (unsigned long)vaend) {
+
+       start = (unsigned long)&ary->wc_array[0];
+       end = (unsigned long)vaend;
+       if (nchunks < 0 ||
+           nchunks > (SIZE_MAX - start) / sizeof(struct rpcrdma_write_chunk) ||
+           (start + (sizeof(struct rpcrdma_write_chunk) * nchunks)) > end) {
                dprintk("svcrdma: ary=%p, wc_nchunks=%d, vaend=%p\n",
                        ary, nchunks, vaend);
                return NULL;
@@ -129,6 +133,7 @@ static u32 *decode_write_list(u32 *va, u32 *vaend)
 
 static u32 *decode_reply_array(u32 *va, u32 *vaend)
 {
+       unsigned long start, end;
        int nchunks;
        struct rpcrdma_write_array *ary =
                (struct rpcrdma_write_array *)va;
@@ -143,9 +148,12 @@ static u32 *decode_reply_array(u32 *va, u32 *vaend)
                return NULL;
        }
        nchunks = ntohl(ary->wc_nchunks);
-       if (((unsigned long)&ary->wc_array[0] +
-            (sizeof(struct rpcrdma_write_chunk) * nchunks)) >
-           (unsigned long)vaend) {
+
+       start = (unsigned long)&ary->wc_array[0];
+       end = (unsigned long)vaend;
+       if (nchunks < 0 ||
+           nchunks > (SIZE_MAX - start) / sizeof(struct rpcrdma_write_chunk) ||
+           (start + (sizeof(struct rpcrdma_write_chunk) * nchunks)) > end) {
                dprintk("svcrdma: ary=%p, wc_nchunks=%d, vaend=%p\n",
                        ary, nchunks, vaend);
                return NULL;
-- 
1.7.10.4


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to