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.) 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? 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*
Responsible Changed From-To: freebsd-bugs->dwmalone Local PR.
State Changed From-To: open->closed The submitted patch was accepted verbatim as delta 1.18 to fsck/pass1.c. The patch resolved the problem.