Subject: bin/1366: [dM] fsck pass1 ignores fs_csaddr
To: None <>
From: der Mouse <mouse@Collatz.McRCIM.McGill.EDU>
List: netbsd-bugs
Date: 08/17/1995 14:40:51
>Number:         1366
>Category:       bin
>Synopsis:       [dM] fsck pass1 ignores fs_csaddr
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Aug 17 14:50:01 1995
>Originator:     der Mouse
>Release:        -current as of this morning's sup (17 Aug '95)
	SPARC IPC, but it doesn't matter
	When fsck is constructing its blocks-used map, it assumes the
	global csum info is in its default position, right after the
	inode area in cylinder group 0.  If it's actually elsewhere,
	this leads to DUP reports and/or missing block gripes,
	depending on whether anything else is using those blocks, and
	complaints about the blocks the csum info is actually in.
	Everything else - in fsck, in the kernel, and everywhere else
	I've thought of to look - correctly uses fs_csaddr to locate
	this info.
	The simplest thing to do is to move the csum info, fill up
	every last frag on the filesystem to ensure that something else
	is using the default location's blocks, and then fsck it and
	watch the whining about DUPs.
	Make pass1 DTRT in this respect, of course.  Here's the patch
	I'm using.  This makes it work; however, code inspection makes
	me think fsck is insufficiently paranoid.  For example, if
	fs_cssize is trashed (gets set to 0x666f6f21, say), then fsck
	will go nuts during setup, allocating memory until it runs out
	or until it gets an error reading what it thinks is csum info
	off the disk.  (The code in question can be located by
	searching for "fs_cssize" in setup.c - fsck uncritically
	believes whatever it finds there.)  There are doubtless many
	other pieces of data fsck uncritically believes that it
	shouldn't, but I'm not about to try to find them all now.

*** /sources/latest-usr-src/sbin/fsck/pass1.c	Mon Mar 20 02:29:51 1995
--- /usr/src/sbin/fsck/pass1.c	Thu Aug 17 14:15:57 1995
*** 74,85 ****
  		cgd = cgdmin(&sblock, c);
  		if (c == 0) {
  			i = cgbase(&sblock, c);
- 			cgd += howmany(sblock.fs_cssize, sblock.fs_fsize);
  		} else
  			i = cgsblock(&sblock, c);
  		for (; i < cgd; i++)
  	 * Find all allocated blocks.
--- 74,88 ----
  		cgd = cgdmin(&sblock, c);
  		if (c == 0) {
  			i = cgbase(&sblock, c);
  		} else
  			i = cgsblock(&sblock, c);
  		for (; i < cgd; i++)
+ 	cgd = sblock.fs_csaddr;
+ 	i = howmany(sblock.fs_cssize, sblock.fs_fsize);
+ 	/* should check these numbers for rudimentary sanity */
+ 	for (;i>0;i--,cgd++) setbmap(cgd);
  	 * Find all allocated blocks.

					der Mouse