Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 14 Oct 1996 06:19:09 +0800 (WST)
From:      Peter Wemm <peter@spinner.DIALix.COM>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/1790: access to /dev/kmem panics system
Message-ID:  <199610132219.GAA02432@spinner.DIALix.COM>
Resent-Message-ID: <199610132220.PAA08753@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         1790
>Category:       kern
>Synopsis:       access to /dev/kmem panics system
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Oct 13 15:20:01 PDT 1996
>Last-Modified:
>Originator:     Peter Wemm
>Organization:
Not..
>Release:        FreeBSD 2.2-CURRENT i386
>Environment:

FreeBSD curie.dialix.com.au 2.2-CURRENT FreeBSD 2.2-CURRENT #5: Mon Oct 14 04:28:03 EST 1996     peter@curie.dialix.com.au:/home/src/sys/compile/CURIE  i386

Built from sources only a few hours old.

>Description:

identd appears to have found an address in /dev/kmem that causes a kernel
panic, although it may just be a pmap bug.  I do not know the address that
identd was trying to access when it died.  At a guess, I think it was trying
to look up 0xffff0000, this address causes the same panic in the test
program.

Fatal trap 12: page fault while in kernel mode
fault virtual address   = 0xefffffc0
fault code              = supervisor read, page not present
instruction pointer     = 0x8:0xf01a25fc
stack pointer           = 0x10:0xefbffe28
frame pointer           = 0x10:0xefbffe30
code segment            = base 0x0, limit 0xfffff, type 0x1b
                        = DPL 0, pres 1, def32 1, gran 1
processor eflags        = interrupt enabled, resume, IOPL = 0
current process         = 1834 (identd)

Addresses around %eip
f01a2548 t _pmap_pte_quick
f01a25d4 T _pmap_extract
f01a261c T _pmap_qenter

Dump of assembler code from 0xf01a25d4 to 0xf01a2600:
0xf01a25d4 <pmap_extract>:      pushl  %ebp
0xf01a25d5 <pmap_extract+1>:    movl   %esp,%ebp
0xf01a25d7 <pmap_extract+3>:    pushl  %ebx
0xf01a25d8 <pmap_extract+4>:    movl   0x8(%ebp),%ecx
0xf01a25db <pmap_extract+7>:    movl   0xc(%ebp),%ebx
0xf01a25de <pmap_extract+10>:   testl  %ecx,%ecx
0xf01a25e0 <pmap_extract+12>:   je     0xf01a2614 <pmap_extract+64>
0xf01a25e2 <pmap_extract+14>:   movl   %ebx,%edx
0xf01a25e4 <pmap_extract+16>:   shrl   $0x16,%edx
0xf01a25e7 <pmap_extract+19>:   movl   (%ecx),%eax
0xf01a25e9 <pmap_extract+21>:   cmpl   $0x0,(%eax,%edx,4)
0xf01a25ed <pmap_extract+25>:   je     0xf01a2614 <pmap_extract+64>
0xf01a25ef <pmap_extract+27>:   pushl  %ecx
0xf01a25f0 <pmap_extract+28>:   call   0xf01a24b8 <get_ptbase>
0xf01a25f5 <pmap_extract+33>:   movl   %eax,%edx
0xf01a25f7 <pmap_extract+35>:   movl   %ebx,%eax
0xf01a25f9 <pmap_extract+37>:   shrl   $0xc,%eax
0xf01a25fc <pmap_extract+40>:   movl   (%edx,%eax,4),%edx
                               ^^^^^^^^^^^^^^^^^^^^^^^ Here
0xf01a25ff <pmap_extract+43>:   andl   $0xfffff000,%edx

vm_offset_t
pmap_extract(pmap, va)
        register pmap_t pmap;
        vm_offset_t va;
{
        vm_offset_t rtval;
        if (pmap && *pmap_pde(pmap, va)) {
                unsigned *pte;
                pte = get_ptbase(pmap) + i386_btop(va);
                rtval = ((*pte & PG_FRAME) | (va & PAGE_MASK));
                        ^^^^^^^^^^^^^^^^^^
                return rtval;
        }
        return 0;
}

The code in mem.c that triggered it:
	addr = trunc_page(uio->uio_offset);
	eaddr = round_page(uio->uio_offset + c);
	for (; addr < eaddr; addr += PAGE_SIZE)
		if (pmap_extract(kernel_pmap, addr) == 0)
		    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
			return EFAULT;
>How-To-Repeat:

save your work, sync a few times, then run this program:

#include <sys/types.h>
#include <unistd.h>
char buf[4096];
main()
{
        int fd = open("/dev/kmem", 0);
        unsigned long offset = 0xffff0000;
        lseek(fd, offset, 0);
        read(fd, buf, 4096);
}

0xffff0000 appears to be one of the common power-up patterns in DRAM that
I've seen on uncleared pages.

>Fix:
	
Not sure, but is that code in mem.c right?  It doesn't appear to
do any bounds checking on what is passed to pmap_extract().  Perhaps
it needs to trap addresses beyond the top of the kernel address
space?  Perhaps it's pmap_pde at fault since it's returning "success"
for an address that would be on the 64th kernel pde, when only 63 (NKPDE)
exist. Checking at that level would probably be a slowdown though.

>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199610132219.GAA02432>