Skip to content

Commit 677a803

Browse files
trondmypdgregkh
authored andcommitted
NFS: Fix 2 use after free issues in the I/O code
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: 4714fb5 ("nfs: remove pgio_header refcount, related cleanup") Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 8447847 commit 677a803

3 files changed

Lines changed: 12 additions & 17 deletions

File tree

fs/nfs/internal.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,6 @@ int nfs_iocounter_wait(struct nfs_io_counter *c);
243243
extern const struct nfs_pageio_ops nfs_pgio_rw_ops;
244244
struct nfs_pgio_header *nfs_pgio_header_alloc(const struct nfs_rw_ops *);
245245
void nfs_pgio_header_free(struct nfs_pgio_header *);
246-
void nfs_pgio_data_destroy(struct nfs_pgio_header *);
247246
int nfs_generic_pgio(struct nfs_pageio_descriptor *, struct nfs_pgio_header *);
248247
int nfs_initiate_pgio(struct rpc_clnt *clnt, struct nfs_pgio_header *hdr,
249248
struct rpc_cred *cred, const struct nfs_rpc_ops *rpc_ops,

fs/nfs/pagelist.c

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -528,16 +528,6 @@ struct nfs_pgio_header *nfs_pgio_header_alloc(const struct nfs_rw_ops *ops)
528528
}
529529
EXPORT_SYMBOL_GPL(nfs_pgio_header_alloc);
530530

531-
/*
532-
* nfs_pgio_header_free - Free a read or write header
533-
* @hdr: The header to free
534-
*/
535-
void nfs_pgio_header_free(struct nfs_pgio_header *hdr)
536-
{
537-
hdr->rw_ops->rw_free_header(hdr);
538-
}
539-
EXPORT_SYMBOL_GPL(nfs_pgio_header_free);
540-
541531
/**
542532
* nfs_pgio_data_destroy - make @hdr suitable for reuse
543533
*
@@ -546,14 +536,24 @@ EXPORT_SYMBOL_GPL(nfs_pgio_header_free);
546536
*
547537
* @hdr: A header that has had nfs_generic_pgio called
548538
*/
549-
void nfs_pgio_data_destroy(struct nfs_pgio_header *hdr)
539+
static void nfs_pgio_data_destroy(struct nfs_pgio_header *hdr)
550540
{
551541
if (hdr->args.context)
552542
put_nfs_open_context(hdr->args.context);
553543
if (hdr->page_array.pagevec != hdr->page_array.page_array)
554544
kfree(hdr->page_array.pagevec);
555545
}
556-
EXPORT_SYMBOL_GPL(nfs_pgio_data_destroy);
546+
547+
/*
548+
* nfs_pgio_header_free - Free a read or write header
549+
* @hdr: The header to free
550+
*/
551+
void nfs_pgio_header_free(struct nfs_pgio_header *hdr)
552+
{
553+
nfs_pgio_data_destroy(hdr);
554+
hdr->rw_ops->rw_free_header(hdr);
555+
}
556+
EXPORT_SYMBOL_GPL(nfs_pgio_header_free);
557557

558558
/**
559559
* nfs_pgio_rpcsetup - Set up arguments for a pageio call
@@ -671,7 +671,6 @@ static int nfs_pgio_error(struct nfs_pageio_descriptor *desc,
671671
u32 midx;
672672

673673
set_bit(NFS_IOHDR_REDO, &hdr->flags);
674-
nfs_pgio_data_destroy(hdr);
675674
hdr->completion_ops->completion(hdr);
676675
/* TODO: Make sure it's right to clean up all mirrors here
677676
* and not just hdr->pgio_mirror_idx */
@@ -689,7 +688,6 @@ static int nfs_pgio_error(struct nfs_pageio_descriptor *desc,
689688
static void nfs_pgio_release(void *calldata)
690689
{
691690
struct nfs_pgio_header *hdr = calldata;
692-
nfs_pgio_data_destroy(hdr);
693691
hdr->completion_ops->completion(hdr);
694692
}
695693

fs/nfs/pnfs.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1943,7 +1943,6 @@ pnfs_write_through_mds(struct nfs_pageio_descriptor *desc,
19431943
nfs_pageio_reset_write_mds(desc);
19441944
mirror->pg_recoalesce = 1;
19451945
}
1946-
nfs_pgio_data_destroy(hdr);
19471946
hdr->release(hdr);
19481947
}
19491948

@@ -2059,7 +2058,6 @@ pnfs_read_through_mds(struct nfs_pageio_descriptor *desc,
20592058
nfs_pageio_reset_read_mds(desc);
20602059
mirror->pg_recoalesce = 1;
20612060
}
2062-
nfs_pgio_data_destroy(hdr);
20632061
hdr->release(hdr);
20642062
}
20652063

0 commit comments

Comments
 (0)