Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp2292579imm; Thu, 7 Jun 2018 08:17:51 -0700 (PDT) X-Google-Smtp-Source: ADUXVKL279tspvgrGwZRM12Yl0Gj9jhl0Vkvdyx/bxWcElQTehpJIUfEVJ4hoEWsuYxNN70Wwai0 X-Received: by 2002:a63:6107:: with SMTP id v7-v6mr1995338pgb.264.1528384671329; Thu, 07 Jun 2018 08:17:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1528384671; cv=none; d=google.com; s=arc-20160816; b=mGd2UcepkTSDSumXbKCKIxUq4j2wco/HQp9G53I1XB0nwLU8r0EfjUWVj6pnbO1bZJ cOstWinS6HkAgsyvsbiwRKSBQdVpru6C9E5eBGP4tU1A9djVbbHr0Kv2kYjlGIAkHpSE ++MFFcyt4DCh3GHEWhXP+olu99ikkNRXsXjSucn+eLr5DYTAXI6ZFbUJ5lcoYwMGf8gl YJYmeKwT3zF7803bsbcBxKTGySWEKPi3FbBzOEZr0vBFYcOJEd+IaNTGIkuA5zCn1Rlr wsVFy1xH1xdGyXvt/gZWafTt805f+L4fakAjuvTo93o7tuHRbmfgfkyjkjqfRGNSeh6L 8qvg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:subject:message-id:date:cc:to :from:mime-version:content-transfer-encoding:content-disposition :arc-authentication-results; bh=txVUPvzlXaga/ODUIX13hF1CiNmAAxX0zq8fFOpyxJU=; b=CQKuX9X27SUG1NG6Ibs5Rs+KOkGnWZOOdSlScZHjiERLWnmz0YQRI53Nj1HzyFa+I5 JGU9W4At3Onh1EzomsTFp02RzMGXueVJxbA4bjkFcLkjx1anxazT0hVusV5/sHo+fhfr 9g41YbygP/kRPQQYR8eDJV4vfaxqdEsHJkASwpYtZ7tF/p8ylpP9GyKMxY0Y4wyRaB0Q rFqNNHf3rlM6B7sxUEKyTNEZeW1q3LE2bW8Ulz7+4rfOmuV/2NR9SiVQYLxb1oVV653F 7dQ99awm+ezoA2qc6+RGBVTixBNJ9Yr5Cj4MixXXbXHkqGeL2he5FsR7FwjvKQtCLpnl UeUg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w12-v6si35084199plq.595.2018.06.07.08.17.36; Thu, 07 Jun 2018 08:17:51 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935837AbeFGPA4 (ORCPT + 99 others); Thu, 7 Jun 2018 11:00:56 -0400 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:41360 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935192AbeFGPAx (ORCPT ); Thu, 7 Jun 2018 11:00:53 -0400 Received: from [148.252.241.226] (helo=deadeye) by shadbolt.decadent.org.uk with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1fQvbo-0005Zl-Ut; Thu, 07 Jun 2018 15:09:49 +0100 Received: from ben by deadeye with local (Exim 4.91) (envelope-from ) id 1fQvb2-0002rb-Fq; Thu, 07 Jun 2018 15:09:00 +0100 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "Trond Myklebust" Date: Thu, 07 Jun 2018 15:05:21 +0100 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) Subject: [PATCH 3.16 128/410] NFS: Fix 2 use after free issues in the I/O code In-Reply-To: X-SA-Exim-Connect-IP: 148.252.241.226 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.16.57-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Trond Myklebust 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 Signed-off-by: Ben Hutchings --- 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); }