2016-12-07 20:42:35

by Trond Myklebust

[permalink] [raw]
Subject: [PATCH 0/2] Fix 2 more flexfiles issues

Fix a use-after-free case and a list ordering issue.

Trond Myklebust (2):
pNFS/flexfiles: Fix ff_layout_add_ds_error_locked()
pNFS: Layoutreturn must free the layout after the layout-private data

fs/nfs/flexfilelayout/flexfilelayoutdev.c | 3 ++-
fs/nfs/nfs4proc.c | 4 ++--
2 files changed, 4 insertions(+), 3 deletions(-)

--
2.9.3



2016-12-07 20:42:30

by Trond Myklebust

[permalink] [raw]
Subject: [PATCH 1/2] pNFS/flexfiles: Fix ff_layout_add_ds_error_locked()

When we're merging an old entry into our new entry, we want to ensure that
we add the list entry in the correct place.

Signed-off-by: Trond Myklebust <[email protected]>
---
fs/nfs/flexfilelayout/flexfilelayoutdev.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
index eb98395c3651..142bfd0b1663 100644
--- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c
+++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
@@ -254,8 +254,9 @@ ff_layout_add_ds_error_locked(struct nfs4_flexfile_layout *flo,
}
/* Entries match, so merge "err" into "dserr" */
extend_ds_error(dserr, err->offset, err->length);
- list_del(&err->list);
+ list_replace(&err->list, &dserr->list);
kfree(err);
+ return;
}

list_add_tail(&dserr->list, head);
--
2.9.3


2016-12-07 20:42:31

by Trond Myklebust

[permalink] [raw]
Subject: [PATCH 2/2] pNFS: Layoutreturn must free the layout after the layout-private data

The layout-private data may depend on the layout and/or the inode
still existing when it does post-processing and frees its data, so we
need to free them after calling lrp->ld_private.ops->free().

This fixes a mirror list corruption issue in the flexfiles driver.

Signed-off-by: Trond Myklebust <[email protected]>
---
fs/nfs/nfs4proc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index d3431ff32662..c5a508669655 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -8641,10 +8641,10 @@ static void nfs4_layoutreturn_release(void *calldata)
pnfs_layoutreturn_free_lsegs(lo, &lrp->args.stateid, &lrp->args.range,
lrp->res.lrs_present ? &lrp->res.stateid : NULL);
nfs4_sequence_free_slot(&lrp->res.seq_res);
- pnfs_put_layout_hdr(lrp->args.layout);
- nfs_iput_and_deactive(lrp->inode);
if (lrp->ld_private.ops && lrp->ld_private.ops->free)
lrp->ld_private.ops->free(&lrp->ld_private);
+ pnfs_put_layout_hdr(lrp->args.layout);
+ nfs_iput_and_deactive(lrp->inode);
kfree(calldata);
dprintk("<-- %s\n", __func__);
}
--
2.9.3