lkml.org 
[lkml]   [2018]   [Jun]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.16 128/410] NFS: Fix 2 use after free issues in the I/O code
    3.16.57-rc1 review patch.  If anyone has any objections, please let me know.

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

    From: Trond Myklebust <trond.myklebust@primarydata.com>

    commit 196639ebbe63a037fe9a80669140bd292d8bcd80 upstream.

    The writeback code wants to send a commit after processing the pages,
    which is why we want to delay releasing the struct path until after
    that's done.

    Also, the layout code expects that we do not free the inode before
    we've put the layout segments in pnfs_writehdr_free() and
    pnfs_readhdr_free()

    Fixes: 919e3bd9a875 ("NFS: Ensure we commit after writeback is complete")
    Fixes: 4714fb51fd03 ("nfs: remove pgio_header refcount, related cleanup")
    Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    fs/nfs/internal.h | 1 -
    fs/nfs/pagelist.c | 26 ++++++++++++--------------
    fs/nfs/pnfs.c | 2 --
    3 files changed, 12 insertions(+), 17 deletions(-)

    --- a/fs/nfs/internal.h
    +++ b/fs/nfs/internal.h
    @@ -249,7 +249,6 @@ int nfs_iocounter_wait(struct nfs_io_cou
    extern const struct nfs_pageio_ops nfs_pgio_rw_ops;
    struct nfs_pgio_header *nfs_pgio_header_alloc(const struct nfs_rw_ops *);
    void nfs_pgio_header_free(struct nfs_pgio_header *);
    -void nfs_pgio_data_destroy(struct nfs_pgio_header *);
    int nfs_generic_pgio(struct nfs_pageio_descriptor *, struct nfs_pgio_header *);
    int nfs_initiate_pgio(struct rpc_clnt *, struct nfs_pgio_header *,
    const struct rpc_call_ops *, int, int);
    --- a/fs/nfs/pagelist.c
    +++ b/fs/nfs/pagelist.c
    @@ -508,16 +508,6 @@ struct nfs_pgio_header *nfs_pgio_header_
    }
    EXPORT_SYMBOL_GPL(nfs_pgio_header_alloc);

    -/*
    - * nfs_pgio_header_free - Free a read or write header
    - * @hdr: The header to free
    - */
    -void nfs_pgio_header_free(struct nfs_pgio_header *hdr)
    -{
    - hdr->rw_ops->rw_free_header(hdr);
    -}
    -EXPORT_SYMBOL_GPL(nfs_pgio_header_free);
    -
    /**
    * nfs_pgio_data_destroy - make @hdr suitable for reuse
    *
    @@ -526,14 +516,24 @@ EXPORT_SYMBOL_GPL(nfs_pgio_header_free);
    *
    * @hdr: A header that has had nfs_generic_pgio called
    */
    -void nfs_pgio_data_destroy(struct nfs_pgio_header *hdr)
    +static void nfs_pgio_data_destroy(struct nfs_pgio_header *hdr)
    {
    if (hdr->args.context)
    put_nfs_open_context(hdr->args.context);
    if (hdr->page_array.pagevec != hdr->page_array.page_array)
    kfree(hdr->page_array.pagevec);
    }
    -EXPORT_SYMBOL_GPL(nfs_pgio_data_destroy);
    +
    +/*
    + * nfs_pgio_header_free - Free a read or write header
    + * @hdr: The header to free
    + */
    +void nfs_pgio_header_free(struct nfs_pgio_header *hdr)
    +{
    + nfs_pgio_data_destroy(hdr);
    + hdr->rw_ops->rw_free_header(hdr);
    +}
    +EXPORT_SYMBOL_GPL(nfs_pgio_header_free);

    /**
    * nfs_pgio_rpcsetup - Set up arguments for a pageio call
    @@ -648,7 +648,6 @@ static int nfs_pgio_error(struct nfs_pag
    struct nfs_pgio_header *hdr)
    {
    set_bit(NFS_IOHDR_REDO, &hdr->flags);
    - nfs_pgio_data_destroy(hdr);
    hdr->completion_ops->completion(hdr);
    desc->pg_completion_ops->error_cleanup(&desc->pg_list);
    return -ENOMEM;
    @@ -663,7 +662,6 @@ static void nfs_pgio_release(void *calld
    struct nfs_pgio_header *hdr = calldata;
    if (hdr->rw_ops->rw_release)
    hdr->rw_ops->rw_release(hdr);
    - nfs_pgio_data_destroy(hdr);
    hdr->completion_ops->completion(hdr);
    }

    --- a/fs/nfs/pnfs.c
    +++ b/fs/nfs/pnfs.c
    @@ -1557,7 +1557,6 @@ pnfs_write_through_mds(struct nfs_pageio
    nfs_pageio_reset_write_mds(desc);
    desc->pg_recoalesce = 1;
    }
    - nfs_pgio_data_destroy(hdr);
    hdr->release(hdr);
    }

    @@ -1695,7 +1694,6 @@ pnfs_read_through_mds(struct nfs_pageio_
    nfs_pageio_reset_read_mds(desc);
    desc->pg_recoalesce = 1;
    }
    - nfs_pgio_data_destroy(hdr);
    hdr->release(hdr);
    }

    \
     
     \ /
      Last update: 2018-06-07 17:16    [W:3.046 / U:0.356 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site