PATCH: kallsyms_symbol_next()

Chris Rorvick chris_rorvick at yahoo.com
Tue Mar 9 21:21:17 PST 2004


KDB Maintainers:
A bug exists in the kallsyms_symbol_next() that causes
an invalid page fault.  When moving to the next module
(outer for-loop), the static variable ka_sym should
always be updated to reference the new module's symbol
table.  This is only happening on the first call to
this method, though.  This causes ka_sym to run beyond
the end of the previous module's symbol table and KDB
dies when it uses a random offset into the string
table of the current module.

I found this bug when trying to do tab completion on
".text".  The patch is for the stock 2.4.23 source
patched with the kdb-v4.3-2.4.23-common-2 and
kdb-v4.3-2.4.23-i386-1.

Let me know if this is helpful, or if I can provide
more information.

Thanks,

Chris Rorvick
chris_rorvick at yahoo.com

__________________________________
Do you Yahoo!?
Yahoo! Search - Find what you’re looking for faster
http://search.yahoo.com

-- Attached file included as plaintext by Ecartis --
-- File: kdb-v4.3-2.4.23.patch
-- Desc: kdb-v4.3-2.4.23.patch

--- linux-2.4.23-kdb/kdb/kdb_io.c	2004-03-09 14:41:46.000000000 +0000
+++ linux-2.4.23-kdb-patched/kdb/kdb_io.c	2004-03-09 14:48:36.000000000 +0000
@@ -346,7 +346,7 @@
 						}
 						kdb_printf("\n");
 						for(i=0;i<count;i++) {
-							if(kallsyms_symbol_next(p_tmp, i)<0)
+							if(kallsyms_symbol_next(p_tmp, i) == 0)
 								break;
 							kdb_printf("%s ",p_tmp);
 							*(p_tmp+len)='\0';
--- linux-2.4.23-kdb/kernel/kallsyms.c	2004-03-09 14:41:46.000000000 +0000
+++ linux-2.4.23-kdb-patched/kernel/kallsyms.c	2004-03-10 03:49:41.000000000 +0000
@@ -365,7 +365,7 @@
 }
 
 /* paramter prefix_name is a buffer provided by the caller, it must ends with '\0'. */
-/* parameter flag = 0 means search from the head, flag = 1 means continue search. */
+/* parameter flag = 0 means search from the head, flag != 0 means continue search. */
 /* return a symbol string which matches the given prefix. */
 /* return 0 means no prefix string is found. */
 /* return >0 means prefix string is found. */
@@ -374,9 +374,9 @@
 	int flag			/* Indicate if search from the head */
 	)
 {
-	const struct kallsyms_header	*ka_hdr = NULL;	/* stupid gcc */
-	const char			*ka_str = NULL;
+	static const struct kallsyms_header	*ka_hdr;
 	static const struct kallsyms_symbol	*ka_sym;
+	static const char			*ka_str;
 	static const struct module *m;
 	static int i;
 	int prefix_len=strlen(prefix_name);
@@ -388,22 +388,16 @@
 
 	if(!flag) {
 		m = *kallsyms_module_list;
+		goto init_mod_kallsyms;
 	}
 
-	for (; m; m = m->next) {
+	while (1) {
 		if (!mod_member_present(m, kallsyms_start) ||
 		    !mod_member_present(m, kallsyms_end) ||
 		    m->kallsyms_start >= m->kallsyms_end)
 			continue;
-		ka_hdr = (struct kallsyms_header *)m->kallsyms_start;
-		if(!flag) {
-			ka_sym = (struct kallsyms_symbol *)
-				((char *)(ka_hdr) + ka_hdr->symbol_off);
-			i = 0;
-		}
-		ka_str = ((char *)(ka_hdr) + ka_hdr->string_off);
 
-		for (; i < ka_hdr->symbols; ++i, kallsyms_next_sym(ka_hdr, ka_sym)) {
+		for (; i < ka_hdr->symbols; ++i) {
 			p = ka_str + ka_sym->name_off;
 			if (strncmp(p, prefix_name,prefix_len) == 0) {
 				strncpy(prefix_name, p, strlen(p)+1);
@@ -411,7 +405,17 @@
 				kallsyms_next_sym(ka_hdr, ka_sym);
 				return 1;
 			}
+			kallsyms_next_sym(ka_hdr, ka_sym);
 		}
+
+		if ( (m = m->next) == NULL)
+			break;
+
+init_mod_kallsyms:
+		ka_hdr = (void *) (m->kallsyms_start);
+		ka_sym = (void *) (m->kallsyms_start + ka_hdr->symbol_off);
+		ka_str = (void *) (m->kallsyms_start + ka_hdr->string_off);
+		i = 0;
 	}
 
 	return 0;


---------------------------
Use http://oss.sgi.com/ecartis to modify your settings or to unsubscribe.


More information about the kdb mailing list