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
[EMAIL PROTECTED]

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

Reply via email to