From owner-freebsd-bugs Sun Oct 13 15:20:05 1996 Return-Path: owner-bugs Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id PAA08793 for bugs-outgoing; Sun, 13 Oct 1996 15:20:05 -0700 (PDT) Received: (from gnats@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id PAA08753; Sun, 13 Oct 1996 15:20:02 -0700 (PDT) Resent-Date: Sun, 13 Oct 1996 15:20:02 -0700 (PDT) Resent-Message-Id: <199610132220.PAA08753@freefall.freebsd.org> Resent-From: gnats (GNATS Management) Resent-To: freebsd-bugs Resent-Reply-To: FreeBSD-gnats@freefall.FreeBSD.org, peter@spinner.DIALix.COM Received: from spinner.DIALix.COM (peter@spinner.DIALix.COM [192.203.228.67]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id PAA08678 for ; Sun, 13 Oct 1996 15:19:17 -0700 (PDT) Received: (from peter@localhost) by spinner.DIALix.COM (8.8.0/8.8.0) id GAA02432; Mon, 14 Oct 1996 06:19:09 +0800 (WST) Message-Id: <199610132219.GAA02432@spinner.DIALix.COM> Date: Mon, 14 Oct 1996 06:19:09 +0800 (WST) From: Peter Wemm Reply-To: peter@spinner.DIALix.COM To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.2 Subject: kern/1790: access to /dev/kmem panics system Sender: owner-bugs@freebsd.org X-Loop: FreeBSD.org Precedence: bulk >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 : pushl %ebp 0xf01a25d5 : movl %esp,%ebp 0xf01a25d7 : pushl %ebx 0xf01a25d8 : movl 0x8(%ebp),%ecx 0xf01a25db : movl 0xc(%ebp),%ebx 0xf01a25de : testl %ecx,%ecx 0xf01a25e0 : je 0xf01a2614 0xf01a25e2 : movl %ebx,%edx 0xf01a25e4 : shrl $0x16,%edx 0xf01a25e7 : movl (%ecx),%eax 0xf01a25e9 : cmpl $0x0,(%eax,%edx,4) 0xf01a25ed : je 0xf01a2614 0xf01a25ef : pushl %ecx 0xf01a25f0 : call 0xf01a24b8 0xf01a25f5 : movl %eax,%edx 0xf01a25f7 : movl %ebx,%eax 0xf01a25f9 : shrl $0xc,%eax 0xf01a25fc : movl (%edx,%eax,4),%edx ^^^^^^^^^^^^^^^^^^^^^^^ Here 0xf01a25ff : 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 #include 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: