All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexander Lobakin <alexandr.lobakin@intel.com>
To: linux-hardening@vger.kernel.org, x86@kernel.org
Cc: Alexander Lobakin <alexandr.lobakin@intel.com>,
	Jesse Brandeburg <jesse.brandeburg@intel.com>,
	Kristen Carlson Accardi <kristen@linux.intel.com>,
	Kees Cook <keescook@chromium.org>,
	Miklos Szeredi <miklos@szeredi.hu>,
	Ard Biesheuvel <ardb@kernel.org>, Tony Luck <tony.luck@intel.com>,
	Bruce Schlobohm <bruce.schlobohm@intel.com>,
	Jessica Yu <jeyu@kernel.org>, kernel test robot <lkp@intel.com>,
	Miroslav Benes <mbenes@suse.cz>,
	Evgenii Shatokhin <eshatokhin@virtuozzo.com>,
	Jonathan Corbet <corbet@lwn.net>,
	Masahiro Yamada <masahiroy@kernel.org>,
	Michal Marek <michal.lkml@markovi.net>,
	Nick Desaulniers <ndesaulniers@google.com>,
	Herbert Xu <herbert@gondor.apana.org.au>,
	"David S. Miller" <davem@davemloft.net>,
	Thomas Gleixner <tglx@linutronix.de>,
	Will Deacon <will@kernel.org>, Ingo Molnar <mingo@redhat.com>,
	Borislav Petkov <bp@alien8.de>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	"H. Peter Anvin" <hpa@zytor.com>,
	Andy Lutomirski <luto@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Arnd Bergmann <arnd@arndb.de>,
	Josh Poimboeuf <jpoimboe@redhat.com>,
	Nathan Chancellor <nathan@kernel.org>,
	Masami Hiramatsu <mhiramat@kernel.org>,
	Marios Pomonis <pomonis@google.com>,
	Sami Tolvanen <samitolvanen@google.com>,
	"H.J. Lu" <hjl.tools@gmail.com>, Nicolas Pitre <nico@fluxnic.net>,
	linux-kernel@vger.kernel.org, linux-kbuild@vger.kernel.org,
	linux-arch@vger.kernel.org, live-patching@vger.kernel.org,
	llvm@lists.linux.dev
Subject: [PATCH v9 12/15] module: Reorder functions
Date: Thu, 23 Dec 2021 01:22:06 +0100	[thread overview]
Message-ID: <20211223002209.1092165-13-alexandr.lobakin@intel.com> (raw)
In-Reply-To: <20211223002209.1092165-1-alexandr.lobakin@intel.com>

From: Kristen Carlson Accardi <kristen@linux.intel.com>

Introduce a new config option to allow modules to be re-ordered
by function. This option can be enabled independently of the
kernel text KASLR or FG_KASLR settings so that it can be used
by architectures that do not support either of these features.
This option will be selected by default if CONFIG_FG_KASLR is
selected.

If a module has functions split out into separate text sections
(i.e. compiled with the -ffunction-sections flag), reorder the
functions to provide some code diversification to modules.

alobakin:
Make it work with ClangCFI -- in such builds, .text section must
always come first and be page-aligned. Exclude it from the shuffle
list and leave as it is.
Make this feature depend on `-z unique-symbol` as well, due to the
very same reasons.
Traditionally, use common shuffle_array() from <linux/random.h>.

Signed-off-by: Kristen Carlson Accardi <kristen@linux.intel.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Tested-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Tony Luck <tony.luck@intel.com>
Tested-by: Tony Luck <tony.luck@intel.com>
Acked-by: Jessica Yu <jeyu@kernel.org>
Tested-by: Jessica Yu <jeyu@kernel.org>
Reported-by: kernel test robot <lkp@intel.com> # swap.cocci
Co-developed-by: Alexander Lobakin <alexandr.lobakin@intel.com>
Signed-off-by: Alexander Lobakin <alexandr.lobakin@intel.com>
---
 Makefile                |  6 +++-
 include/linux/linkage.h |  1 +
 init/Kconfig            | 14 ++++++++
 kernel/module.c         | 73 +++++++++++++++++++++++++++++++++++++++--
 4 files changed, 91 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index 3346269341d4..74d270c77d96 100644
--- a/Makefile
+++ b/Makefile
@@ -900,7 +900,7 @@ export SECSUBST_AFLAGS
 endif
 
 # Same for modules. LD DCE doesn't work for them, thus not checking for it
-ifneq ($(CONFIG_LTO_CLANG),)
+ifneq ($(CONFIG_MODULE_FG_KASLR)$(CONFIG_LTO_CLANG),)
 KBUILD_AFLAGS_MODULE += -Wa,--sectname-subst
 KBUILD_CFLAGS_MODULE += -Wa,--sectname-subst
 endif
@@ -909,6 +909,10 @@ endif # CONFIG_HAVE_ASM_FUNCTION_SECTIONS
 # ClangLTO implies `-ffunction-sections -fdata-sections`, no need
 # to specify them manually and trigger a pointless full rebuild
 ifndef CONFIG_LTO_CLANG
+ifdef CONFIG_MODULE_FG_KASLR
+KBUILD_CFLAGS_MODULE += -ffunction-sections
+endif
+
 ifneq ($(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION)$(CONFIG_FG_KASLR),)
 KBUILD_CFLAGS_KERNEL += -ffunction-sections
 endif
diff --git a/include/linux/linkage.h b/include/linux/linkage.h
index f3c96fb6a534..deb26069278a 100644
--- a/include/linux/linkage.h
+++ b/include/linux/linkage.h
@@ -80,6 +80,7 @@
 #if defined(CONFIG_HAVE_ASM_FUNCTION_SECTIONS) && \
     ((defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION) && !defined(MODULE)) || \
      (defined(CONFIG_FG_KASLR) && !defined(MODULE)) || \
+     (defined(CONFIG_MODULE_FG_KASLR) && defined(MODULE)) || \
      (defined(CONFIG_LTO_CLANG)))
 
 #define SYM_PUSH_SECTION(name)				\
diff --git a/init/Kconfig b/init/Kconfig
index 381b063b4925..38c82e21efd7 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -2376,6 +2376,20 @@ config UNUSED_KSYMS_WHITELIST
 	  one per line. The path can be absolute, or relative to the kernel
 	  source tree.
 
+config MODULE_FG_KASLR
+	bool "Module Function Granular Layout Randomization"
+	depends on $(cc-option,-ffunction-sections)
+	depends on LD_HAS_Z_UNIQUE_SYMBOL || !LIVEPATCH
+	default FG_KASLR
+	depends on BROKEN
+	help
+	  This option randomizes the module text section by reordering the text
+	  section by function at module load time. In order to use this
+	  feature, the module must have been compiled with the
+	  -ffunction-sections compiler flag.
+
+	  If unsure, say N.
+
 endif # MODULES
 
 config MODULES_TREE_LOOKUP
diff --git a/kernel/module.c b/kernel/module.c
index 84a9141a5e15..802e1098eaf4 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -57,6 +57,7 @@
 #include <linux/bsearch.h>
 #include <linux/dynamic_debug.h>
 #include <linux/audit.h>
+#include <linux/random.h>
 #include <uapi/linux/module.h>
 #include "module-internal.h"
 
@@ -1527,7 +1528,7 @@ static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
 
 	for (section = 0; section < sect_attrs->nsections; section++)
 		kfree(sect_attrs->attrs[section].battr.attr.name);
-	kfree(sect_attrs);
+	kvfree(sect_attrs);
 }
 
 static void add_sect_attrs(struct module *mod, const struct load_info *info)
@@ -1544,7 +1545,7 @@ static void add_sect_attrs(struct module *mod, const struct load_info *info)
 	size[0] = ALIGN(struct_size(sect_attrs, attrs, nloaded),
 			sizeof(sect_attrs->grp.bin_attrs[0]));
 	size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.bin_attrs[0]);
-	sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL);
+	sect_attrs = kvzalloc(size[0] + size[1], GFP_KERNEL);
 	if (sect_attrs == NULL)
 		return;
 
@@ -2416,6 +2417,71 @@ static bool module_init_layout_section(const char *sname)
 	return module_init_section(sname);
 }
 
+/*
+ * randomize_text()
+ * Look through the core section looking for executable code sections.
+ * Store sections in an array and then shuffle the sections
+ * to reorder the functions.
+ */
+static void randomize_text(struct module *mod, struct load_info *info)
+{
+	int max_sections = info->hdr->e_shnum;
+	int num_text_sections = 0;
+	Elf_Shdr **text_list;
+	int i, size;
+
+	text_list = kvmalloc_array(max_sections, sizeof(*text_list), GFP_KERNEL);
+	if (!text_list)
+		return;
+
+	for (i = 0; i < max_sections; i++) {
+		Elf_Shdr *shdr = &info->sechdrs[i];
+		const char *sname = info->secstrings + shdr->sh_name;
+
+		if (!(shdr->sh_flags & SHF_ALLOC) ||
+		    !(shdr->sh_flags & SHF_EXECINSTR) ||
+		    (shdr->sh_flags & ARCH_SHF_SMALL) ||
+		    module_init_layout_section(sname))
+			continue;
+
+		/*
+		 * With CONFIG_CFI_CLANG, .text with __cfi_check() must come
+		 * before any other text sections, and be aligned to PAGE_SIZE.
+		 * Don't include it in the shuffle list.
+		 */
+		if (IS_ENABLED(CONFIG_CFI_CLANG) && !strcmp(sname, ".text"))
+			continue;
+
+		if (!num_text_sections)
+			size = shdr->sh_entsize;
+
+		text_list[num_text_sections] = shdr;
+		num_text_sections++;
+	}
+
+	if (!num_text_sections)
+		goto exit;
+
+	shuffle_array(text_list, num_text_sections);
+
+	for (i = 0; i < num_text_sections; i++) {
+		Elf_Shdr *shdr = text_list[i];
+
+		/*
+		 * get_offset has a section index for it's last
+		 * argument, that is only used by arch_mod_section_prepend(),
+		 * which is only defined by parisc. Since this type
+		 * of randomization isn't supported on parisc, we can
+		 * safely pass in zero as the last argument, as it is
+		 * ignored.
+		 */
+		shdr->sh_entsize = get_offset(mod, &size, shdr, 0);
+	}
+
+exit:
+	kvfree(text_list);
+}
+
 /*
  * Lay out the SHF_ALLOC sections in a way not dissimilar to how ld
  * might -- code, read-only data, read-write data, small data.  Tally
@@ -2510,6 +2576,9 @@ static void layout_sections(struct module *mod, struct load_info *info)
 			break;
 		}
 	}
+
+	if (IS_ENABLED(CONFIG_MODULE_FG_KASLR))
+		randomize_text(mod, info);
 }
 
 static void set_license(struct module *mod, const char *license)
-- 
2.33.1


  parent reply	other threads:[~2021-12-23  0:23 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-23  0:21 [PATCH v9 00/15] Function Granular KASLR Alexander Lobakin
2021-12-23  0:21 ` [PATCH v9 01/15] modpost: fix removing numeric suffixes Alexander Lobakin
2021-12-23 16:19   ` Borislav Petkov
2021-12-27 18:22     ` Alexander Lobakin
2021-12-27 21:26       ` Borislav Petkov
2021-12-28 17:03         ` Alexander Lobakin
2022-01-03 13:07   ` Miroslav Benes
2021-12-23  0:21 ` [PATCH v9 02/15] livepatch: use `-z unique-symbol` if available to nuke pos-based search Alexander Lobakin
2021-12-30 11:10   ` Borislav Petkov
2021-12-30 18:31     ` Fāng-ruì Sòng
2022-01-03 13:55       ` Miroslav Benes
2022-01-03 16:06         ` Alexander Lobakin
2022-01-05  3:24           ` Fāng-ruì Sòng
2022-01-03 16:29     ` Alexander Lobakin
2022-01-03 13:44   ` Miroslav Benes
2021-12-23  0:21 ` [PATCH v9 03/15] kallsyms: Hide layout Alexander Lobakin
2021-12-30 22:36   ` Borislav Petkov
2022-01-03 15:40     ` Alexander Lobakin
2022-01-03 16:59       ` Borislav Petkov
2022-01-05 18:46   ` Borislav Petkov
2021-12-23  0:21 ` [PATCH v9 04/15] arch: introduce ASM function sections Alexander Lobakin
2022-01-17 21:08   ` Borislav Petkov
2022-01-17 21:38     ` Nicolas Pitre
2022-01-17 21:55       ` Borislav Petkov
2021-12-23  0:21 ` [PATCH v9 05/15] x86: support " Alexander Lobakin
2022-01-21 15:08   ` Borislav Petkov
2022-01-26 14:49     ` Alexander Lobakin
2021-12-23  0:22 ` [PATCH v9 06/15] x86: decouple ORC table sorting into a separate file Alexander Lobakin
2021-12-23  0:22 ` [PATCH v9 07/15] Makefile: Add build and config option for CONFIG_FG_KASLR Alexander Lobakin
2021-12-23  0:22 ` [PATCH v9 08/15] x86/tools: Add relative relocs for randomized functions Alexander Lobakin
2021-12-23  0:22 ` [PATCH v9 09/15] x86: Add support for function granular KASLR Alexander Lobakin
2021-12-23  0:22 ` [PATCH v9 10/15] FG-KASLR: use a scripted approach to handle .text.* sections Alexander Lobakin
2021-12-23  0:22 ` [PATCH v9 11/15] x86/boot: allow FG-KASLR to be selected Alexander Lobakin
2021-12-23  0:22 ` Alexander Lobakin [this message]
2021-12-23  0:22 ` [PATCH v9 13/15] module: use a scripted approach for FG-KASLR Alexander Lobakin
2021-12-23  0:22 ` [PATCH v9 14/15] Documentation: add documentation " Alexander Lobakin
2021-12-23  0:22 ` [PATCH v9 15/15] maintainers: add MAINTAINERS entry " Alexander Lobakin
2021-12-23 15:15 ` [PATCH v9 00/15] Function Granular KASLR Alexander Lobakin
2021-12-23 15:40   ` Peter Zijlstra
2021-12-24  6:38 ` Christoph Hellwig
2021-12-27 18:33   ` Alexander Lobakin
2021-12-30  9:00     ` Christoph Hellwig

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211223002209.1092165-13-alexandr.lobakin@intel.com \
    --to=alexandr.lobakin@intel.com \
    --cc=ardb@kernel.org \
    --cc=arnd@arndb.de \
    --cc=bp@alien8.de \
    --cc=bruce.schlobohm@intel.com \
    --cc=corbet@lwn.net \
    --cc=dave.hansen@linux.intel.com \
    --cc=davem@davemloft.net \
    --cc=eshatokhin@virtuozzo.com \
    --cc=herbert@gondor.apana.org.au \
    --cc=hjl.tools@gmail.com \
    --cc=hpa@zytor.com \
    --cc=jesse.brandeburg@intel.com \
    --cc=jeyu@kernel.org \
    --cc=jpoimboe@redhat.com \
    --cc=keescook@chromium.org \
    --cc=kristen@linux.intel.com \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kbuild@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=live-patching@vger.kernel.org \
    --cc=lkp@intel.com \
    --cc=llvm@lists.linux.dev \
    --cc=luto@kernel.org \
    --cc=masahiroy@kernel.org \
    --cc=mbenes@suse.cz \
    --cc=mhiramat@kernel.org \
    --cc=michal.lkml@markovi.net \
    --cc=miklos@szeredi.hu \
    --cc=mingo@redhat.com \
    --cc=nathan@kernel.org \
    --cc=ndesaulniers@google.com \
    --cc=nico@fluxnic.net \
    --cc=peterz@infradead.org \
    --cc=pomonis@google.com \
    --cc=samitolvanen@google.com \
    --cc=tglx@linutronix.de \
    --cc=tony.luck@intel.com \
    --cc=will@kernel.org \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.