lkml.org 
[lkml]   [2019]   [Dec]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 118/243] lockd: fix decoding of TEST results
    Date
    From: J. Bruce Fields <bfields@redhat.com>

    [ Upstream commit b8db159239b3f51e2b909859935cc25cb3ff3eed ]

    We fail to advance the read pointer when reading the stat.oh field that
    identifies the lock-holder in a TEST result.

    This turns out not to matter if the server is knfsd, which always
    returns a zero-length field. But other servers (Ganesha is an example)
    may not do this. The result is bad values in fcntl F_GETLK results.

    Fix this.

    Signed-off-by: J. Bruce Fields <bfields@redhat.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    fs/lockd/clnt4xdr.c | 22 ++++++----------------
    fs/lockd/clntxdr.c | 22 ++++++----------------
    2 files changed, 12 insertions(+), 32 deletions(-)

    diff --git a/fs/lockd/clnt4xdr.c b/fs/lockd/clnt4xdr.c
    index 00d5ef5f99f73..214a2fa1f1e39 100644
    --- a/fs/lockd/clnt4xdr.c
    +++ b/fs/lockd/clnt4xdr.c
    @@ -128,24 +128,14 @@ static void encode_netobj(struct xdr_stream *xdr,
    static int decode_netobj(struct xdr_stream *xdr,
    struct xdr_netobj *obj)
    {
    - u32 length;
    - __be32 *p;
    + ssize_t ret;

    - p = xdr_inline_decode(xdr, 4);
    - if (unlikely(p == NULL))
    - goto out_overflow;
    - length = be32_to_cpup(p++);
    - if (unlikely(length > XDR_MAX_NETOBJ))
    - goto out_size;
    - obj->len = length;
    - obj->data = (u8 *)p;
    + ret = xdr_stream_decode_opaque_inline(xdr, (void *)&obj->data,
    + XDR_MAX_NETOBJ);
    + if (unlikely(ret < 0))
    + return -EIO;
    + obj->len = ret;
    return 0;
    -out_size:
    - dprintk("NFS: returned netobj was too long: %u\n", length);
    - return -EIO;
    -out_overflow:
    - print_overflow_msg(__func__, xdr);
    - return -EIO;
    }

    /*
    diff --git a/fs/lockd/clntxdr.c b/fs/lockd/clntxdr.c
    index 2c6176387143c..747b9c8c940ac 100644
    --- a/fs/lockd/clntxdr.c
    +++ b/fs/lockd/clntxdr.c
    @@ -125,24 +125,14 @@ static void encode_netobj(struct xdr_stream *xdr,
    static int decode_netobj(struct xdr_stream *xdr,
    struct xdr_netobj *obj)
    {
    - u32 length;
    - __be32 *p;
    + ssize_t ret;

    - p = xdr_inline_decode(xdr, 4);
    - if (unlikely(p == NULL))
    - goto out_overflow;
    - length = be32_to_cpup(p++);
    - if (unlikely(length > XDR_MAX_NETOBJ))
    - goto out_size;
    - obj->len = length;
    - obj->data = (u8 *)p;
    + ret = xdr_stream_decode_opaque_inline(xdr, (void *)&obj->data,
    + XDR_MAX_NETOBJ);
    + if (unlikely(ret < 0))
    + return -EIO;
    + obj->len = ret;
    return 0;
    -out_size:
    - dprintk("NFS: returned netobj was too long: %u\n", length);
    - return -EIO;
    -out_overflow:
    - print_overflow_msg(__func__, xdr);
    - return -EIO;
    }

    /*
    --
    2.20.1


    \
     
     \ /
      Last update: 2019-12-11 16:53    [W:4.357 / U:0.188 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site