Date: Wed, 21 Jun 2000 23:26:37 +0100 (BST) From: iedowse@maths.tcd.ie To: FreeBSD-gnats-submit@freebsd.org Subject: bin/19426: fsck(8) allows non-zero di_size on device inodes Message-ID: <200006212326.aa55817@walton.maths.tcd.ie>
next in thread | raw e-mail | index | archive | help
>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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200006212326.aa55817>
