From: Trond Myklebust Date: Tue, 25 Apr 2017 15:26:53 +0000 (-0400) Subject: pNFS: Fix use after free issues in pnfs_do_read() X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=6aeafd05eca9bc8ab6b03d7e56d09ffd18190f44;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git pNFS: Fix use after free issues in pnfs_do_read() The assumption should be that if the caller returns PNFS_ATTEMPTED, then hdr has been consumed, and so we should not be testing hdr->task.tk_status. If the caller returns PNFS_TRY_AGAIN, then we need to recoalesce and free hdr. Signed-off-by: Trond Myklebust --- diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 634adb3f8524..eff266ea813c 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -2419,10 +2419,20 @@ pnfs_do_read(struct nfs_pageio_descriptor *desc, struct nfs_pgio_header *hdr) enum pnfs_try_status trypnfs; trypnfs = pnfs_try_to_read_data(hdr, call_ops, lseg); - if (trypnfs == PNFS_TRY_AGAIN) - pnfs_read_resend_pnfs(hdr); - if (trypnfs == PNFS_NOT_ATTEMPTED || hdr->task.tk_status) + switch (trypnfs) { + case PNFS_NOT_ATTEMPTED: pnfs_read_through_mds(desc, hdr); + case PNFS_ATTEMPTED: + break; + case PNFS_TRY_AGAIN: + /* cleanup hdr and prepare to redo pnfs */ + if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) { + struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(desc); + list_splice_init(&hdr->pages, &mirror->pg_list); + mirror->pg_recoalesce = 1; + } + hdr->mds_ops->rpc_release(hdr); + } } static void pnfs_readhdr_free(struct nfs_pgio_header *hdr)