Skip site navigation (1)Skip section navigation (2)
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>