From patchwork Mon Aug 14 12:54:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 9898873 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9CEE0602BA for ; Mon, 14 Aug 2017 13:00:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 91BAE2860E for ; Mon, 14 Aug 2017 13:00:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8648F28628; Mon, 14 Aug 2017 13:00:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id 86BC72860E for ; Mon, 14 Aug 2017 13:00:20 +0000 (UTC) Received: (qmail 30235 invoked by uid 550); 14 Aug 2017 12:56:17 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 30113 invoked from network); 14 Aug 2017 12:56:13 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=zvKWkV5hh1GX1FJZjTc/7qPWFTrhMCPREjjv8pVUjgk=; b=Ks2E82pi+eIceAm+yPhTmB37IMYnuIbFc04jzKufbHq+upaxRv0liKxx0WmxAMx0Ao YjC/WSL5lQnxs9md0UAw/4UEXlb22h3QqWJWt2prZdkaVTowGyvfusje1/BGKKn3HW60 /yeDrijw0/7v0GBR2kKOqvwCWZ0v0Cjr7aAIo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=zvKWkV5hh1GX1FJZjTc/7qPWFTrhMCPREjjv8pVUjgk=; b=jVXkVfqldZ4cmf0syRhd++HmLEyPsAmNOj7YDdzeeqwGO66tJbPrv4fNXAPneZlUYy 7mw7nXTPJzoajvYC3JaVycDQ+sB6jVgSATWIwc6nReqPxcUoM642P8ia1ctqjP64ueqr ErvVTiiwsiQOrm3O7Z2qEGh3S8r3Jnga2Aq/B9WFsxhjq0I6hJOn+7m/uAvInkJ+muxs EefXlZcOoo3ZAkUawRVihfCcGdW9k3P6EJNWiL83Kylhb99poTiuq7NrVaBWRJqkcqRd ///zE5zo0BnYGopsewokobyMnHpEmfDRP8THwuG8uB39W7iZOB8xWN/E0MrPeaCnS94G fgUw== X-Gm-Message-State: AHYfb5gCNYnZPJY9ECuc6Gf96XZPxQadPqBCoJ0ZcNDew3oTGY7/68AJ T+d2EjFtEqTiv4UINhRPDQ== X-Received: by 10.223.166.162 with SMTP id t31mr15210763wrc.52.1502715361424; Mon, 14 Aug 2017 05:56:01 -0700 (PDT) From: Ard Biesheuvel To: kernel-hardening@lists.openwall.com Cc: linux-arm-kernel@lists.infradead.org, Ard Biesheuvel , Arnd Bergmann , Nicolas Pitre , Russell King , Kees Cook , Thomas Garnier , Marc Zyngier , Mark Rutland , Tony Lindgren , Matt Fleming , Dave Martin Date: Mon, 14 Aug 2017 13:54:11 +0100 Message-Id: <20170814125411.22604-31-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170814125411.22604-1-ard.biesheuvel@linaro.org> References: <20170814125411.22604-1-ard.biesheuvel@linaro.org> Subject: [kernel-hardening] [PATCH 30/30] efi/libstub: arm: implement KASLR X-Virus-Scanned: ClamAV using ClamSMTP This wires up the new KASLR implementation for ARM to the random number generator and memory allocation routines in the UEFI stub. Given how the UEFI stub keeps track of the placement of the DTB and potentially an initrd via its memory map, we can quite simply use efi_random_alloc() to carve out a window for the kernel proper, and inform the decompressor about this by setting the kaslr_offset variable directly. Since the presence of a vmalloc= command line option complicates the calculations involved, let's just disable KASLR for now if a vmalloc= command line argument was provided. Cc: Matt Fleming Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/arm32-stub.c | 46 +++++++++++++++++++- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/efi/libstub/arm32-stub.c b/drivers/firmware/efi/libstub/arm32-stub.c index becbda445913..f812cbca08ee 100644 --- a/drivers/firmware/efi/libstub/arm32-stub.c +++ b/drivers/firmware/efi/libstub/arm32-stub.c @@ -8,6 +8,8 @@ */ #include #include +#include +#include #include "efistub.h" @@ -200,6 +202,29 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table, efi_loaded_image_t *image) { efi_status_t status; + u32 phys_seed = 0; + + if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) { + if (have_vmalloc()) { + pr_efi(sys_table, + "vmalloc= command line argument found, disabling KASLR\n"); + } else if (!nokaslr()) { + status = efi_get_random_bytes(sys_table, + sizeof(phys_seed), + (u8 *)&phys_seed); + if (status == EFI_NOT_FOUND) { + pr_efi(sys_table, + "EFI_RNG_PROTOCOL unavailable, no randomness supplied\n"); + } else if (status != EFI_SUCCESS) { + pr_efi_err(sys_table, + "efi_get_random_bytes() failed\n"); + return status; + } + } else { + pr_efi(sys_table, + "KASLR disabled on kernel command line\n"); + } + } /* * Verify that the DRAM base address is compatible with the ARM @@ -210,8 +235,25 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table, */ dram_base = round_up(dram_base, SZ_128M); - status = reserve_kernel_base(sys_table, dram_base, reserve_addr, - reserve_size); + if (!IS_ENABLED(CONFIG_RANDOMIZE_BASE) || phys_seed == 0) { + status = reserve_kernel_base(sys_table, dram_base, reserve_addr, + reserve_size); + } else { + /* the end of the lowmem region */ + unsigned long max = dram_base + VMALLOC_DEFAULT_BASE + - PAGE_OFFSET - 1; + /* + * The DTB and initrd are covered by allocations in the UEFI + * memory map, so we can create a random allocation for the + * uncompressed kernel, and inform the decompressor about the + * offset with respect to the base of memory. + */ + *reserve_size = MAX_UNCOMP_KERNEL_SIZE; + status = efi_random_alloc(sys_table, *reserve_size, SZ_2M, + reserve_addr, phys_seed, max); + kaslr_offset = *reserve_addr - dram_base; + } + if (status != EFI_SUCCESS) { pr_efi_err(sys_table, "Unable to allocate memory for uncompressed kernel.\n"); return status;