Received: by 2002:ac0:a581:0:0:0:0:0 with SMTP id m1-v6csp618886imm; Mon, 2 Jul 2018 18:52:38 -0700 (PDT) X-Google-Smtp-Source: AAOMgpe66IsMA+Zyc3QhD72cTxnYnGiROoFfv7AH+kyfp1eBhu52p9xq5qdvTH2CFLGNnyXL+8IC X-Received: by 2002:a63:4203:: with SMTP id p3-v6mr22117994pga.184.1530582758382; Mon, 02 Jul 2018 18:52:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1530582758; cv=none; d=google.com; s=arc-20160816; b=kj+qb4vep+lsX5Y5k++0DZLvLhuT3Z9J/4soidfyx/N178BM7kbhrlRMmJOJU6UKEP aj5Ms6YXXKmYb0Zied+ne/9XtE2ZJ/jPV+ECQOhCnSqkfw4BLY15zFhcoZdO0QVhZkVq 4s8cvpiZptsgRI13yrdhM1ONs+9fJSfIRGUyMf/iATJBEQ+IdkqqDmT893UN5MX/b6mV e5I4fJemYllOWUmWuOsi1xeWviKf1Bw/vYPpR4eoFha/9/vSSKa31aksARQTyA9ZQuwM h7ohonr5XC05u3FAWBe7iO+EYJIdyonXHOOloiB96TOZqZw5CZFEEQdn/bYiOIH/VAa3 56Tg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=XIXe94Z1LHUVFgSE/07hlJEZPtIxEKaEpXiKFmwdozw=; b=hQuFBEe/nsKOqGtFHmaQZenbBjUqgYq4udQX+lDfzq43ygs4Ibo2HQlpDeQnHA9p04 g8funup6V4GIADaXW8lPDwWXrF3tMDfc6kKO7FNj8kPDyBcb0hmjt1V2rrPJH0cafUc2 z0J0BzRSqIWcJbn6jENgj88jhvgJnxdJp5gQIcTzO4Z4q4JBWrqIFaXOWVgqZNW9htiB 7Qhlht31X8ijgeWbI6adv6Y9hlUCOFQTJYHbu4l0YsxPAMD+KBP0sCeeElgdSpwnnrnl 72XvfhO7z/yX960BnC2VDoF6ba6hKNauwPXMp0JFj9ff8H0RuVCSxR/ee+EdZ05MC4jU Q4PA== 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r4-v6si7017416pgb.97.2018.07.02.18.52.24; Mon, 02 Jul 2018 18:52:38 -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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753797AbeGCBvh (ORCPT + 99 others); Mon, 2 Jul 2018 21:51:37 -0400 Received: from mga07.intel.com ([134.134.136.100]:5207 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753697AbeGCBvX (ORCPT ); Mon, 2 Jul 2018 21:51:23 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 02 Jul 2018 18:51:22 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,301,1526367600"; d="scan'208";a="212956416" Received: from sai-dev-mach.sc.intel.com ([143.183.140.52]) by orsmga004.jf.intel.com with ESMTP; 02 Jul 2018 18:51:18 -0700 From: Sai Praneeth Prakhya To: linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Sai Praneeth , Lee Chun-Yi , Dave Young , Borislav Petkov , Laszlo Ersek , Jan Kiszka , Dave Hansen , Bhupesh Sharma , Nicolai Stange , Naresh Bhat , Ricardo Neri , Peter Zijlstra , Taku Izumi , Ravi Shankar , Matt Fleming , Dan Williams , Ard Biesheuvel Subject: [PATCH 6/6] efi: Fix unaligned fake memmap entries corrupting efi memory map Date: Mon, 2 Jul 2018 18:50:54 -0700 Message-Id: <1530582654-25662-7-git-send-email-sai.praneeth.prakhya@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1530582654-25662-1-git-send-email-sai.praneeth.prakhya@intel.com> References: <1530582654-25662-1-git-send-email-sai.praneeth.prakhya@intel.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Sai Praneeth efi_fake_memmap() inserts user given fake memory map entries into the original efi memory map using efi_memmmap_insert(). efi_memmmap_insert() checks for EFI_PAGE_SIZE alignment and could fail if an unaligned efi memory region is passed (Eg: efi_fake_memmap=1K@0x73ae0000: 0x8000000000000000). Since EFI_PAGE_SIZE is 4K the above request fails, but efi_fake_memmap() doesn't check for failures in efi_memmap_insert() and installs an empty efi memory map from efi_memmap_alloc(). Since efi memory map is corrupted all the later efi calls fail too. Hence, fix this bug by changing the return type of efi_memmap_insert() from void to int. Signed-off-by: Sai Praneeth Prakhya Suggested-by: Ard Biesheuvel Cc: Lee Chun-Yi Cc: Dave Young Cc: Borislav Petkov Cc: Laszlo Ersek Cc: Jan Kiszka Cc: Dave Hansen Cc: Bhupesh Sharma Cc: Nicolai Stange Cc: Naresh Bhat Cc: Ricardo Neri Cc: Peter Zijlstra Cc: Taku Izumi Cc: Ravi Shankar Cc: Matt Fleming Cc: Dan Williams Cc: Ard Biesheuvel --- arch/x86/platform/efi/quirks.c | 8 +++++++- drivers/firmware/efi/fake_mem.c | 11 +++++++++-- drivers/firmware/efi/memmap.c | 12 ++++++++---- include/linux/efi.h | 4 ++-- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c index 8fce327387e5..0e607ac24a3b 100644 --- a/arch/x86/platform/efi/quirks.c +++ b/arch/x86/platform/efi/quirks.c @@ -290,7 +290,13 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size) return; } - efi_memmap_insert(&efi.memmap, new, &mr); + if (efi_memmap_insert(&efi.memmap, new, &mr)) { + pr_err("Failed to reserve EFI memory region\n"); + early_memunmap(new, new_size); + efi_memmap_free(new_phys, num_entries, alloc_type); + return; + } + early_memunmap(new, new_size); /* Free existing memory map before installing new memory map */ diff --git a/drivers/firmware/efi/fake_mem.c b/drivers/firmware/efi/fake_mem.c index 09b0fabf07fd..ae373af6931b 100644 --- a/drivers/firmware/efi/fake_mem.c +++ b/drivers/firmware/efi/fake_mem.c @@ -84,8 +84,15 @@ void __init efi_fake_memmap(void) return; } - for (i = 0; i < nr_fake_mem; i++) - efi_memmap_insert(&efi.memmap, new_memmap, &fake_mems[i]); + for (i = 0; i < nr_fake_mem; i++) { + if (efi_memmap_insert(&efi.memmap, new_memmap, &fake_mems[i])) { + pr_err("efi_fake_mem: Failed to create fake memmap\n"); + early_memunmap(new_memmap, + efi.memmap.desc_size * new_nr_map); + efi_memmap_free(new_memmap_phy, new_nr_map, alloc_type); + return; + } + } /* swap into new EFI memmap */ early_memunmap(new_memmap, efi.memmap.desc_size * new_nr_map); diff --git a/drivers/firmware/efi/memmap.c b/drivers/firmware/efi/memmap.c index d4e3e114cf86..05a556e63ec2 100644 --- a/drivers/firmware/efi/memmap.c +++ b/drivers/firmware/efi/memmap.c @@ -290,9 +290,11 @@ int __init efi_memmap_split_count(efi_memory_desc_t *md, struct range *range) * * It is suggested that you call efi_memmap_split_count() first * to see how large @buf needs to be. + * + * Returns zero on success, a negative error code on failure. */ -void __init efi_memmap_insert(struct efi_memory_map *old_memmap, void *buf, - struct efi_mem_range *mem) +int __init efi_memmap_insert(struct efi_memory_map *old_memmap, void *buf, + struct efi_mem_range *mem) { u64 m_start, m_end, m_attr; efi_memory_desc_t *md; @@ -311,8 +313,9 @@ void __init efi_memmap_insert(struct efi_memory_map *old_memmap, void *buf, */ if (!IS_ALIGNED(m_start, EFI_PAGE_SIZE) || !IS_ALIGNED(m_end + 1, EFI_PAGE_SIZE)) { - WARN_ON(1); - return; + WARN(1, "Address 0x%llx - 0x%llx is not EFI_PAGE_SIZE aligned", + m_start, m_end); + return -EINVAL; } for (old = old_memmap->map, new = buf; @@ -379,4 +382,5 @@ void __init efi_memmap_insert(struct efi_memory_map *old_memmap, void *buf, md->attribute |= m_attr; } } + return 0; } diff --git a/include/linux/efi.h b/include/linux/efi.h index c9752c67d184..bca955205a3f 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -1023,8 +1023,8 @@ extern int __init efi_memmap_install(phys_addr_t addr, unsigned int nr_map, enum efi_memmap_type alloc_type); extern int __init efi_memmap_split_count(efi_memory_desc_t *md, struct range *range); -extern void __init efi_memmap_insert(struct efi_memory_map *old_memmap, - void *buf, struct efi_mem_range *mem); +extern int __init efi_memmap_insert(struct efi_memory_map *old_memmap, + void *buf, struct efi_mem_range *mem); extern void __init efi_memmap_free(phys_addr_t mem, unsigned int num_entries, enum efi_memmap_type alloc_type); -- 2.7.4