lkml.org 
[lkml]   [2016]   [Apr]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 189/210] nfsd4: fix bad bounds checking
    Date
    4.4-stable review patch.  If anyone has any objections, please let me know.

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

    From: J. Bruce Fields <bfields@redhat.com>

    commit 4aed9c46afb80164401143aa0fdcfe3798baa9d5 upstream.

    A number of spots in the xdr decoding follow a pattern like

    n = be32_to_cpup(p++);
    READ_BUF(n + 4);

    where n is a u32. The only bounds checking is done in READ_BUF itself,
    but since it's checking (n + 4), it won't catch cases where n is very
    large, (u32)(-4) or higher. I'm not sure exactly what the consequences
    are, but we've seen crashes soon after.

    Instead, just break these up into two READ_BUF()s.

    Signed-off-by: J. Bruce Fields <bfields@redhat.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    fs/nfsd/nfs4xdr.c | 13 ++++++++-----
    1 file changed, 8 insertions(+), 5 deletions(-)

    --- a/fs/nfsd/nfs4xdr.c
    +++ b/fs/nfsd/nfs4xdr.c
    @@ -1072,8 +1072,9 @@ nfsd4_decode_rename(struct nfsd4_compoun

    READ_BUF(4);
    rename->rn_snamelen = be32_to_cpup(p++);
    - READ_BUF(rename->rn_snamelen + 4);
    + READ_BUF(rename->rn_snamelen);
    SAVEMEM(rename->rn_sname, rename->rn_snamelen);
    + READ_BUF(4);
    rename->rn_tnamelen = be32_to_cpup(p++);
    READ_BUF(rename->rn_tnamelen);
    SAVEMEM(rename->rn_tname, rename->rn_tnamelen);
    @@ -1155,13 +1156,14 @@ nfsd4_decode_setclientid(struct nfsd4_co
    READ_BUF(8);
    setclientid->se_callback_prog = be32_to_cpup(p++);
    setclientid->se_callback_netid_len = be32_to_cpup(p++);
    -
    - READ_BUF(setclientid->se_callback_netid_len + 4);
    + READ_BUF(setclientid->se_callback_netid_len);
    SAVEMEM(setclientid->se_callback_netid_val, setclientid->se_callback_netid_len);
    + READ_BUF(4);
    setclientid->se_callback_addr_len = be32_to_cpup(p++);

    - READ_BUF(setclientid->se_callback_addr_len + 4);
    + READ_BUF(setclientid->se_callback_addr_len);
    SAVEMEM(setclientid->se_callback_addr_val, setclientid->se_callback_addr_len);
    + READ_BUF(4);
    setclientid->se_callback_ident = be32_to_cpup(p++);

    DECODE_TAIL;
    @@ -1815,8 +1817,9 @@ nfsd4_decode_compound(struct nfsd4_compo

    READ_BUF(4);
    argp->taglen = be32_to_cpup(p++);
    - READ_BUF(argp->taglen + 8);
    + READ_BUF(argp->taglen);
    SAVEMEM(argp->tag, argp->taglen);
    + READ_BUF(8);
    argp->minorversion = be32_to_cpup(p++);
    argp->opcnt = be32_to_cpup(p++);
    max_reply += 4 + (XDR_QUADLEN(argp->taglen) << 2);

    \
     
     \ /
      Last update: 2016-04-10 21:41    [W:4.077 / U:0.040 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site