lkml.org 
[lkml]   [2013]   [Sep]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[103/251] svcrdma: underflow issue in decode_write_list()
    3.6.11.9-rc1 stable review patch.
    If anyone has any objections, please let me know.

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

    From: Dan Carpenter <dan.carpenter@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: stable@vger.kernel.org
    Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
    Signed-off-by: J. Bruce Fields <bfields@redhat.com>
    Signed-off-by: Steven Rostedt <rostedt@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



    \
     
     \ /
      Last update: 2013-09-11 07:41    [W:4.193 / U:0.064 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site