Received: by 2002:a25:e74b:0:0:0:0:0 with SMTP id e72csp2133105ybh; Fri, 17 Jul 2020 10:02:31 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyz+2PorRoSOX9htqqD3d6mEbGCaWAJJ5IGxXnIxf/8PuSAq4fIP0xmKgoy4Py8ATpvq8T9 X-Received: by 2002:a17:906:19c9:: with SMTP id h9mr9146247ejd.526.1595005351147; Fri, 17 Jul 2020 10:02:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1595005351; cv=none; d=google.com; s=arc-20160816; b=FhKVNsXeHm+qhtuqaSbxn8cokESuBcpz4y509PNKuHLjY7bbuwGicoDJmHTEvJke/Y uW+IR0z3xr7nywLTmcWsm5sQYJAGkAskRKKKkV/kvvxPij8kebDVNyYnUNdBqd4yH2B5 kNu81z8WE3P0w8de+Pj05LexFbaKAknn4UvQQnV+BQOg93+dFCGPyEaYG5Vhnby3PoaV qQlq/m9O57bGu673YPUrQq1IwlNY0LVwzDLZgSnQHrduMmp8dJh762mYFNw6S7NrKFNx J9DXGrH2gNSWqH55+t4quf7v4plcMWBNbIl/JZFIZWjskeDwKTYHKPSUhskC8xYnz2sF DuKw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :ironport-sdr:ironport-sdr; bh=HSl2+sHKffiXAQ6l6B0i2+ERRpKeQ86W7pgArJ2W244=; b=Xz0t8Wbhov8MXWPjAFocsdsHLkwigRhi5QhpaSJI2OjIWCQtVAm8umSKT+WunnEgmj wUXzKfPVB+yeM6EkdYi8UgV1vytD4URVxyesxkS7501YoZTyRY5n8aeAaXCI9zs0wn5m +r1Hy5bCmALxBb3mj4LKSoqCVlv9H5ZZT05FhvfAjeYaUwtCld+W2v3d+MXtr1g/kUZ9 cznBHJNKlOXpnRaWPlfs7GyLdSaGxCkKbJJNoh3N2xoJO7MoqyI5tESDgXYKsb4xKQWk Fi8lRbJ037gMtZH/QYnuw6ug4akIPmmr2L8FDxeRZHWQn9NnfL+ZLT0esOMOd6MD3Hrq Ih4g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 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. [23.128.96.18]) by mx.google.com with ESMTP id f1si5304832eje.610.2020.07.17.10.02.06; Fri, 17 Jul 2020 10:02:31 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 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 S1726936AbgGQRBI (ORCPT + 99 others); Fri, 17 Jul 2020 13:01:08 -0400 Received: from mga18.intel.com ([134.134.136.126]:1897 "EHLO mga18.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728210AbgGQRBD (ORCPT ); Fri, 17 Jul 2020 13:01:03 -0400 IronPort-SDR: B8npC8r5KWDXEjclygS+GPBEox/SDBqBJJb89ruByRkihNymzDqf5WupZdSyg2wcdndWBQ1KVH rjtJD3yjweUw== X-IronPort-AV: E=McAfee;i="6000,8403,9685"; a="137102982" X-IronPort-AV: E=Sophos;i="5.75,362,1589266800"; d="scan'208";a="137102982" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jul 2020 10:01:02 -0700 IronPort-SDR: YlJ98+kE/rZOgfAyKy2KRuoB3VOum1TV+Wc6cob0H1N42bJ+0/52jZSaxvvWVP9aWfpeFZ30J8 0UjwzN8oXoSw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.75,362,1589266800"; d="scan'208";a="270862167" Received: from kcaccard-mobl.amr.corp.intel.com (HELO kcaccard-mobl1.jf.intel.com) ([10.212.33.149]) by fmsmga008.fm.intel.com with ESMTP; 17 Jul 2020 10:00:58 -0700 From: Kristen Carlson Accardi To: keescook@chromium.org, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, x86@kernel.org, "H. Peter Anvin" Cc: arjan@linux.intel.com, linux-kernel@vger.kernel.org, kernel-hardening@lists.openwall.com, rick.p.edgecombe@intel.com, Kristen Carlson Accardi Subject: [PATCH v4 07/10] x86/boot/compressed: Avoid duplicate malloc() implementations Date: Fri, 17 Jul 2020 10:00:04 -0700 Message-Id: <20200717170008.5949-8-kristen@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200717170008.5949-1-kristen@linux.intel.com> References: <20200717170008.5949-1-kristen@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Kees Cook The preboot malloc() (and free()) implementation in include/linux/decompress/mm.h (which is also included by the static decompressors) is static. This is fine when the only thing interested in using malloc() is the decompression code, but the x86 preboot environment uses malloc() in a couple places, leading to a potential collision when the static copies of the available memory region ("malloc_ptr") gets reset to the global "free_mem_ptr" value. As it happens, the existing usage pattern happened to be safe because each user did 1 malloc() and 1 free() before returning and were not nested: extract_kernel() (misc.c) choose_random_location() (kaslr.c) mem_avoid_init() handle_mem_options() malloc() ... free() ... parse_elf() (misc.c) malloc() ... free() Adding FGKASLR, however, will insert additional malloc() calls local to fgkaslr.c in the middle of parse_elf()'s malloc()/free() pair: parse_elf() (misc.c) malloc() if (...) { layout_randomized_image(output, &ehdr, phdrs); malloc() <- boom ... else layout_image(output, &ehdr, phdrs); free() To avoid collisions, there must be a single implementation of malloc(). Adjust include/linux/decompress/mm.h so that visibility can be controlled, provide prototypes in misc.h, and implement the functions in misc.c. This also results in a small size savings: $ size vmlinux.before vmlinux.after text data bss dec hex filename 8842314 468 178320 9021102 89a6ae vmlinux.before 8842240 468 178320 9021028 89a664 vmlinux.after Signed-off-by: Kees Cook Signed-off-by: Kristen Carlson Accardi --- arch/x86/boot/compressed/kaslr.c | 4 ---- arch/x86/boot/compressed/misc.c | 3 +++ arch/x86/boot/compressed/misc.h | 2 ++ include/linux/decompress/mm.h | 12 ++++++++++-- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c index d7408af55738..6f596bd5b6e5 100644 --- a/arch/x86/boot/compressed/kaslr.c +++ b/arch/x86/boot/compressed/kaslr.c @@ -39,10 +39,6 @@ #include #include -/* Macros used by the included decompressor code below. */ -#define STATIC -#include - #ifdef CONFIG_X86_5LEVEL unsigned int __pgtable_l5_enabled; unsigned int pgdir_shift __ro_after_init = 39; diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index 9652d5c2afda..90a4b64b3037 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c @@ -28,6 +28,9 @@ /* Macros used by the included decompressor code below. */ #define STATIC static +/* Define an externally visible malloc()/free(). */ +#define MALLOC_VISIBLE +#include /* * Use normal definitions of mem*() from string.c. There are already diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h index 726e264410ff..81fbc8d686fa 100644 --- a/arch/x86/boot/compressed/misc.h +++ b/arch/x86/boot/compressed/misc.h @@ -39,6 +39,8 @@ /* misc.c */ extern memptr free_mem_ptr; extern memptr free_mem_end_ptr; +extern void *malloc(int size); +extern void free(void *where); extern struct boot_params *boot_params; void __putstr(const char *s); void __puthex(unsigned long value); diff --git a/include/linux/decompress/mm.h b/include/linux/decompress/mm.h index 868e9eacd69e..9192986b1a73 100644 --- a/include/linux/decompress/mm.h +++ b/include/linux/decompress/mm.h @@ -25,13 +25,21 @@ #define STATIC_RW_DATA static #endif +/* + * When an architecture needs to share the malloc()/free() implementation + * between compilation units, it needs to have non-local visibility. + */ +#ifndef MALLOC_VISIBLE +#define MALLOC_VISIBLE static +#endif + /* A trivial malloc implementation, adapted from * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 */ STATIC_RW_DATA unsigned long malloc_ptr; STATIC_RW_DATA int malloc_count; -static void *malloc(int size) +MALLOC_VISIBLE void *malloc(int size) { void *p; @@ -52,7 +60,7 @@ static void *malloc(int size) return p; } -static void free(void *where) +MALLOC_VISIBLE void free(void *where) { malloc_count--; if (!malloc_count) -- 2.20.1