lkml.org 
[lkml]   [2020]   [Jan]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.14 127/371] NFSv4/flexfiles: Fix invalid deref in FF_LAYOUT_DEVID_NODE()
    Date
    From: Trond Myklebust <trond.myklebust@hammerspace.com>

    [ Upstream commit 108bb4afd351d65826648a47f11fa3104e250d9b ]

    If the attempt to instantiate the mirror's layout DS pointer failed,
    then that pointer may hold a value of type ERR_PTR(), so we need
    to check that before we dereference it.

    Fixes: 65990d1afbd2d ("pNFS/flexfiles: Fix a deadlock on LAYOUTGET")
    Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    fs/nfs/flexfilelayout/flexfilelayout.h | 32 +++++++++++++++-----------
    1 file changed, 19 insertions(+), 13 deletions(-)

    diff --git a/fs/nfs/flexfilelayout/flexfilelayout.h b/fs/nfs/flexfilelayout/flexfilelayout.h
    index d6515f1584f3..d78ec99b6c4c 100644
    --- a/fs/nfs/flexfilelayout/flexfilelayout.h
    +++ b/fs/nfs/flexfilelayout/flexfilelayout.h
    @@ -131,16 +131,6 @@ FF_LAYOUT_LSEG(struct pnfs_layout_segment *lseg)
    generic_hdr);
    }

    -static inline struct nfs4_deviceid_node *
    -FF_LAYOUT_DEVID_NODE(struct pnfs_layout_segment *lseg, u32 idx)
    -{
    - if (idx >= FF_LAYOUT_LSEG(lseg)->mirror_array_cnt ||
    - FF_LAYOUT_LSEG(lseg)->mirror_array[idx] == NULL ||
    - FF_LAYOUT_LSEG(lseg)->mirror_array[idx]->mirror_ds == NULL)
    - return NULL;
    - return &FF_LAYOUT_LSEG(lseg)->mirror_array[idx]->mirror_ds->id_node;
    -}
    -
    static inline struct nfs4_ff_layout_ds *
    FF_LAYOUT_MIRROR_DS(struct nfs4_deviceid_node *node)
    {
    @@ -150,9 +140,25 @@ FF_LAYOUT_MIRROR_DS(struct nfs4_deviceid_node *node)
    static inline struct nfs4_ff_layout_mirror *
    FF_LAYOUT_COMP(struct pnfs_layout_segment *lseg, u32 idx)
    {
    - if (idx >= FF_LAYOUT_LSEG(lseg)->mirror_array_cnt)
    - return NULL;
    - return FF_LAYOUT_LSEG(lseg)->mirror_array[idx];
    + struct nfs4_ff_layout_segment *fls = FF_LAYOUT_LSEG(lseg);
    +
    + if (idx < fls->mirror_array_cnt)
    + return fls->mirror_array[idx];
    + return NULL;
    +}
    +
    +static inline struct nfs4_deviceid_node *
    +FF_LAYOUT_DEVID_NODE(struct pnfs_layout_segment *lseg, u32 idx)
    +{
    + struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, idx);
    +
    + if (mirror != NULL) {
    + struct nfs4_ff_layout_ds *mirror_ds = mirror->mirror_ds;
    +
    + if (!IS_ERR_OR_NULL(mirror_ds))
    + return &mirror_ds->id_node;
    + }
    + return NULL;
    }

    static inline u32
    --
    2.20.1
    \
     
     \ /
      Last update: 2020-01-16 19:29    [W:4.073 / U:0.072 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site