Received: by 2002:a25:e74b:0:0:0:0:0 with SMTP id e72csp2133024ybh; Fri, 17 Jul 2020 10:02:25 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw7ii9CMkjzSZs4QRyS4wH8yjfhpTW7KaG6PjKRZXh0z27UeL8vKmbN6c4O6g3zSM8XcKcL X-Received: by 2002:aa7:cd52:: with SMTP id v18mr9704878edw.196.1595005345301; Fri, 17 Jul 2020 10:02:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1595005345; cv=none; d=google.com; s=arc-20160816; b=gleVuJsacRo8PeJY0iIiIj7V9o68mZ13E8izowwDb7pZKCx3XAshISTMU8gC+cwgwp XdVXehGwknVVa/MQjntWa2p8T4iJ4QEh73u0LJYyI9/WBGO+OQ/E6eqveKQ2ZGA89bfN yhZoVvE9GB+oEdtn+Pkedx4kXEIg4tBicK1sWWYCrKrdPPdRydUoA9L69NUyuluMUO/u Trh/kodNoOKHgbp3G1bFEZCy5PX47Gy78HxNW3UDnaNLC7p3vH0JzmBOvCHRAo8x7M2S CbA9/bCX6lT185Loa2uXVIdyBILyNckImSFNRROXrQXiMJBbahO1T96if/yo1LbEN7jh M9ZQ== 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=QE2A2N/WINZ5PmIzeABssxFASuo+QtFZQcjU6uPui3g=; b=xAtOMIWy/4EL1oglqyVPe8s8KqmnuY0nMMw+ZZbqsIeqQ3tonTiQQVIclaJwa9ABRP TBYFu1QUCqxF31PgfdsQJJWDO/lPeIUG/qJOAfTlW9zIYPZu8JIRWL/WWvwX/mzPt1Jl CHYycQbRWvk6LrO2wFY2BHZlx9SQIBatQmw37xFHvgy763GDYfYAtmoVAVSXvxXwowxF FsRPourLhxYwYbpymcBH/fIsnSDc0Ov+5rD37oE/i6Nsfh8ID9Lv4umQJcEoBP4cncF3 ksZEtGNorU7/xW3urt930nqy0732ipzZvpUUy308i5pIS84jFNQZHiF8QMWWjP+Au8gB 5GBw== 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 o26si5813645ejx.227.2020.07.17.10.02.01; Fri, 17 Jul 2020 10:02:25 -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 S1728209AbgGQRBD (ORCPT + 99 others); Fri, 17 Jul 2020 13:01:03 -0400 Received: from mga18.intel.com ([134.134.136.126]:1883 "EHLO mga18.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728129AbgGQRA4 (ORCPT ); Fri, 17 Jul 2020 13:00:56 -0400 IronPort-SDR: JlsClbSipu/3HeWQ7moERJLZLq5gF0mz/4Moa1rPQiqxTHlVPPTPISVfFn9vZbJVqF2AC1SQWa JtfZ2Isg4YcQ== X-IronPort-AV: E=McAfee;i="6000,8403,9685"; a="137102934" X-IronPort-AV: E=Sophos;i="5.75,362,1589266800"; d="scan'208";a="137102934" 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:00:55 -0700 IronPort-SDR: NWj7oLgSmlwHYacGEeXpVk//kBB+ogD+RefXmM+m9lS+AvKxLZXdjbQVYXvBKDxa2dGtBMrDoq JQ3NHH5ZmRiA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.75,362,1589266800"; d="scan'208";a="270862125" 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:51 -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 , Tony Luck Subject: [PATCH v4 06/10] x86/tools: Add relative relocs for randomized functions Date: Fri, 17 Jul 2020 10:00:03 -0700 Message-Id: <20200717170008.5949-7-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 When reordering functions, the relative offsets for relocs that are either in the randomized sections, or refer to the randomized sections will need to be adjusted. Add code to detect whether a reloc satisfies these cases, and if so, add them to the appropriate reloc list. Signed-off-by: Kristen Carlson Accardi Reviewed-by: Tony Luck Tested-by: Tony Luck Reviewed-by: Kees Cook --- arch/x86/boot/compressed/Makefile | 7 +++++- arch/x86/tools/relocs.c | 41 ++++++++++++++++++++++++++++--- arch/x86/tools/relocs.h | 4 +-- arch/x86/tools/relocs_common.c | 15 +++++++---- 4 files changed, 55 insertions(+), 12 deletions(-) diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 7619742f91c9..c17b1c8ec82c 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -119,6 +119,11 @@ $(obj)/vmlinux: $(vmlinux-objs-y) FORCE $(call if_changed,check-and-link-vmlinux) OBJCOPYFLAGS_vmlinux.bin := -R .comment -S + +ifdef CONFIG_FG_KASLR + RELOCS_ARGS += --fg-kaslr +endif + $(obj)/vmlinux.bin: vmlinux FORCE $(call if_changed,objcopy) @@ -126,7 +131,7 @@ targets += $(patsubst $(obj)/%,%,$(vmlinux-objs-y)) vmlinux.bin.all vmlinux.relo CMD_RELOCS = arch/x86/tools/relocs quiet_cmd_relocs = RELOCS $@ - cmd_relocs = $(CMD_RELOCS) $< > $@;$(CMD_RELOCS) --abs-relocs $< + cmd_relocs = $(CMD_RELOCS) $(RELOCS_ARGS) $< > $@;$(CMD_RELOCS) $(RELOCS_ARGS) --abs-relocs $< $(obj)/vmlinux.relocs: vmlinux FORCE $(call if_changed,relocs) diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c index 31b2d151aa63..e0665038742e 100644 --- a/arch/x86/tools/relocs.c +++ b/arch/x86/tools/relocs.c @@ -42,6 +42,8 @@ struct section { }; static struct section *secs; +static int fgkaslr_mode; + static const char * const sym_regex_kernel[S_NSYMTYPES] = { /* * Following symbols have been audited. There values are constant and do @@ -818,6 +820,32 @@ static int is_percpu_sym(ElfW(Sym) *sym, const char *symname) strncmp(symname, "init_per_cpu_", 13); } +static int is_function_section(struct section *sec) +{ + const char *name; + + if (!fgkaslr_mode) + return 0; + + name = sec_name(sec->shdr.sh_info); + + return(!strncmp(name, ".text.", 6)); +} + +static int is_randomized_sym(ElfW(Sym) *sym) +{ + const char *name; + + if (!fgkaslr_mode) + return 0; + + if (sym->st_shndx > shnum) + return 0; + + name = sec_name(sym_index(sym)); + return(!strncmp(name, ".text.", 6)); +} + static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym, const char *symname) { @@ -842,13 +870,17 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym, case R_X86_64_PC32: case R_X86_64_PLT32: /* - * PC relative relocations don't need to be adjusted unless - * referencing a percpu symbol. + * we need to keep pc relative relocations for sections which + * might be randomized, and for the percpu section. + * We also need to keep relocations for any offset which might + * reference an address in a section which has been randomized. * * NB: R_X86_64_PLT32 can be treated as R_X86_64_PC32. */ - if (is_percpu_sym(sym, symname)) + if (is_function_section(sec) || is_randomized_sym(sym) || + is_percpu_sym(sym, symname)) add_reloc(&relocs32neg, offset); + break; case R_X86_64_PC64: @@ -1158,8 +1190,9 @@ static void print_reloc_info(void) void process(FILE *fp, int use_real_mode, int as_text, int show_absolute_syms, int show_absolute_relocs, - int show_reloc_info) + int show_reloc_info, int fgkaslr) { + fgkaslr_mode = fgkaslr; regex_init(use_real_mode); read_ehdr(fp); read_shdrs(fp); diff --git a/arch/x86/tools/relocs.h b/arch/x86/tools/relocs.h index 43c83c0fd22c..f582895c04dd 100644 --- a/arch/x86/tools/relocs.h +++ b/arch/x86/tools/relocs.h @@ -31,8 +31,8 @@ enum symtype { void process_32(FILE *fp, int use_real_mode, int as_text, int show_absolute_syms, int show_absolute_relocs, - int show_reloc_info); + int show_reloc_info, int fgkaslr); void process_64(FILE *fp, int use_real_mode, int as_text, int show_absolute_syms, int show_absolute_relocs, - int show_reloc_info); + int show_reloc_info, int fgkaslr); #endif /* RELOCS_H */ diff --git a/arch/x86/tools/relocs_common.c b/arch/x86/tools/relocs_common.c index 6634352a20bc..a80efa2f53ff 100644 --- a/arch/x86/tools/relocs_common.c +++ b/arch/x86/tools/relocs_common.c @@ -12,14 +12,14 @@ void die(char *fmt, ...) static void usage(void) { - die("relocs [--abs-syms|--abs-relocs|--reloc-info|--text|--realmode]" \ - " vmlinux\n"); + die("relocs [--abs-syms|--abs-relocs|--reloc-info|--text|--realmode|" \ + "--fg-kaslr] vmlinux\n"); } int main(int argc, char **argv) { int show_absolute_syms, show_absolute_relocs, show_reloc_info; - int as_text, use_real_mode; + int as_text, use_real_mode, fgkaslr_opt; const char *fname; FILE *fp; int i; @@ -30,6 +30,7 @@ int main(int argc, char **argv) show_reloc_info = 0; as_text = 0; use_real_mode = 0; + fgkaslr_opt = 0; fname = NULL; for (i = 1; i < argc; i++) { char *arg = argv[i]; @@ -54,6 +55,10 @@ int main(int argc, char **argv) use_real_mode = 1; continue; } + if (strcmp(arg, "--fg-kaslr") == 0) { + fgkaslr_opt = 1; + continue; + } } else if (!fname) { fname = arg; @@ -75,11 +80,11 @@ int main(int argc, char **argv) if (e_ident[EI_CLASS] == ELFCLASS64) process_64(fp, use_real_mode, as_text, show_absolute_syms, show_absolute_relocs, - show_reloc_info); + show_reloc_info, fgkaslr_opt); else process_32(fp, use_real_mode, as_text, show_absolute_syms, show_absolute_relocs, - show_reloc_info); + show_reloc_info, fgkaslr_opt); fclose(fp); return 0; } -- 2.20.1