[PATCH] validate_mem uses uninitialized memory

Pavel Roskin proski at gnu.org
Mon Apr 21 13:46:32 BST 2003


Hello, Russell!

If I compile a recent 2.5.x kernel without CONFIG_ISA defined, I get an
oops in validate_mem().  Stack trace contains 0x6b6b6b6 - a clear sign
that freed memory is being accessed:

*pde = 00000000
Oops: 0000 [#1]
CPU:    0
EIP:    0060:[<c88edef0>]    Not tainted
EFLAGS: 00010a83
EIP is at validate_mem+0x70/0xb0 [pcmcia_core]
eax: 00000000   ebx: 6b6b6b6b   ecx: 00000001   edx: c02fd078
esi: c551a000   edi: c551a000   ebp: c4a15a10   esp: c4a159fc
ds: 007b   es: 007b   ss: 0068
Process cardmgr (pid: 1096, threadinfo=c4a14000 task=c62bc120)
Stack: 000c0000 00000000 c551a000 0000c001 c551a03c c4a15a3c c88eb11a c551a000
       00000000 00000000 c4a15a30 c0147721 c4b77ebc 00000002 c4a15ac2 c4a15ac2
       c4a15a70 c88eb359 c551a000 00000000 00000021 00000021 00000000 00000002
Call Trace:
 [<c88eb11a>] set_cis_map+0x9a/0x110 [pcmcia_core]
 [<c0147721>] wake_up_buffer+0x11/0x30
 [<c88eb359>] read_cis_mem+0x1c9/0x250 [pcmcia_core]
 [<c88eb78b>] read_cis_cache+0x17b/0x1c0 [pcmcia_core]
 [<c88ebd5c>] pcmcia_get_next_tuple+0x9c/0x2b0 [pcmcia_core]
 [<c88eba75>] pcmcia_get_first_tuple+0xb5/0x160 [pcmcia_core]

It's the second validate_mem() in drivers/pcmcia/rsrc_mgr.c - the one used
when CONFIG_PCMCIA_PROBE is not defined.  It turns out the memory is freed
in do_mem_probe() when it's called from validate_mem().

The solution is to use the same trick as in the first validate_mem().
This problem is quite serious and it's not specific to the plx9052 driver.
I see it with yenta_socket as well.

Here's the patch:

===============================
--- linux.orig/drivers/pcmcia/rsrc_mgr.c
+++ linux/drivers/pcmcia/rsrc_mgr.c
@@ -499,14 +499,16 @@ void validate_mem(socket_info_t *s)

 void validate_mem(socket_info_t *s)
 {
-    resource_map_t *m;
+    resource_map_t *m, *n;
     static int done = 0;

     if (probe_mem && done++ == 0) {
 	down(&rsrc_sem);
-	for (m = mem_db.next; m != &mem_db; m = m->next)
+	for (m = mem_db.next; m != &mem_db; m = n) {
+	    n = m->next;
 	    if (do_mem_probe(m->base, m->num, s))
 		break;
+	}
 	up(&rsrc_sem);
     }
 }
===============================

-- 
Regards,
Pavel Roskin



More information about the linux-pcmcia mailing list