From patchwork Sun Sep 3 12:07:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 9936187 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 1E1EE603D7 for ; Sun, 3 Sep 2017 12:14:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0F8872623C for ; Sun, 3 Sep 2017 12:14:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 043272623D; Sun, 3 Sep 2017 12:14:44 +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 3E81127D16 for ; Sun, 3 Sep 2017 12:14:40 +0000 (UTC) Received: (qmail 21625 invoked by uid 550); 3 Sep 2017 12:10:00 -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 20465 invoked from network); 3 Sep 2017 12:09:58 -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=Nn/HmMRyr90Xqri1BT8ZO2AoWegxPtKsE7O407vskg0=; b=fJbm/kmxvaa/OGedyIfYD5MULWYEXKolaHpJ3NvIQ4pz1Cqf8r4E/uwI4j/RMBqt0c gnQg8OCslqPzuX5WdCxDkfjqlKrRhjzapqQPWzyT/W7O3KaNswc33u5GmOUnaY+ijT3T imrakEIpalgINX2QX2BUnoH2+8XWSz6Mcrr9g= 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=Nn/HmMRyr90Xqri1BT8ZO2AoWegxPtKsE7O407vskg0=; b=KM2VjdZVGbX2TIfLOiyx/rtD+ZW4Tio2IlKnPsw8ovlLxJPayPylP8hNYftLE3Jkh5 MLADzYOx3g3gE+Uj7vTLwaWgiQlJjGwRXGNu49dyEFcj7RTQWILTgTXdBzB+2Ss3Wlh2 IB+nRQMr/VV0l5VOuHZ7fA5sJGKdoPNOtQeAv8QJJcRS/IjeNt08509i1qSgdINYKWkx YtzFrK81mLrabL85R3Wmplm/L0Xa+Zbgjdt5u717ZsfqThLKQ+sNuszS9KhXG7tQtPmb /ZOOPLGdobaWnhVYbX90e4wHNriTwY25ZOOXgEhpQzB0Xdh+Lzbb9bcEgkYKAiOTbLGc FVzw== X-Gm-Message-State: AHPjjUhw7BAzGsoJ5c67x6TRJdQWEtqbzRks4FzoLeFUM9wae7sZrdMv M7C+gtvES/PmgF6sWdVNJA== X-Google-Smtp-Source: ADKCNb6SwyF04Y8wBSbmXfzj9wl7eZ0SznR8JJK7sJUZ4yPtiFj4SAZfXpJsj8JRpS/50IKr6DN8nA== X-Received: by 10.223.134.108 with SMTP id 41mr2533073wrw.229.1504440587061; Sun, 03 Sep 2017 05:09:47 -0700 (PDT) From: Ard Biesheuvel To: linux-arm-kernel@lists.infradead.org, kernel-hardening@lists.openwall.com Cc: Ard Biesheuvel , Arnd Bergmann , Nicolas Pitre , Russell King , Kees Cook , Thomas Garnier , Marc Zyngier , Mark Rutland , Tony Lindgren , Matt Fleming , Dave Martin Date: Sun, 3 Sep 2017 13:07:57 +0100 Message-Id: <20170903120757.14968-30-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170903120757.14968-1-ard.biesheuvel@linaro.org> References: <20170903120757.14968-1-ard.biesheuvel@linaro.org> Subject: [kernel-hardening] [PATCH v2 29/29] 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 --- arch/arm/boot/compressed/head.S | 12 ++++- drivers/firmware/efi/libstub/arm32-stub.c | 47 +++++++++++++++++++- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 79b4033b0ed4..68d803dfdf3f 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -203,6 +203,15 @@ not_angel: */ mov r4, pc and r4, r4, #0xf8000000 +#if defined(CONFIG_RANDOMIZE_BASE) && defined(CONFIG_EFI_STUB) + /* + * The KASLR randomization may have already been performed by + * the UEFI stub, in which case kaslr_offset will already have + * a value. + */ + ldr r0, kaslr_offset + add r4, r4, r0 +#endif /* Determine final kernel image address. */ add r4, r4, #TEXT_OFFSET #else @@ -1428,7 +1437,8 @@ ENTRY(__crc16) ENDPROC(__crc16) .align 2 -kaslr_offset: .long 0 +ENTRY(kaslr_offset) + .long 0 #ifdef CONFIG_EFI_STUB __efi_boot: .long 0 #endif diff --git a/drivers/firmware/efi/libstub/arm32-stub.c b/drivers/firmware/efi/libstub/arm32-stub.c index becbda445913..73d3694d2fbb 100644 --- a/drivers/firmware/efi/libstub/arm32-stub.c +++ b/drivers/firmware/efi/libstub/arm32-stub.c @@ -8,9 +8,12 @@ */ #include #include +#include #include "efistub.h" +extern u32 kaslr_offset; + efi_status_t check_platform_features(efi_system_table_t *sys_table_arg) { int block; @@ -200,6 +203,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 +236,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;