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>,
	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 v8 11/14] module: Reorder functions
Date: Thu,  2 Dec 2021 23:32:11 +0100	[thread overview]
Message-ID: <20211202223214.72888-12-alexandr.lobakin@intel.com> (raw)
In-Reply-To: <20211202223214.72888-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.

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
[ alobakin: make it work with ClangCFI ]
Signed-off-by: Alexander Lobakin <alexandr.lobakin@intel.com>
---
 Makefile                |  4 ++
 init/Kconfig            | 12 ++++++
 kernel/kallsyms.c       |  4 +-
 kernel/livepatch/core.c |  3 +-
 kernel/module.c         | 91 ++++++++++++++++++++++++++++++++++++++++-
 5 files changed, 109 insertions(+), 5 deletions(-)

diff --git a/Makefile b/Makefile
index a4d2eac5f81f..649c309d10e2 100644
--- a/Makefile
+++ b/Makefile
@@ -885,6 +885,10 @@ endif
 # 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/init/Kconfig b/init/Kconfig
index 8baeaef382c9..1f7e57d323bb 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -2360,6 +2360,18 @@ 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"
+	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/kallsyms.c b/kernel/kallsyms.c
index ff9d8b651966..4ff14a94d1bd 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -861,7 +861,7 @@ static int __kallsyms_open(struct inode *inode, struct file *file)
  * When function granular kaslr is enabled, we need to print out the symbols
  * at random so we don't reveal the new layout.
  */
-#ifdef CONFIG_FG_KASLR
+#if defined(CONFIG_FG_KASLR) || defined(CONFIG_MODULE_FG_KASLR)
 static int update_random_pos(struct kallsyms_shuffled_iter *s_iter,
 			     loff_t pos, loff_t *new_pos)
 {
@@ -1005,7 +1005,7 @@ static int kallsyms_random_open(struct inode *inode, struct file *file)
 #define kallsyms_open kallsyms_random_open
 #else
 #define kallsyms_open __kallsyms_open
-#endif /* !CONFIG_FG_KASLR */
+#endif /* !CONFIG_FG_KASLR && !CONFIG_MODULE_FG_KASLR */
 
 #ifdef	CONFIG_KGDB_KDB
 const char *kdb_walk_kallsyms(loff_t *pos)
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c
index 10ea75111057..8a5240b5eb5e 100644
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -174,7 +174,8 @@ static int klp_find_object_symbol(const char *objname, const char *name,
 	 * to resolve symbols when there are duplicates using the previous
 	 * symbol position (i.e. sympos != 0).
 	 */
-	if (IS_ENABLED(CONFIG_FG_KASLR) && sympos) {
+	if ((IS_ENABLED(CONFIG_FG_KASLR) || IS_ENABLED(CONFIG_MODULE_FG_KASLR)) &&
+	    sympos) {
 		pr_err("FG-KASLR is enabled, specifying symbol position %lu for symbol '%s' in object '%s' does not work\n",
 		       sympos, name, objname ? objname : "vmlinux");
 		goto out_err;
diff --git a/kernel/module.c b/kernel/module.c
index 84a9141a5e15..48d5919d09dd 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,89 @@ static bool module_init_layout_section(const char *sname)
 	return module_init_section(sname);
 }
 
+/*
+ * shuffle_text_list()
+ * Use a Fisher Yates algorithm to shuffle a list of text sections.
+ */
+static void shuffle_text_list(Elf_Shdr **list, int size)
+{
+	u32 i, j;
+
+	for (i = size - 1; i > 0; i--) {
+		/*
+		 * pick a random index from 0 to i
+		 */
+		j = get_random_u32() % (i + 1);
+
+		swap(list[i], list[j]);
+	}
+}
+
+/*
+ * 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_text_list(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 +2594,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-02 22:33 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-02 22:32 [PATCH v8 00/14] Function Granular KASLR Alexander Lobakin
2021-12-02 22:32 ` [PATCH v8 01/14] x86: Makefile: Add build and config option for CONFIG_FG_KASLR Alexander Lobakin
2021-12-02 22:32 ` [PATCH v8 02/14] x86/tools: Add relative relocs for randomized functions Alexander Lobakin
2021-12-02 22:32 ` [PATCH v8 03/14] x86: Add support for function granular KASLR Alexander Lobakin
2021-12-03  9:18   ` Peter Zijlstra
2021-12-03 13:57     ` Alexander Lobakin
2021-12-03 10:34   ` Peter Zijlstra
2021-12-02 22:32 ` [PATCH v8 04/14] linkage: add macros for putting ASM functions into own sections Alexander Lobakin
2021-12-03  9:31   ` Peter Zijlstra
2021-12-03 14:08     ` Alexander Lobakin
2021-12-02 22:32 ` [PATCH v8 05/14] x86: conditionally place regular ASM functions into separate sections Alexander Lobakin
2021-12-03  9:44   ` Peter Zijlstra
2021-12-03 14:10     ` Alexander Lobakin
2021-12-03 16:34       ` Peter Zijlstra
2021-12-03 16:51         ` H.J. Lu
2021-12-03 19:46         ` Nicolas Pitre
2021-12-04  8:31           ` Ard Biesheuvel
2021-12-04  8:55           ` Peter Zijlstra
2021-12-10 11:01     ` Alexander Lobakin
2021-12-10 13:20       ` Nicolas Pitre
2021-12-02 22:32 ` [PATCH v8 06/14] FG-KASLR: use a scripted approach to handle .text.* sections Alexander Lobakin
2021-12-03  9:54   ` Peter Zijlstra
2021-12-02 22:32 ` [PATCH v8 07/14] kallsyms: Hide layout Alexander Lobakin
2021-12-03 10:00   ` Peter Zijlstra
2021-12-03 10:03     ` Ard Biesheuvel
2021-12-07  5:31       ` Josh Poimboeuf
2021-12-02 22:32 ` [PATCH v8 08/14] livepatch: only match unique symbols when using FG-KASLR Alexander Lobakin
2021-12-03 10:05   ` Peter Zijlstra
2021-12-03 14:14     ` Alexander Lobakin
2021-12-06  6:03     ` Josh Poimboeuf
2021-12-02 22:32 ` [PATCH v8 09/14] x86/boot: allow FG-KASLR to be selected Alexander Lobakin
2021-12-02 22:32 ` [PATCH v8 10/14] arm64/crypto: conditionally place ASM functions into separate sections Alexander Lobakin
2021-12-02 22:32 ` Alexander Lobakin [this message]
2021-12-03 10:23   ` [PATCH v8 11/14] module: Reorder functions Peter Zijlstra
2021-12-02 22:32 ` [PATCH v8 12/14] module: use a scripted approach for FG-KASLR Alexander Lobakin
2021-12-02 22:32 ` [PATCH v8 13/14] Documentation: add documentation " Alexander Lobakin
2021-12-02 22:32 ` [PATCH v8 14/14] maintainers: add MAINTAINERS entry " Alexander Lobakin
2021-12-03 10:38 ` [PATCH v8 00/14] Function Granular KASLR Peter Zijlstra
2021-12-03 14:41   ` Alexander Lobakin
2021-12-03 16:32     ` Peter Zijlstra

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=20211202223214.72888-12-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=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=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.