lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Fri, 27 Jun 2008 05:40:50 -0700
From:	"nkalmala@...il.com" <nkalmala@...il.com>
To:	linux-kernel@...r.kernel.org
CC:	akpm@...ux-foundation.org, rusty@...tcorp.com.au
Subject: [patch] experimental: try-resolve-unexported-symbol-references-in-modules

For purely experimental purposes, let the kernel resolve unexported-symbol references
in external modules when loading them. Iff used carefully, this helps save time on 
development cycles. building testing experimenting certain kinds of changes becomes 
really fast.

Signed-off-by: <nkalmala@...il.com>
---

 include/linux/kallsyms.h |   11 +++++++++++
 include/linux/module.h   |   11 ++++++++---
 init/Kconfig             |   18 ++++++++++++++++++
 kernel/kallsyms.c        |   21 ++++++++++++++++++---
 kernel/module.c          |   31 ++++++++++++++++++++++++++++---
 5 files changed, 83 insertions(+), 9 deletions(-)


diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
index 00c1801..f39569d 100644
--- a/include/linux/kallsyms.h
+++ b/include/linux/kallsyms.h
@@ -13,8 +13,12 @@
 			 2*(BITS_PER_LONG*3/10) + (MODULE_NAME_LEN - 1) + 1)
 
 #ifdef CONFIG_KALLSYMS
+struct module;
 /* Lookup the address for a symbol. Returns 0 if not found. */
 unsigned long kallsyms_lookup_name(const char *name);
+/* Like above, but this also tells which module (owner) defines the symbol,
+ * NULL if kernel or no symbol */
+unsigned long kallsyms_lookup_name_owner(const char *name, struct module **owner);
 
 extern int kallsyms_lookup_size_offset(unsigned long addr,
 				  unsigned long *symbolsize,
@@ -42,6 +46,13 @@ static inline unsigned long kallsyms_lookup_name(const char *name)
 	return 0;
 }
 
+static inline unsigned long kallsyms_lookup_name_owner(const char *name,
+		struct module **owner)
+{
+	if (owner) *owner = NULL;
+	return 0;
+}
+
 static inline int kallsyms_lookup_size_offset(unsigned long addr,
 					      unsigned long *symbolsize,
 					      unsigned long *offset)
diff --git a/include/linux/module.h b/include/linux/module.h
index 3e03b1a..e99da01 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -365,8 +365,11 @@ int is_module_address(unsigned long addr);
 int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
 			char *name, char *module_name, int *exported);
 
-/* Look for this name: can be of form module:name. */
-unsigned long module_kallsyms_lookup_name(const char *name);
+/* Look for this name: can be of form module:name.
+ * If name is a module symbol, *owner will be set to struct module, NULL
+ * otherwise */
+unsigned long module_kallsyms_lookup_name(const char *name,
+		struct module **owner);
 
 extern void __module_put_and_exit(struct module *mod, long code)
 	__attribute__((noreturn));
@@ -528,8 +531,10 @@ static inline int module_get_kallsym(unsigned int symnum, unsigned long *value,
 	return -ERANGE;
 }
 
-static inline unsigned long module_kallsyms_lookup_name(const char *name)
+static inline unsigned long module_kallsyms_lookup_name(const char *name,
+		struct module **owner)
 {
+	if (owner) *owner = NULL;
 	return 0;
 }
 
diff --git a/init/Kconfig b/init/Kconfig
index 6199d11..c0c2810 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -892,6 +892,24 @@ config MODULE_SRCVERSION_ALL
 	  the version).  With this option, such a "srcversion" field
 	  will be created for all modules.  If unsure, say N.
 
+config RESOLVE_UNEXPORTED_SYMBOL
+	bool "Try to resolve unexported symbols (experimental use only)"
+	depends on MODULES && KALLSYMS
+	default n
+	help
+	  Say Y here to let the kernel resolve unexported-symbol references
+	  in external modules when loading them. This taints the kernel with
+	  TAINT_PROPRIETARY_MODULE and TAINT_FORCED_MODULE, when the first
+	  unexported symbol gets resolved; this also bypasses version checks,
+	  if enabled, on such symbols. Use carefully.
+	  Building the kernel with KALLSYMS_ALL expands the range of symbols
+	  that can be referenced.
+	  This is purely for experimental purposes. Enable this config if you
+	  prefer experimenting in the kernel using loadable modules. Once the
+	  kernel gets tainted by resolving an unexported symbol, any subsequent
+	  kernel issue becomes the individual's responsibility to worry; do not
+	  report back those issues.
+
 config KMOD
 	bool "Automatic kernel module loading"
 	depends on MODULES
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 6fc0040..f0e8928 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -146,7 +146,8 @@ static unsigned int get_symbol_offset(unsigned long pos)
 }
 
 /* Lookup the address for this symbol. Returns 0 if not found. */
-unsigned long kallsyms_lookup_name(const char *name)
+static unsigned long __kallsyms_lookup_name_owner(const char *name,
+		struct module **owner)
 {
 	char namebuf[KSYM_NAME_LEN];
 	unsigned long i;
@@ -155,10 +156,24 @@ unsigned long kallsyms_lookup_name(const char *name)
 	for (i = 0, off = 0; i < kallsyms_num_syms; i++) {
 		off = kallsyms_expand_symbol(off, namebuf);
 
-		if (strcmp(namebuf, name) == 0)
+		if (strcmp(namebuf, name) == 0) {
+			if (owner)
+				*owner = NULL;
 			return kallsyms_addresses[i];
+		}
 	}
-	return module_kallsyms_lookup_name(name);
+	return module_kallsyms_lookup_name(name, owner);
+}
+
+unsigned long kallsyms_lookup_name(const char *name)
+{
+	return __kallsyms_lookup_name_owner(name, NULL);
+}
+
+unsigned long kallsyms_lookup_name_owner(const char *name,
+		struct module **owner)
+{
+	return __kallsyms_lookup_name_owner(name, owner);
 }
 
 static unsigned long get_symbol_pos(unsigned long addr,
diff --git a/kernel/module.c b/kernel/module.c
index 5f80478..c8863f1 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1001,13 +1001,30 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
 	struct module *owner;
 	unsigned long ret;
 	const unsigned long *crc;
+	int check_ver = 1;
 
 	ret = find_symbol(name, &owner, &crc,
 			  !(mod->taints & TAINT_PROPRIETARY_MODULE), true);
+
+#ifdef CONFIG_RESOLVE_UNEXPORTED_SYMBOL
+	if (IS_ERR_VALUE(ret)) {
+		unsigned long addr = kallsyms_lookup_name_owner(name, &owner);
+		check_ver = 0;
+		if (addr) {
+			ret = addr;
+			printk(KERN_WARNING "%s: Symbol %s not exported.. "
+				"resolved to %s:%lx - kernel tainted\n", mod->name,
+				name, owner ? owner->name : "", ret);
+			add_taint(TAINT_FORCED_MODULE);
+			add_taint(TAINT_PROPRIETARY_MODULE);
+		}
+	}
+#endif
+
 	if (!IS_ERR_VALUE(ret)) {
 		/* use_module can fail due to OOM,
 		   or module initialization or unloading */
-		if (!check_version(sechdrs, versindex, name, mod, crc) ||
+		if ((check_ver && !check_version(sechdrs, versindex, name, mod, crc)) ||
 		    !use_module(mod, owner))
 			ret = -EINVAL;
 	}
@@ -2435,8 +2452,12 @@ static unsigned long mod_find_symname(struct module *mod, const char *name)
 	return 0;
 }
 
-/* Look for this name: can be of form module:name. */
-unsigned long module_kallsyms_lookup_name(const char *name)
+/* Look for this name: can be of form module:name.
+ * if symbol found in a module, *owner will be set to its struct module,
+ * else NULL
+ */
+unsigned long module_kallsyms_lookup_name(const char *name,
+		struct module **owner)
 {
 	struct module *mod;
 	char *colon;
@@ -2455,6 +2476,10 @@ unsigned long module_kallsyms_lookup_name(const char *name)
 				break;
 	}
 	preempt_enable();
+
+	if (owner)
+		*owner = ret ? mod : NULL;
+
 	return ret;
 }
 #endif /* CONFIG_KALLSYMS */
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ