linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] module: Add module name to modinfo
@ 2017-04-21 22:35 Kees Cook
  2017-04-21 22:35 ` [PATCH v2 1/2] module: Pass struct load_info into symbol checks Kees Cook
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Kees Cook @ 2017-04-21 22:35 UTC (permalink / raw)
  To: Jessica Yu
  Cc: Kees Cook, Rusty Russell, Peter Zijlstra (Intel),
	Josh Poimboeuf, Ard Biesheuvel, Heinrich Schuchardt,
	Nicholas Piggin, Chris Metcalf, linux-kernel

The mod structure is accessed for the "name" field prior to validating
sanity in check_modstruct_version(). This becomes very obvious once
struct layout randomization is happening, so instead add the module
name to modinfo and use that until the mod struct has been sanity-checked.

-Kees

v2:
- adjusted for more odd name load failure cases; jeyu

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 1/2] module: Pass struct load_info into symbol checks
  2017-04-21 22:35 [PATCH v2 0/2] module: Add module name to modinfo Kees Cook
@ 2017-04-21 22:35 ` Kees Cook
  2017-04-21 22:35 ` [PATCH v2 2/2] module: Add module name to modinfo Kees Cook
  2017-04-26  2:32 ` [PATCH v2 0/2] " Jessica Yu
  2 siblings, 0 replies; 9+ messages in thread
From: Kees Cook @ 2017-04-21 22:35 UTC (permalink / raw)
  To: Jessica Yu
  Cc: Kees Cook, Rusty Russell, Peter Zijlstra (Intel),
	Josh Poimboeuf, Ard Biesheuvel, Heinrich Schuchardt,
	Nicholas Piggin, Chris Metcalf, linux-kernel

Since we're already using values from struct load_info, just pass this
pointer in directly and use what's needed as we need it. This allows us
to access future fields in struct load_info too.

Signed-off-by: Kees Cook <keescook@chromium.org>
---
 kernel/module.c | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/kernel/module.c b/kernel/module.c
index 7eba6dea4f41..ed6cf2367217 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1257,12 +1257,13 @@ static u32 resolve_rel_crc(const s32 *crc)
 	return *(u32 *)((void *)crc + *crc);
 }
 
-static int check_version(Elf_Shdr *sechdrs,
-			 unsigned int versindex,
+static int check_version(const struct load_info *info,
 			 const char *symname,
 			 struct module *mod,
 			 const s32 *crc)
 {
+	Elf_Shdr *sechdrs = info->sechdrs;
+	unsigned int versindex = info->index.vers;
 	unsigned int i, num_versions;
 	struct modversion_info *versions;
 
@@ -1305,8 +1306,7 @@ static int check_version(Elf_Shdr *sechdrs,
 	return 0;
 }
 
-static inline int check_modstruct_version(Elf_Shdr *sechdrs,
-					  unsigned int versindex,
+static inline int check_modstruct_version(const struct load_info *info,
 					  struct module *mod)
 {
 	const s32 *crc;
@@ -1322,8 +1322,8 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs,
 		BUG();
 	}
 	preempt_enable();
-	return check_version(sechdrs, versindex,
-			     VMLINUX_SYMBOL_STR(module_layout), mod, crc);
+	return check_version(info, VMLINUX_SYMBOL_STR(module_layout),
+			     mod, crc);
 }
 
 /* First part is kernel version, which we ignore if module has crcs. */
@@ -1337,8 +1337,7 @@ static inline int same_magic(const char *amagic, const char *bmagic,
 	return strcmp(amagic, bmagic) == 0;
 }
 #else
-static inline int check_version(Elf_Shdr *sechdrs,
-				unsigned int versindex,
+static inline int check_version(const struct load_info *info,
 				const char *symname,
 				struct module *mod,
 				const s32 *crc)
@@ -1346,8 +1345,7 @@ static inline int check_version(Elf_Shdr *sechdrs,
 	return 1;
 }
 
-static inline int check_modstruct_version(Elf_Shdr *sechdrs,
-					  unsigned int versindex,
+static inline int check_modstruct_version(const struct load_info *info,
 					  struct module *mod)
 {
 	return 1;
@@ -1383,7 +1381,7 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
 	if (!sym)
 		goto unlock;
 
-	if (!check_version(info->sechdrs, info->index.vers, name, mod, crc)) {
+	if (!check_version(info, name, mod, crc)) {
 		sym = ERR_PTR(-EINVAL);
 		goto getname;
 	}
@@ -2950,7 +2948,7 @@ static struct module *setup_load_info(struct load_info *info, int flags)
 	info->index.pcpu = find_pcpusec(info);
 
 	/* Check module struct version now, before we try to use module. */
-	if (!check_modstruct_version(info->sechdrs, info->index.vers, mod))
+	if (!check_modstruct_version(info, mod))
 		return ERR_PTR(-ENOEXEC);
 
 	return mod;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 2/2] module: Add module name to modinfo
  2017-04-21 22:35 [PATCH v2 0/2] module: Add module name to modinfo Kees Cook
  2017-04-21 22:35 ` [PATCH v2 1/2] module: Pass struct load_info into symbol checks Kees Cook
@ 2017-04-21 22:35 ` Kees Cook
  2017-04-25  7:00   ` Jon Masters
  2017-04-26  2:32 ` [PATCH v2 0/2] " Jessica Yu
  2 siblings, 1 reply; 9+ messages in thread
From: Kees Cook @ 2017-04-21 22:35 UTC (permalink / raw)
  To: Jessica Yu
  Cc: Kees Cook, Rusty Russell, Peter Zijlstra (Intel),
	Josh Poimboeuf, Ard Biesheuvel, Heinrich Schuchardt,
	Nicholas Piggin, Chris Metcalf, linux-kernel

Accessing the mod structure (e.g. for mod->name) prior to having completed
check_modstruct_version() can result in writing garbage to the error logs
if the layout of the mod structure loaded from disk doesn't match the
running kernel's mod structure layout. This kind of mismatch will become
much more likely if a kernel is built with different randomization seed
for the struct layout randomization plugin.

Instead, add and use a new modinfo string for logging the module name.

Signed-off-by: Kees Cook <keescook@chromium.org>
---
 kernel/module.c       | 29 ++++++++++++++++++++++-------
 scripts/mod/modpost.c |  1 +
 2 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/kernel/module.c b/kernel/module.c
index ed6cf2367217..29a4a77b6849 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -299,6 +299,7 @@ int unregister_module_notifier(struct notifier_block *nb)
 EXPORT_SYMBOL(unregister_module_notifier);
 
 struct load_info {
+	char *name;
 	Elf_Ehdr *hdr;
 	unsigned long len;
 	Elf_Shdr *sechdrs;
@@ -1297,12 +1298,12 @@ static int check_version(const struct load_info *info,
 	}
 
 	/* Broken toolchain. Warn once, then let it go.. */
-	pr_warn_once("%s: no symbol version for %s\n", mod->name, symname);
+	pr_warn_once("%s: no symbol version for %s\n", info->name, symname);
 	return 1;
 
 bad_version:
 	pr_warn("%s: disagrees about version of symbol %s\n",
-	       mod->name, symname);
+	       info->name, symname);
 	return 0;
 }
 
@@ -2892,9 +2893,15 @@ static int rewrite_section_headers(struct load_info *info, int flags)
 		info->index.vers = 0; /* Pretend no __versions section! */
 	else
 		info->index.vers = find_sec(info, "__versions");
+	info->sechdrs[info->index.vers].sh_flags &= ~(unsigned long)SHF_ALLOC;
+
 	info->index.info = find_sec(info, ".modinfo");
+	if (!info->index.info)
+		info->name = "(missing .modinfo section)";
+	else
+		info->name = get_modinfo(info, "name");
 	info->sechdrs[info->index.info].sh_flags &= ~(unsigned long)SHF_ALLOC;
-	info->sechdrs[info->index.vers].sh_flags &= ~(unsigned long)SHF_ALLOC;
+
 	return 0;
 }
 
@@ -2934,14 +2941,22 @@ static struct module *setup_load_info(struct load_info *info, int flags)
 
 	info->index.mod = find_sec(info, ".gnu.linkonce.this_module");
 	if (!info->index.mod) {
-		pr_warn("No module found in object\n");
+		pr_warn("%s: No module found in object\n",
+			info->name ?: "(missing .modinfo name field)");
 		return ERR_PTR(-ENOEXEC);
 	}
 	/* This is temporary: point mod into copy of data. */
 	mod = (void *)info->sechdrs[info->index.mod].sh_addr;
 
+	/*
+	 * If we didn't load the .modinfo 'name' field, fall back to
+	 * on-disk struct mod 'name' field.
+	 */
+	if (!info->name)
+		info->name = mod->name;
+
 	if (info->index.sym == 0) {
-		pr_warn("%s: module has no symbols (stripped?)\n", mod->name);
+		pr_warn("%s: module has no symbols (stripped?)\n", info->name);
 		return ERR_PTR(-ENOEXEC);
 	}
 
@@ -2969,7 +2984,7 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags)
 			return err;
 	} else if (!same_magic(modmagic, vermagic, info->index.vers)) {
 		pr_err("%s: version magic '%s' should be '%s'\n",
-		       mod->name, modmagic, vermagic);
+		       info->name, modmagic, vermagic);
 		return -ENOEXEC;
 	}
 
@@ -3249,7 +3264,7 @@ static struct module *layout_and_allocate(struct load_info *info, int flags)
 	if (IS_ERR(mod))
 		return mod;
 
-	if (blacklisted(mod->name))
+	if (blacklisted(info->name))
 		return ERR_PTR(-EPERM);
 
 	err = check_modinfo(mod, info, flags);
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 30d752a4a6a6..48397feb08fb 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -2126,6 +2126,7 @@ static void add_header(struct buffer *b, struct module *mod)
 	buf_printf(b, "#include <linux/compiler.h>\n");
 	buf_printf(b, "\n");
 	buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
+	buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n");
 	buf_printf(b, "\n");
 	buf_printf(b, "__visible struct module __this_module\n");
 	buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n");
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/2] module: Add module name to modinfo
  2017-04-21 22:35 ` [PATCH v2 2/2] module: Add module name to modinfo Kees Cook
@ 2017-04-25  7:00   ` Jon Masters
  2017-04-25  7:04     ` Jon Masters
  0 siblings, 1 reply; 9+ messages in thread
From: Jon Masters @ 2017-04-25  7:00 UTC (permalink / raw)
  To: Kees Cook, Jessica Yu
  Cc: Rusty Russell, Peter Zijlstra (Intel),
	Josh Poimboeuf, Ard Biesheuvel, Heinrich Schuchardt,
	Nicholas Piggin, Chris Metcalf, linux-kernel, Lucas De Marchi

On 04/21/2017 06:35 PM, Kees Cook wrote:

> Accessing the mod structure (e.g. for mod->name) prior to having completed
> check_modstruct_version() can result in writing garbage to the error logs
> if the layout of the mod structure loaded from disk doesn't match the
> running kernel's mod structure layout. This kind of mismatch will become
> much more likely if a kernel is built with different randomization seed
> for the struct layout randomization plugin.
> 
> Instead, add and use a new modinfo string for logging the module name.

+Lucas - probably something that the modinfo kmod utility should track.

Jon.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/2] module: Add module name to modinfo
  2017-04-25  7:00   ` Jon Masters
@ 2017-04-25  7:04     ` Jon Masters
  2017-04-26  2:58       ` Jessica Yu
  0 siblings, 1 reply; 9+ messages in thread
From: Jon Masters @ 2017-04-25  7:04 UTC (permalink / raw)
  To: Kees Cook, Jessica Yu
  Cc: Rusty Russell, Peter Zijlstra (Intel),
	Josh Poimboeuf, Ard Biesheuvel, Heinrich Schuchardt,
	Nicholas Piggin, Chris Metcalf, linux-kernel, Lucas De Marchi

Nevermind. Missread the patch as doing something different on first pass.

-- 
Computer Architect | Sent from my 64-bit #ARM Powered phone

> On Apr 25, 2017, at 03:00, Jon Masters <jcm@jonmasters.org> wrote:
> 
>> On 04/21/2017 06:35 PM, Kees Cook wrote:
>> 
>> Accessing the mod structure (e.g. for mod->name) prior to having completed
>> check_modstruct_version() can result in writing garbage to the error logs
>> if the layout of the mod structure loaded from disk doesn't match the
>> running kernel's mod structure layout. This kind of mismatch will become
>> much more likely if a kernel is built with different randomization seed
>> for the struct layout randomization plugin.
>> 
>> Instead, add and use a new modinfo string for logging the module name.
> 
> +Lucas - probably something that the modinfo kmod utility should track.
> 
> Jon.
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 0/2] module: Add module name to modinfo
  2017-04-21 22:35 [PATCH v2 0/2] module: Add module name to modinfo Kees Cook
  2017-04-21 22:35 ` [PATCH v2 1/2] module: Pass struct load_info into symbol checks Kees Cook
  2017-04-21 22:35 ` [PATCH v2 2/2] module: Add module name to modinfo Kees Cook
@ 2017-04-26  2:32 ` Jessica Yu
  2017-04-26  4:43   ` Kees Cook
  2 siblings, 1 reply; 9+ messages in thread
From: Jessica Yu @ 2017-04-26  2:32 UTC (permalink / raw)
  To: Kees Cook
  Cc: Rusty Russell, Peter Zijlstra (Intel),
	Josh Poimboeuf, Ard Biesheuvel, Heinrich Schuchardt,
	Nicholas Piggin, Chris Metcalf, linux-kernel

+++ Kees Cook [21/04/17 15:35 -0700]:
>The mod structure is accessed for the "name" field prior to validating
>sanity in check_modstruct_version(). This becomes very obvious once
>struct layout randomization is happening, so instead add the module
>name to modinfo and use that until the mod struct has been sanity-checked.
>
>-Kees
>
>v2:
>- adjusted for more odd name load failure cases; jeyu

Hi Kees!

These patches look fine to me, would you mind if I held on to them
until after the upcoming merge window? (Since we're at -rc8, and I'd
still like for them to sit in -next for a while)

Thanks,

Jessica

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/2] module: Add module name to modinfo
  2017-04-25  7:04     ` Jon Masters
@ 2017-04-26  2:58       ` Jessica Yu
  0 siblings, 0 replies; 9+ messages in thread
From: Jessica Yu @ 2017-04-26  2:58 UTC (permalink / raw)
  To: Jon Masters
  Cc: Kees Cook, Rusty Russell, Peter Zijlstra (Intel),
	Josh Poimboeuf, Ard Biesheuvel, Heinrich Schuchardt,
	Nicholas Piggin, Chris Metcalf, linux-kernel, Lucas De Marchi

+++ Jon Masters [25/04/17 03:04 -0400]:
>Nevermind. Missread the patch as doing something different on first pass.

It's good to give the kmod folks a heads up anyway (as name would be
visible in modinfo), thanks Jon!

>> On Apr 25, 2017, at 03:00, Jon Masters <jcm@jonmasters.org> wrote:
>>
>>> On 04/21/2017 06:35 PM, Kees Cook wrote:
>>>
>>> Accessing the mod structure (e.g. for mod->name) prior to having completed
>>> check_modstruct_version() can result in writing garbage to the error logs
>>> if the layout of the mod structure loaded from disk doesn't match the
>>> running kernel's mod structure layout. This kind of mismatch will become
>>> much more likely if a kernel is built with different randomization seed
>>> for the struct layout randomization plugin.
>>>
>>> Instead, add and use a new modinfo string for logging the module name.
>>
>> +Lucas - probably something that the modinfo kmod utility should track.
>>
>> Jon.
>>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 0/2] module: Add module name to modinfo
  2017-04-26  2:32 ` [PATCH v2 0/2] " Jessica Yu
@ 2017-04-26  4:43   ` Kees Cook
  2017-05-24  3:26     ` Jessica Yu
  0 siblings, 1 reply; 9+ messages in thread
From: Kees Cook @ 2017-04-26  4:43 UTC (permalink / raw)
  To: Jessica Yu
  Cc: Rusty Russell, Peter Zijlstra (Intel),
	Josh Poimboeuf, Ard Biesheuvel, Heinrich Schuchardt,
	Nicholas Piggin, Chris Metcalf, LKML

On Tue, Apr 25, 2017 at 7:32 PM, Jessica Yu <jeyu@redhat.com> wrote:
> +++ Kees Cook [21/04/17 15:35 -0700]:
>
>> The mod structure is accessed for the "name" field prior to validating
>> sanity in check_modstruct_version(). This becomes very obvious once
>> struct layout randomization is happening, so instead add the module
>> name to modinfo and use that until the mod struct has been sanity-checked.
>>
>> -Kees
>>
>> v2:
>> - adjusted for more odd name load failure cases; jeyu
>
>
> Hi Kees!
>
> These patches look fine to me, would you mind if I held on to them
> until after the upcoming merge window? (Since we're at -rc8, and I'd
> still like for them to sit in -next for a while)

Sure thing; I'm in no rush. :)

Thanks!

-Kees

-- 
Kees Cook
Pixel Security

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 0/2] module: Add module name to modinfo
  2017-04-26  4:43   ` Kees Cook
@ 2017-05-24  3:26     ` Jessica Yu
  0 siblings, 0 replies; 9+ messages in thread
From: Jessica Yu @ 2017-05-24  3:26 UTC (permalink / raw)
  To: Kees Cook
  Cc: Rusty Russell, Peter Zijlstra (Intel),
	Josh Poimboeuf, Ard Biesheuvel, Heinrich Schuchardt,
	Nicholas Piggin, Chris Metcalf, LKML

+++ Kees Cook [25/04/17 21:43 -0700]:
>On Tue, Apr 25, 2017 at 7:32 PM, Jessica Yu <jeyu@redhat.com> wrote:
>> +++ Kees Cook [21/04/17 15:35 -0700]:
>>
>>> The mod structure is accessed for the "name" field prior to validating
>>> sanity in check_modstruct_version(). This becomes very obvious once
>>> struct layout randomization is happening, so instead add the module
>>> name to modinfo and use that until the mod struct has been sanity-checked.
>>>
>>> -Kees
>>>
>>> v2:
>>> - adjusted for more odd name load failure cases; jeyu
>>
>>
>> Hi Kees!
>>
>> These patches look fine to me, would you mind if I held on to them
>> until after the upcoming merge window? (Since we're at -rc8, and I'd
>> still like for them to sit in -next for a while)
>
>Sure thing; I'm in no rush. :)

These have been applied to modules-next, thanks!

Jessica

>Thanks!
>
>-Kees

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2017-05-24  3:26 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-21 22:35 [PATCH v2 0/2] module: Add module name to modinfo Kees Cook
2017-04-21 22:35 ` [PATCH v2 1/2] module: Pass struct load_info into symbol checks Kees Cook
2017-04-21 22:35 ` [PATCH v2 2/2] module: Add module name to modinfo Kees Cook
2017-04-25  7:00   ` Jon Masters
2017-04-25  7:04     ` Jon Masters
2017-04-26  2:58       ` Jessica Yu
2017-04-26  2:32 ` [PATCH v2 0/2] " Jessica Yu
2017-04-26  4:43   ` Kees Cook
2017-05-24  3:26     ` Jessica Yu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).