From patchwork Tue Apr 19 07:01:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: mawupeng X-Patchwork-Id: 12817442 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9937BC43217 for ; Tue, 19 Apr 2022 06:43:12 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id F19238D004F; Tue, 19 Apr 2022 02:43:11 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id E2A9F8D0047; Tue, 19 Apr 2022 02:43:11 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id BBB0E8D004F; Tue, 19 Apr 2022 02:43:11 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (relay.hostedemail.com [64.99.140.28]) by kanga.kvack.org (Postfix) with ESMTP id AA85E8D0047 for ; Tue, 19 Apr 2022 02:43:11 -0400 (EDT) Received: from smtpin04.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay13.hostedemail.com (Postfix) with ESMTP id 7B32161318 for ; Tue, 19 Apr 2022 06:43:11 +0000 (UTC) X-FDA: 79372686582.04.6A3115A Received: from szxga03-in.huawei.com (szxga03-in.huawei.com [45.249.212.189]) by imf31.hostedemail.com (Postfix) with ESMTP id C68DD2000A for ; Tue, 19 Apr 2022 06:43:09 +0000 (UTC) Received: from dggpemm500022.china.huawei.com (unknown [172.30.72.54]) by szxga03-in.huawei.com (SkyGuard) with ESMTP id 4KjDfC1XhTzCrYM; Tue, 19 Apr 2022 14:38:43 +0800 (CST) Received: from dggpemm500014.china.huawei.com (7.185.36.153) by dggpemm500022.china.huawei.com (7.185.36.162) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.24; Tue, 19 Apr 2022 14:43:07 +0800 Received: from localhost.localdomain (10.175.112.125) by dggpemm500014.china.huawei.com (7.185.36.153) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.24; Tue, 19 Apr 2022 14:43:05 +0800 From: Wupeng Ma To: , , , CC: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , Subject: [PATCH 1/2] arm64/boot/KASLR: Add support to relocate kernel image to mirrored region Date: Tue, 19 Apr 2022 15:01:49 +0800 Message-ID: <20220419070150.254377-2-mawupeng1@huawei.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220419070150.254377-1-mawupeng1@huawei.com> References: <20220419070150.254377-1-mawupeng1@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.112.125] X-ClientProxiedBy: dggems705-chm.china.huawei.com (10.3.19.182) To dggpemm500014.china.huawei.com (7.185.36.153) X-CFilter-Loop: Reflected X-Rspamd-Server: rspam05 X-Rspamd-Queue-Id: C68DD2000A X-Rspam-User: Authentication-Results: imf31.hostedemail.com; dkim=none; dmarc=pass (policy=quarantine) header.from=huawei.com; spf=pass (imf31.hostedemail.com: domain of mawupeng1@huawei.com designates 45.249.212.189 as permitted sender) smtp.mailfrom=mawupeng1@huawei.com X-Stat-Signature: dgqmtpwcbzk3aysskeik3bbhjocu8o8y X-HE-Tag: 1650350589-437477 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: From: Ma Wupeng Add support to relocate kernel image to mirrored regions if KASLR is enabled. If a suiable mirrored slot if found, iterate EFI memory map and pick the mirrored region to process for adding candidate of randomization slot. If no suitable mirrored region found, alloc memory from non-mirrored regions. Signed-off-by: Ma Wupeng --- drivers/firmware/efi/libstub/arm64-stub.c | 52 +++++++++++++++++++++- drivers/firmware/efi/libstub/efistub.h | 7 ++- drivers/firmware/efi/libstub/randomalloc.c | 13 +++++- 3 files changed, 68 insertions(+), 4 deletions(-) diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c index 9cc556013d08..39b774853b93 100644 --- a/drivers/firmware/efi/libstub/arm64-stub.c +++ b/drivers/firmware/efi/libstub/arm64-stub.c @@ -79,6 +79,51 @@ static bool check_image_region(u64 base, u64 size) return ret; } +/* check if system has suitable for kernel to relocate */ +static bool check_mirror_suitable(unsigned long size, + unsigned long align) +{ + unsigned long map_size, desc_size; + unsigned long buff_size; + efi_status_t status; + efi_memory_desc_t *memory_map; + int map_offset; + struct efi_boot_memmap map; + bool found = false; + + map.map = &memory_map; + map.map_size = &map_size; + map.desc_size = &desc_size; + map.desc_ver = NULL; + map.key_ptr = NULL; + map.buff_size = &buff_size; + + status = efi_get_memory_map(&map); + if (status != EFI_SUCCESS) + return false; + + if (align < EFI_ALLOC_ALIGN) + align = EFI_ALLOC_ALIGN; + + size = round_up(size, EFI_ALLOC_ALIGN); + + for (map_offset = 0; map_offset < map_size; map_offset += desc_size) { + efi_memory_desc_t *md = (void *)memory_map + map_offset; + unsigned long slots; + + /* system has suiable mirrored area */ + slots = get_entry_num_slots(md, size, ilog2(align)); + if (slots > 0 && md->attribute & EFI_MEMORY_MORE_RELIABLE) { + found = true; + break; + } + } + + efi_bs_call(free_pool, memory_map); + + return found; +} + efi_status_t handle_kernel_image(unsigned long *image_addr, unsigned long *image_size, unsigned long *reserve_addr, @@ -88,6 +133,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, efi_status_t status; unsigned long kernel_size, kernel_memsize = 0; u32 phys_seed = 0; + bool efi_mirror_found; /* * Although relocatable kernels can fix up the misalignment with @@ -127,13 +173,16 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, kernel_memsize = kernel_size + (_end - _edata); *reserve_size = kernel_memsize; + efi_mirror_found = check_mirror_suitable(*reserve_size, min_kimg_align); + if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && phys_seed != 0) { /* * If KASLR is enabled, and we have some randomness available, * locate the kernel at a randomized offset in physical memory. */ status = efi_random_alloc(*reserve_size, min_kimg_align, - reserve_addr, phys_seed); + reserve_addr, phys_seed, + efi_mirror_found); if (status != EFI_SUCCESS) efi_warn("efi_random_alloc() failed: 0x%lx\n", status); } else { @@ -163,6 +212,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, } } +out: *image_addr = *reserve_addr; memcpy((void *)*image_addr, _text, kernel_size); diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h index edb77b0621ea..0cf2e25cb7d0 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -790,7 +790,8 @@ void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size, efi_status_t efi_get_random_bytes(unsigned long size, u8 *out); efi_status_t efi_random_alloc(unsigned long size, unsigned long align, - unsigned long *addr, unsigned long random_seed); + unsigned long *addr, unsigned long random_seed, + bool efi_has_mirror); efi_status_t check_platform_features(void); @@ -875,6 +876,10 @@ void efi_handle_post_ebs_state(void); enum efi_secureboot_mode efi_get_secureboot(void); +extern unsigned long get_entry_num_slots(efi_memory_desc_t *md, + unsigned long size, + unsigned long align_shift); + #ifdef CONFIG_RESET_ATTACK_MITIGATION void efi_enable_reset_attack_mitigation(void); #else diff --git a/drivers/firmware/efi/libstub/randomalloc.c b/drivers/firmware/efi/libstub/randomalloc.c index 724155b9e10d..dd81d6c3c406 100644 --- a/drivers/firmware/efi/libstub/randomalloc.c +++ b/drivers/firmware/efi/libstub/randomalloc.c @@ -14,7 +14,7 @@ * addresses it covers that are suitably aligned and supply enough room * for the allocation. */ -static unsigned long get_entry_num_slots(efi_memory_desc_t *md, +unsigned long get_entry_num_slots(efi_memory_desc_t *md, unsigned long size, unsigned long align_shift) { @@ -53,7 +53,8 @@ static unsigned long get_entry_num_slots(efi_memory_desc_t *md, efi_status_t efi_random_alloc(unsigned long size, unsigned long align, unsigned long *addr, - unsigned long random_seed) + unsigned long random_seed, + bool efi_mirror_found) { unsigned long map_size, desc_size, total_slots = 0, target_slot; unsigned long buff_size; @@ -83,6 +84,10 @@ efi_status_t efi_random_alloc(unsigned long size, efi_memory_desc_t *md = (void *)memory_map + map_offset; unsigned long slots; + if (efi_mirror_found && + !(md->attribute & EFI_MEMORY_MORE_RELIABLE)) + continue; + slots = get_entry_num_slots(md, size, ilog2(align)); MD_NUM_SLOTS(md) = slots; total_slots += slots; @@ -112,6 +117,10 @@ efi_status_t efi_random_alloc(unsigned long size, continue; } + if (efi_mirror_found && + !(md->attribute & EFI_MEMORY_MORE_RELIABLE)) + continue; + target = round_up(md->phys_addr, align) + target_slot * align; pages = size / EFI_PAGE_SIZE; From patchwork Tue Apr 19 07:01:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: mawupeng X-Patchwork-Id: 12817443 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0C443C433EF for ; Tue, 19 Apr 2022 06:43:13 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id A5DD18D0050; Tue, 19 Apr 2022 02:43:12 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 9BDB88D0047; Tue, 19 Apr 2022 02:43:12 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 7751C8D0050; Tue, 19 Apr 2022 02:43:12 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (relay.hostedemail.com [64.99.140.25]) by kanga.kvack.org (Postfix) with ESMTP id 5E7E78D0047 for ; Tue, 19 Apr 2022 02:43:12 -0400 (EDT) Received: from smtpin16.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay07.hostedemail.com (Postfix) with ESMTP id 34B73221DE for ; Tue, 19 Apr 2022 06:43:12 +0000 (UTC) X-FDA: 79372686624.16.4702C55 Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) by imf16.hostedemail.com (Postfix) with ESMTP id 9D321180007 for ; Tue, 19 Apr 2022 06:43:10 +0000 (UTC) Received: from dggpemm500023.china.huawei.com (unknown [172.30.72.57]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4KjDlB2KG7zhXb2; Tue, 19 Apr 2022 14:43:02 +0800 (CST) Received: from dggpemm500014.china.huawei.com (7.185.36.153) by dggpemm500023.china.huawei.com (7.185.36.83) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.24; Tue, 19 Apr 2022 14:43:08 +0800 Received: from localhost.localdomain (10.175.112.125) by dggpemm500014.china.huawei.com (7.185.36.153) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.24; Tue, 19 Apr 2022 14:43:07 +0800 From: Wupeng Ma To: , , , CC: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , Subject: [PATCH 2/2] arm64/boot: Add support to relocate kernel image to mirrored region without kaslr Date: Tue, 19 Apr 2022 15:01:50 +0800 Message-ID: <20220419070150.254377-3-mawupeng1@huawei.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220419070150.254377-1-mawupeng1@huawei.com> References: <20220419070150.254377-1-mawupeng1@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.112.125] X-ClientProxiedBy: dggems705-chm.china.huawei.com (10.3.19.182) To dggpemm500014.china.huawei.com (7.185.36.153) X-CFilter-Loop: Reflected Authentication-Results: imf16.hostedemail.com; dkim=none; dmarc=pass (policy=quarantine) header.from=huawei.com; spf=pass (imf16.hostedemail.com: domain of mawupeng1@huawei.com designates 45.249.212.188 as permitted sender) smtp.mailfrom=mawupeng1@huawei.com X-Rspam-User: X-Rspamd-Server: rspam08 X-Rspamd-Queue-Id: 9D321180007 X-Stat-Signature: mn1ymndpdonb7z61eitpar84n1ooe71f X-HE-Tag: 1650350590-912355 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: From: Ma Wupeng Add support to relocate kernel image to mirrord regions if KASLR doesn't work. If a suiable mirrored slot if found, call efi_random_alloc() with random_seed be zero to relocate kernel code and data to the first slot available. Signed-off-by: Ma Wupeng --- drivers/firmware/efi/libstub/arm64-stub.c | 10 ++++++++++ drivers/firmware/efi/libstub/randomalloc.c | 1 + 2 files changed, 11 insertions(+) diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c index 39b774853b93..851a8948cafb 100644 --- a/drivers/firmware/efi/libstub/arm64-stub.c +++ b/drivers/firmware/efi/libstub/arm64-stub.c @@ -190,6 +190,16 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, } if (status != EFI_SUCCESS) { + if (efi_mirror_found) { + status = efi_random_alloc(*reserve_size, min_kimg_align, + reserve_addr, 0, + efi_mirror_found); + if (status == EFI_SUCCESS) + goto out; + + efi_err("Failed to relocate kernel to mirrored region\n"); + } + if (!check_image_region((u64)_text, kernel_memsize)) { efi_err("FIRMWARE BUG: Image BSS overlaps adjacent EFI memory region\n"); } else if (IS_ALIGNED((u64)_text, min_kimg_align)) { diff --git a/drivers/firmware/efi/libstub/randomalloc.c b/drivers/firmware/efi/libstub/randomalloc.c index dd81d6c3c406..d5f4249943a7 100644 --- a/drivers/firmware/efi/libstub/randomalloc.c +++ b/drivers/firmware/efi/libstub/randomalloc.c @@ -50,6 +50,7 @@ unsigned long get_entry_num_slots(efi_memory_desc_t *md, */ #define MD_NUM_SLOTS(md) ((md)->virt_addr) +/* random_seed == 0 means alloc mem from the first suitable slot */ efi_status_t efi_random_alloc(unsigned long size, unsigned long align, unsigned long *addr,