From owner-freebsd-bugs Wed Jun 21 15:30: 9 2000 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 3FA3E37C10F for ; Wed, 21 Jun 2000 15:30:01 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id PAA85013; Wed, 21 Jun 2000 15:30:01 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from salmon.maths.tcd.ie (salmon.maths.tcd.ie [134.226.81.11]) by hub.freebsd.org (Postfix) with SMTP id 215B537B9B6 for ; Wed, 21 Jun 2000 15:26:40 -0700 (PDT) (envelope-from iedowse@maths.tcd.ie) Received: from walton.maths.tcd.ie by salmon.maths.tcd.ie with SMTP id ; 21 Jun 2000 23:26:39 +0100 (BST) Message-Id: <200006212326.aa55817@walton.maths.tcd.ie> Date: Wed, 21 Jun 2000 23:26:37 +0100 (BST) From: iedowse@maths.tcd.ie Reply-To: iedowse@maths.tcd.ie To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.2 Subject: bin/19426: fsck(8) allows non-zero di_size on device inodes Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 19426 >Category: bin >Synopsis: fsck(8) allows non-zero di_size on device inodes >Confidential: no >Severity: serious >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Jun 21 15:30:00 PDT 2000 >Closed-Date: >Last-Modified: >Originator: Ian Dowse >Release: FreeBSD 3.4-STABLE i386 >Organization: School of Mathematics, Trinity College Dublin >Environment: All versions of FreeBSD. >Description: The FreeBSD ffs code assumes that the di_size field of a device special file's inode will always be zero. However fsck(8) does not ensure that this is the case. This is only a problem if part of a filesystem's inode tables should become corrupted. In this case it is possible for fsck to consider the filesystem as 'clean' when it is not; attempts to delete these corrupted device special files wil result in system panics. (After a relatively minor case of disk corruption on a machine I was working on, deleting the affected device file appeared to make ffs_truncate go wild. The resulting corruption was much worse than the original problem.) >How-To-Repeat: The following commands demonstrate the problem by specifically writing junk into the di_size field of a special file's inode. dd if=/dev/zero bs=1k of=/tmp/fdimage count=1440 vnconfig -e /dev/vn0 /tmp/fdimage newfs -T fd1440 /dev/vn0c mount /dev/vn0c /mnt mknod /mnt/chardev c 1 1 umount /mnt # some magic to corrupt the di_size field of 'chardev' dd if=/dev/vn0c skip=56 count=1 > /tmp/x (head -c 395 /tmp/x; echo -n x; tail -c 116 /tmp/x) > /tmp/x1 dd if=/tmp/x1 of=/dev/vn0c seek=56 count=1 # Perform a full check, note how no errors are found fsck /dev/vn0 mount /dev/vn0c /mnt rm /mnt/chardev # *Boom* >Fix: Apply the following patch in src/sbin/fsck. Someone might like to comment on whether checking for types IFIFO and IFSOCK is sensible here? --- pass1.c.orig Wed Jun 21 22:47:35 2000 +++ pass1.c Wed Jun 21 22:49:12 2000 @@ -209,6 +209,12 @@ dp->di_mode = IFREG|0600; inodirty(); } + if ((mode == IFBLK || mode == IFCHR || mode == IFIFO || + mode == IFSOCK) && dp->di_size != 0) { + if (debug) + printf("bad special-file size %qu:", dp->di_size); + goto unknown; + } ndb = howmany(dp->di_size, sblock.fs_bsize); if (ndb < 0) { if (debug) >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message