From owner-freebsd-bugs Wed Apr 28 6:50: 4 1999 Delivered-To: freebsd-bugs@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (Postfix) with ESMTP id 7C2FE14D39 for ; Wed, 28 Apr 1999 06:50:00 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id GAA25866; Wed, 28 Apr 1999 06:50:00 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: by hub.freebsd.org (Postfix, from userid 32767) id 031E714DC4; Wed, 28 Apr 1999 06:43:48 -0700 (PDT) Message-Id: <19990428134348.031E714DC4@hub.freebsd.org> Date: Wed, 28 Apr 1999 06:43:48 -0700 (PDT) From: smcclure@emc.com To: freebsd-gnats-submit@freebsd.org X-Send-Pr-Version: www-1.0 Subject: kern/11366: Filesystem can cause hang/crash in certain situations Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 11366 >Category: kern >Synopsis: Filesystem can cause hang/crash in certain situations >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Apr 28 06:50:00 PDT 1999 >Closed-Date: >Last-Modified: >Originator: Steve McClure >Release: 3.1 Release >Organization: EMC Corporation >Environment: FreeBSD lbn1050.lss.emc.com 3.1-RELEASE FreeBSD 3.1-RELEASE #7: Tue Apr 27 14:43:51 GMT 1999 smcclure@lbn1050.lss.emc.com:/usr/src/sys/compile/COMPAQ.AP200 i386 >Description: Hello. I think I have found a bug in the UFS filesystem code in ufs_lookup.c that can cause the kernel to hang/crash in certain situations. (Note this is coming from the 3.1 release code. If this has been fixed, sorry, but I couldn't find any report of it.) On line 238 this assignment is made: ep = (struct direct *)((char *)bp->b_data + entryoffsetinblock); This pointer is then used during the lookup of directory entry names while looking for a specific entry. On line 311, if we have actually found the entry we are looking for, we save the inode and the record length, and then do a brelse of bp. I.E. we release the buffer that the ep pointer is pointing to. We then jump to the "found" label. The found label is on line 405. On line 412, we do this check: if (entryoffsetinblock + DIRSIZ(OFSFMT(vdp), ep) > dp->i_size) { I have found that this can cause problems because we are using a pointer to a buffer that now may contain garbage or not even exist anymore (if we managed to get interrupted between here and there and the buffer gets used by someone else.) It only happens under extreme circumstances in ufs. Note that I found this problem while working on a variation of the ufs filesystem, where timing was more critical (as in the buffer would always be released before we got to the pointer use again) but it can still be a big problem. I'm not sure if this exists in any of the other filesystems or not. >How-To-Repeat: Under standard ufs, it's very hard to get it to repeat reliably (in fact I think I've only seen it twice under extremely heavy load in very "weird" circumstances, but not even sure if it was this.) I was able to verify it using a variation of brelse that makes sure the buffer is released before returning. >Fix: My solution to this was to release the buffer *after* this check. On line 313, I took out the "brelse(bp);" call. On line 334 there is this code: if (bp != NULL) brelse(bp); I also put this below the bad entry check to release bp after the check has been done and we are done with the buffer. >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message