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