Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp4843937imm; Tue, 19 Jun 2018 00:24:07 -0700 (PDT) X-Google-Smtp-Source: ADUXVKK0Qii6yJwe2tWr+kQX630Jczq23MAXLNkB78mjdQSlfRFDxI1CROoyfnKSUi1GeWurwkJv X-Received: by 2002:a65:6141:: with SMTP id o1-v6mr13643046pgv.409.1529393047252; Tue, 19 Jun 2018 00:24:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1529393047; cv=none; d=google.com; s=arc-20160816; b=i65F4oWDrgl9SHBXleCaqKVn5ezEzob32Ian8hgFfTlkjLFEW0xy9ZSsOMu7yWnoJ0 0mSC0vPwIA0gK59pS6YekZVf+wWd2+Snn+N7o++FdDjj4DetY3uWFwvGflKAJAd6Zetj jd8tTioORb8+WLy6mYJ2ix+2z5ODKkCixNMrYDZdK7ix/bWBWknLQPra4Pl1yUt1DArs WVThT2Jt7oUi5cxqQ1+K7eyAvMMDBcRz7COvPbxkDKYVN14C0qNfWSXdE/NN7+0Qh6TZ SLyk++UJ1tD23XlDif+Coya3/SIX9QmDQoHsEtsIapW6wKrvj170+m3NPABuLcJqQZuq ChTg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :references:in-reply-to:mime-version:dkim-signature :arc-authentication-results; bh=SOdnokf/LZv64a115dKEkgqSsv1uDgCnlaRlPqsdiwM=; b=ZxnJUxzGbOy9e3vG0XmV2j+33D143T4BqCjv9QtQQmQgBi9v8r/ZupOkfL/EL2YSDu yN+7Y6a6AsTkYgig2SU7ulU4PPN/oWUcXaT5+8H9o4PVUlCfcMlZG3NEQOpBdg1AQU0P uVaYwHuYLI/ihFe2ds41ALTBp4oEiZaR9Pzdc6n5Kn+kkQpeLMg3iAEQd43Li/YeOxFO OtGl3gJIb23Mu9go5SxAQTuf8SCzpDxewoPgZ6O8eHA5bHL7hyuOboDZiDVhhPrV70CC S0puF5sbwT78XG6RentnEq/eCq/5iU33Iqn1/X1bzbVleYNk2/qEvycW8WmcNyLyYLdV ya1g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=DRlaj74p; 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=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i8-v6si13846380pgf.649.2018.06.19.00.23.53; Tue, 19 Jun 2018 00:24:07 -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=@linaro.org header.s=google header.b=DRlaj74p; 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=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756270AbeFSHVb (ORCPT + 99 others); Tue, 19 Jun 2018 03:21:31 -0400 Received: from mail-it0-f65.google.com ([209.85.214.65]:35419 "EHLO mail-it0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755658AbeFSHV3 (ORCPT ); Tue, 19 Jun 2018 03:21:29 -0400 Received: by mail-it0-f65.google.com with SMTP id a3-v6so15771028itd.0 for ; Tue, 19 Jun 2018 00:21:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=SOdnokf/LZv64a115dKEkgqSsv1uDgCnlaRlPqsdiwM=; b=DRlaj74pXXpP8BIn+IPHuTYI7igFFuO7ejzaqwN8A9zOu6nD/KMpDRjOSBisQSXe26 FY0bbCze1t1Z0B2y9tS/8PBqyzlBfwuPdZ6EB9ZLLRnOq2k4ZOWOH1N7Y13X/zWm6Gf3 0oZPhww1KjRUhOXN98J5l2iM2gQxEJZ1u3pfo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=SOdnokf/LZv64a115dKEkgqSsv1uDgCnlaRlPqsdiwM=; b=Jyj0J59w7rd2FUp+ufoO3EjmT04xmiyl/nN8xhfqMSWEg0V6LA+vNVZbKw3cGlsP93 unw4BC8UNAJam+Dm9SqALEIfegMogSjpTUGdSOFMYVnyK4oO1Gc4GpXq0qFP67qNNrCs lZHoTy5FXOYj68TEglHgr0q0mjw4HMIjzGUVle4FFKDgt+/X3IU8SI0p/XFWPQ5+PcKK lYG5Km8Hf63tjcPA1xFG4PUvsT1aLDjloCdGHbIW/j56D4D6r0P6f2E5VMeB4B9CSyu5 my2nyuT+HFXmRzUii5TMd2KL14b+V8rimEIwoKAnL9NvDiBJGs4g/6yRtG3FQFr93cbI ue3g== X-Gm-Message-State: APt69E0DQQhJ/5oOITYehcxOFjyiEJj97rMJGeTkkWZ/3M31H14yvi3h 0QuqR5W3jMQLautoBO/tQ4Xx0Taab8B2mCMXl+R4aQ== X-Received: by 2002:a24:3105:: with SMTP id y5-v6mr12167332ity.138.1529392888569; Tue, 19 Jun 2018 00:21:28 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:a6b:bbc7:0:0:0:0:0 with HTTP; Tue, 19 Jun 2018 00:21:28 -0700 (PDT) In-Reply-To: <1529350614-15555-1-git-send-email-sai.praneeth.prakhya@intel.com> References: <1529350614-15555-1-git-send-email-sai.praneeth.prakhya@intel.com> From: Ard Biesheuvel Date: Tue, 19 Jun 2018 09:21:28 +0200 Message-ID: Subject: Re: [PATCH V2] x86/efi: Free allocated memory if remap fails To: Sai Praneeth Prakhya Cc: linux-efi , Linux Kernel Mailing List , Lee Chun-Yi , Borislav Petkov , Tony Luck , Dave Hansen , Bhupesh Sharma , Ricardo Neri , Peter Zijlstra , Ravi Shankar , Matt Fleming Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 18 June 2018 at 21:36, Sai Praneeth Prakhya wrote: > From: Sai Praneeth > > efi_memmap_alloc(), as the name suggests, allocates memory for a new efi > memory map. It's referenced from couple of places, namely, > efi_arch_mem_reserve() and efi_free_boot_services(). These callers, > after allocating memory, remap it for further use. As usual, a routine > check is performed to confirm successful remap. If the remap fails, > ideally, the allocated memory should be freed but presently we just > return without freeing it up. Hence, fix this bug by freeing up the > memory appropriately. > > As efi_memmap_alloc() allocates memory depending on whether mm_init() > has already been invoked or not, similarly, while freeing use > memblock_free() to free memory allocated before invoking mm_init() and > __free_pages() to free memory allocated after invoking mm_init(). > > It's a fact that memremap() and early_memremap() might never fail and > this code might never get a chance to run but to maintain good kernel > programming semantics, we might need this patch. > > Signed-off-by: Sai Praneeth Prakhya > Cc: Lee Chun-Yi > Cc: Borislav Petkov > Cc: Tony Luck > Cc: Dave Hansen > Cc: Bhupesh Sharma > Cc: Ricardo Neri > Cc: Peter Zijlstra > Cc: Ravi Shankar > Cc: Matt Fleming > Cc: Ard Biesheuvel > --- > > I found this bug when working on a different patch set which uses > efi_memmap_alloc() and then noticed that I never freed the allocated > memory. I found it weird, in the sense that, memory is allocated but is > not freed (upon returning from an error). So, wasn't sure if that should > be treated as a bug or should I just leave it as is because everything > works fine even without this patch. Since the effort for the patch is > very minimal, I just went ahead and posted one, so that I could know > your thoughts on it. > > Changes from V1 to V2: > ---------------------- > 1. Fix the bug of freeing memory map that was just installed by correctly > calling free_pages(). > 2. Call memblock_free() and __free_pages() directly from the appropriate > places instead of efi_memmap_free(). > > Note: Patch based on Linus's mainline tree V4.18-rc1 > > arch/x86/platform/efi/quirks.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c > index 36c1f8b9f7e0..cfa93af97def 100644 > --- a/arch/x86/platform/efi/quirks.c > +++ b/arch/x86/platform/efi/quirks.c > @@ -285,6 +285,7 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size) > new = early_memremap(new_phys, new_size); > if (!new) { > pr_err("Failed to map new boot services memmap\n"); > + memblock_free(new_phys, new_size); > return; > } > > @@ -429,6 +430,7 @@ void __init efi_free_boot_services(void) > new = memremap(new_phys, new_size, MEMREMAP_WB); > if (!new) { > pr_err("Failed to map new EFI memmap\n"); > + __free_pages(pfn_to_page(PHYS_PFN(new_phys)), get_order(new_size)); > return; > } > > @@ -452,6 +454,7 @@ void __init efi_free_boot_services(void) > > if (efi_memmap_install(new_phys, num_entries)) { > pr_err("Could not install new EFI memmap\n"); > + __free_pages(pfn_to_page(PHYS_PFN(new_phys)), get_order(new_size)); > return; > } > } > -- > 2.7.4 > Thank you Sai. But this is not really what I meant. How about we modify efi_memmap_alloc() like this @@ -39,10 +39,12 @@ static phys_addr_t __init __efi_memmap_alloc_late(unsigned long size) * Returns the physical address of the allocated memory map on * success, zero on failure. */ -phys_addr_t __init efi_memmap_alloc(unsigned int num_entries) +phys_addr_t __init efi_memmap_alloc(unsigned int num_entries, bool *late) { unsigned long size = num_entries * efi.memmap.desc_size; + if (late) + *late = slab_is_available(); if (slab_is_available()) return __efi_memmap_alloc_late(size); and introduce efi_memmap_free() as before, but pass it the 'late' parameter you received from efi_memmap_alloc(). That way, it is the caller's job to take care of this. Also, it seems to me that efi_arch_mem_reserve() leaks the old memory map every time you create a new one, no? That is a separate issue that you may want to look into, but it affects the design of this API as well.