Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp3905118ybi; Mon, 29 Jul 2019 15:03:42 -0700 (PDT) X-Google-Smtp-Source: APXvYqxdEOfgugMn2fUufzlAhQfW6EO4PDMTEPNYdzXSsSMJs0GRfLEZYO01F832YoAEkgllrIdh X-Received: by 2002:a17:902:f81:: with SMTP id 1mr17258873plz.191.1564437822594; Mon, 29 Jul 2019 15:03:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1564437822; cv=none; d=google.com; s=arc-20160816; b=MRKQSktD5+gByGm1ViCl9PlEkIMiVBY5v/pea3FGIcipQu30z7pM15Y7Z7S7nf/Mch ZTOKNtkDnxtq/I7pEUejyNEf1my266C0JFXJyhlch5ysQUVRHY4SGxZsP1GtPVqg2a8L I6z/95DcZeSuLjrf9VRqDGt5RbQNuJe1j5IHp07GFUFPF5wASe3cA/22mDHbptCa+2AJ 9M7WDpCkt2+zFL2N9pzy+l3/79w5oLrTcs43Mxx7do3QwiNDlpAd3IWycpPES3De4BmG Cq2izM+8+YKBfP+jwD4q7q0wH6zZHNlWrBFFHHBXo1TnB2iwfZzp9ZUSyLLKmn51OD0s /ztw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=gN6jyHCKhyZ+/VkAhHppNGY63fKWMkqjv5u8z8HEsEc=; b=XuJVDrebDhpYuT8KYlu8e430uJoCED1AxwgLeB9zRri1GQXaOwp3OF2HSqIlXEZnBV pAOv8yJiZleNgF9RqJg3zEomkTQCd0exc/2VRCSxWWdkn5AebHYMW9NpajBj4b3wV9op wTr0v5ZC5hqbI6peRzQXUOcq//JmBqDomxf6RLwQrB9ZMxHUGmCUZCfo5L6ulhB787Zt PTmkydBW8Sc1Khz2IENwkLVGM+h+/SBZyWRQ95a5+2VViclIvG0gHwWsqUDNGcdm0vEb lVkSRxfEUwdZaT4Ml/SRoY3bERhOnvtnc97a++5G5EkPk3jpcjoiLFsO6bsEN8LLn3Fy 65ZA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=c8OFItFl; 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 gb4si26816527plb.429.2019.07.29.15.03.27; Mon, 29 Jul 2019 15:03:42 -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; dkim=pass header.i=@kernel.org header.s=default header.b=c8OFItFl; 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 S1730171AbfG2Tb4 (ORCPT + 99 others); Mon, 29 Jul 2019 15:31:56 -0400 Received: from mail.kernel.org ([198.145.29.99]:44856 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730191AbfG2Tbw (ORCPT ); Mon, 29 Jul 2019 15:31:52 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 7F90B21655; Mon, 29 Jul 2019 19:31:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1564428711; bh=0W16tsMQAcxB/cu+dIZ70l3X1En5LlP5plGhVJf4liE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=c8OFItFlk8oSJbwusZNV5sL5UhnFnT4TdYmUuzAkr6Ffsp6bFiXig6g1j5iUj0Syz GnWttL9CSJs9E5ceAXu5S3OF0flsg7Nk99/of8IGvykXz9A8sRmGgZsX+EbZL0Bce5 pv2cEubmRcnK0s741rz5KqZzB3cjd6jmsDfN3StU= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Dan Williams , David Hildenbrand , Jane Chu , Jeff Moyer , =?UTF-8?q?J=C3=A9r=C3=B4me=20Glisse?= , Jonathan Corbet , Logan Gunthorpe , Michal Hocko , Mike Rapoport , Oscar Salvador , Pavel Tatashin , Toshi Kani , Vlastimil Babka , Wei Yang , Jason Gunthorpe , Christoph Hellwig , Andrew Morton , Linus Torvalds , "Aneesh Kumar K . V" Subject: [PATCH 4.14 162/293] libnvdimm/pfn: fix fsdax-mode namespace info-block zero-fields Date: Mon, 29 Jul 2019 21:20:53 +0200 Message-Id: <20190729190836.979840257@linuxfoundation.org> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190729190820.321094988@linuxfoundation.org> References: <20190729190820.321094988@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Dan Williams commit 7e3e888dfc138089f4c15a81b418e88f0978f744 upstream. At namespace creation time there is the potential for the "expected to be zero" fields of a 'pfn' info-block to be filled with indeterminate data. While the kernel buffer is zeroed on allocation it is immediately overwritten by nd_pfn_validate() filling it with the current contents of the on-media info-block location. For fields like, 'flags' and the 'padding' it potentially means that future implementations can not rely on those fields being zero. In preparation to stop using the 'start_pad' and 'end_trunc' fields for section alignment, arrange for fields that are not explicitly initialized to be guaranteed zero. Bump the minor version to indicate it is safe to assume the 'padding' and 'flags' are zero. Otherwise, this corruption is expected to benign since all other critical fields are explicitly initialized. Note The cc: stable is about spreading this new policy to as many kernels as possible not fixing an issue in those kernels. It is not until the change titled "libnvdimm/pfn: Stop padding pmem namespaces to section alignment" where this improper initialization becomes a problem. So if someone decides to backport "libnvdimm/pfn: Stop padding pmem namespaces to section alignment" (which is not tagged for stable), make sure this pre-requisite is flagged. Link: http://lkml.kernel.org/r/156092356065.979959.6681003754765958296.stgit@dwillia2-desk3.amr.corp.intel.com Fixes: 32ab0a3f5170 ("libnvdimm, pmem: 'struct page' for pmem") Signed-off-by: Dan Williams Tested-by: Aneesh Kumar K.V [ppc64] Cc: Cc: David Hildenbrand Cc: Jane Chu Cc: Jeff Moyer Cc: Jérôme Glisse Cc: Jonathan Corbet Cc: Logan Gunthorpe Cc: Michal Hocko Cc: Mike Rapoport Cc: Oscar Salvador Cc: Pavel Tatashin Cc: Toshi Kani Cc: Vlastimil Babka Cc: Wei Yang Cc: Jason Gunthorpe Cc: Christoph Hellwig Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/nvdimm/dax_devs.c | 2 +- drivers/nvdimm/pfn.h | 1 + drivers/nvdimm/pfn_devs.c | 18 +++++++++++++++--- 3 files changed, 17 insertions(+), 4 deletions(-) --- a/drivers/nvdimm/dax_devs.c +++ b/drivers/nvdimm/dax_devs.c @@ -126,7 +126,7 @@ int nd_dax_probe(struct device *dev, str nvdimm_bus_unlock(&ndns->dev); if (!dax_dev) return -ENOMEM; - pfn_sb = devm_kzalloc(dev, sizeof(*pfn_sb), GFP_KERNEL); + pfn_sb = devm_kmalloc(dev, sizeof(*pfn_sb), GFP_KERNEL); nd_pfn->pfn_sb = pfn_sb; rc = nd_pfn_validate(nd_pfn, DAX_SIG); dev_dbg(dev, "%s: dax: %s\n", __func__, --- a/drivers/nvdimm/pfn.h +++ b/drivers/nvdimm/pfn.h @@ -36,6 +36,7 @@ struct nd_pfn_sb { __le32 end_trunc; /* minor-version-2 record the base alignment of the mapping */ __le32 align; + /* minor-version-3 guarantee the padding and flags are zero */ u8 padding[4000]; __le64 checksum; }; --- a/drivers/nvdimm/pfn_devs.c +++ b/drivers/nvdimm/pfn_devs.c @@ -361,6 +361,15 @@ struct device *nd_pfn_create(struct nd_r return dev; } +/** + * nd_pfn_validate - read and validate info-block + * @nd_pfn: fsdax namespace runtime state / properties + * @sig: 'devdax' or 'fsdax' signature + * + * Upon return the info-block buffer contents (->pfn_sb) are + * indeterminate when validation fails, and a coherent info-block + * otherwise. + */ int nd_pfn_validate(struct nd_pfn *nd_pfn, const char *sig) { u64 checksum, offset; @@ -506,7 +515,7 @@ int nd_pfn_probe(struct device *dev, str nvdimm_bus_unlock(&ndns->dev); if (!pfn_dev) return -ENOMEM; - pfn_sb = devm_kzalloc(dev, sizeof(*pfn_sb), GFP_KERNEL); + pfn_sb = devm_kmalloc(dev, sizeof(*pfn_sb), GFP_KERNEL); nd_pfn = to_nd_pfn(pfn_dev); nd_pfn->pfn_sb = pfn_sb; rc = nd_pfn_validate(nd_pfn, PFN_SIG); @@ -637,7 +646,7 @@ static int nd_pfn_init(struct nd_pfn *nd u64 checksum; int rc; - pfn_sb = devm_kzalloc(&nd_pfn->dev, sizeof(*pfn_sb), GFP_KERNEL); + pfn_sb = devm_kmalloc(&nd_pfn->dev, sizeof(*pfn_sb), GFP_KERNEL); if (!pfn_sb) return -ENOMEM; @@ -646,11 +655,14 @@ static int nd_pfn_init(struct nd_pfn *nd sig = DAX_SIG; else sig = PFN_SIG; + rc = nd_pfn_validate(nd_pfn, sig); if (rc != -ENODEV) return rc; /* no info block, do init */; + memset(pfn_sb, 0, sizeof(*pfn_sb)); + nd_region = to_nd_region(nd_pfn->dev.parent); if (nd_region->ro) { dev_info(&nd_pfn->dev, @@ -704,7 +716,7 @@ static int nd_pfn_init(struct nd_pfn *nd memcpy(pfn_sb->uuid, nd_pfn->uuid, 16); memcpy(pfn_sb->parent_uuid, nd_dev_to_uuid(&ndns->dev), 16); pfn_sb->version_major = cpu_to_le16(1); - pfn_sb->version_minor = cpu_to_le16(2); + pfn_sb->version_minor = cpu_to_le16(3); pfn_sb->start_pad = cpu_to_le32(start_pad); pfn_sb->end_trunc = cpu_to_le32(end_trunc); pfn_sb->align = cpu_to_le32(nd_pfn->align);