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:	Thu, 19 Jun 2008 15:11:54 +0200 (CEST)
From:	Jiri Kosina <jkosina@...e.cz>
To:	Rusty Russell <rusty@...tcorp.com.au>,
	Andrew Morton <akpm@...ux-foundation.org>
cc:	linux-kernel@...r.kernel.org, llipavsky@...e.cz
Subject: [PATCH] module: make symbol_put_addr() work for all exported
 symbols

symbol_put_addr() works only for exported function names (symbols present 
in text section). This for example means that

         symbol_put_addr(__symbol_get("any_exported_variable_name"))

triggers a BUG, which really seems wrong.

This patch introduces generic lookup_symbol_address(), which performs 
lookup on symbol tables of all modules according to the address, and makes 
symbol_put_addr() use this interface to find the module owner instead.

Signed-off-by: Jiri Kosina <jkosina@...e.cz>

diff --git a/kernel/module.c b/kernel/module.c
index 5f80478..77ff23e 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -302,6 +302,64 @@ static unsigned long find_symbol(const char *name,
  	return -ENOENT;
  }

+/* Lookup module symbol by address */
+const static struct kernel_symbol *lookup_symbol_address(unsigned long addr,
+		struct module **owner)
+{
+	struct module *mod;
+	const struct kernel_symbol *s;
+	unsigned int i;
+
+	/* Core kernel first */
+	struct {
+		const struct kernel_symbol *s_start;
+		const struct kernel_symbol *s_end;
+	} kern_syms[] = {
+		{ __start___ksymtab, __stop___ksymtab },
+		{ __start___ksymtab_gpl, __stop___ksymtab_gpl },
+		{ __start___ksymtab_gpl_future, __stop___ksymtab_gpl_future },
+		{ __start___ksymtab_unused, __stop___ksymtab_unused },
+		{ __start___ksymtab_unused_gpl, __stop___ksymtab_unused_gpl },
+	};
+
+	for (i = 0; i < ARRAY_SIZE(kern_syms); i++) {
+		for (s = kern_syms[i].s_start; s < kern_syms[i].s_end; s++) {
+			if (s->value == addr) {
+				if (owner)
+					*owner = NULL;
+				return s;
+			}
+		}
+	}
+
+	/* Now try modules */
+	list_for_each_entry(mod, &modules, list) {
+		struct {
+			const struct kernel_symbol *sym;
+			unsigned int num;
+		} arr[] = {
+			{ mod->syms, mod->num_syms },
+			{ mod->gpl_syms, mod->num_gpl_syms },
+			{ mod->gpl_future_syms, mod->num_gpl_future_syms },
+			{ mod->unused_syms, mod->num_unused_syms },
+			{ mod->unused_gpl_syms, mod->num_unused_gpl_syms },
+		};
+
+		for (i = 0; i < ARRAY_SIZE(arr); i++) {
+			for (s = arr[i].sym; s < arr[i].sym + arr[i].num; s++) {
+				if (s->value == addr) {
+					if (owner)
+						*owner = mod;
+					return s;
+				}
+			}
+		}
+	}
+	return NULL;
+}
+
+
+
  /* Search for module by name: must hold module_mutex. */
  static struct module *find_module(const char *name)
  {
@@ -799,13 +857,12 @@ EXPORT_SYMBOL(__symbol_put);
  void symbol_put_addr(void *addr)
  {
  	struct module *modaddr;
-
-	if (core_kernel_text((unsigned long)addr))
-		return;
-
-	if (!(modaddr = module_text_address((unsigned long)addr)))
+
+	if (!lookup_symbol_address((unsigned long)addr, &modaddr))
  		BUG();
-	module_put(modaddr);
+
+	if(modaddr)
+		module_put(modaddr);
  }
  EXPORT_SYMBOL_GPL(symbol_put_addr);



--
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