From owner-freebsd-current@FreeBSD.ORG Fri Jan 28 02:51:30 2005 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3CD2816A4CE for ; Fri, 28 Jan 2005 02:51:30 +0000 (GMT) Received: from mail2.dreamscape.com (mail2.dreamscape.com [206.64.128.18]) by mx1.FreeBSD.org (Postfix) with ESMTP id 94EF843D2F for ; Fri, 28 Jan 2005 02:51:29 +0000 (GMT) (envelope-from krentel@dreamscape.com) Received: from blue.mwk.domain (syr-mdm-05-216-171-177-169.dreamscape.com [216.171.177.169])j0S2pPlO022521; Thu, 27 Jan 2005 21:51:25 -0500 (EST) Received: from blue.mwk.domain (localhost [127.0.0.1]) by blue.mwk.domain (8.12.9p2/8.12.9) with ESMTP id j0S2sMJH050277; Thu, 27 Jan 2005 21:54:22 -0500 (EST) (envelope-from krentel@blue.mwk.domain) Message-Id: <200501280254.j0S2sMJH050277@blue.mwk.domain> To: Kris Kennaway , freebsd-current@freebsd.org Date: Thu, 27 Jan 2005 21:54:22 -0500 From: "Mark W. Krentel" X-Mailman-Approved-At: Fri, 28 Jan 2005 12:53:38 +0000 cc: alc@cs.rice.edu Subject: Re: fstat triggered INVARIANTS panic in memrw() X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 28 Jan 2005 02:51:30 -0000 I've looked a little deeper into Kris's fstat panic. Turns out there are bugs in three places. (1) fstat(1) sometimes calls kvm_read() with a ridiculously out-of- bounds value for nbytes. In fstat.c, dofiles() gets a struct filedesc via kvm_read(), and sometimes the value for fd_lastfile (the high- water mark for file descriptors) is garbage. This value (times sizeof(struct file *)) is then passed to the next kvm_read() as the number of bytes to read. A classic case where you need to be suspicious of the data from kvm_read() in a running kernel. This same problem was reported a year ago in PR i386/62699. The best you can do is pick some bounds and add a sanity check to fd_lastfile. I sent a patch to PR 62699. I don't know if fstat(1) has a regular maintainer, but there have been a couple commits over the past year or two. If someone in the area could review the patch and commit it (it's short). (2) kvm_read() and kmem(4) don't check for address wrap. This shows up in kernacc() in vm_glue.c and then in vm_map_check_protection() in vm_map.c. I was able to induce the same address wrap in kernacc() without using fstat(1) in two ways. One is with kvm_open(), kvm_getprocs() and kvm_read(), the other is with open("/dev/kmem"), lseek() and read(). In both cases, a large enough value for number of bytes will induce address wrap in kernacc(). I haven't looked into this too deeply. I know the address wrap happens, but I don't know the best place to fix it. Maybe someone more familiar with kvm(3) and kmem(4) could take a look. (3) kernacc() in vm_glue.c doesn't check for address wrap. Alan recently committed a patch for kernacc(), so this is now fixed. --Mark