linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andries.Brouwer@cwi.nl
To: Andries.Brouwer@cwi.nl, torvalds@transmeta.com
Cc: alan@lxorguk.ukuu.org.uk, hch@caldera.de,
	linux-kernel@vger.kernel.org, viro@math.psu.edu
Subject: Re: [PATCH] vxfs fix
Date: Thu, 2 Aug 2001 19:15:31 GMT	[thread overview]
Message-ID: <200108021915.TAA114350@vlet.cwi.nl> (raw)

	From: Linus Torvalds <torvalds@transmeta.com>

	On Wed, 1 Aug 2001 Andries.Brouwer@cwi.nl wrote:
	>
	> When mount continues to try all types, it may try V7.
	> That always succeeds, there is no test for magic or so,
	> and after garbage has been mounted as a V7 filesystem,
	> the kernel crashes or hangs or fails in other sad ways.

	Even on filesystems that have bad (limited or non-existent)
	magic numbers, 	the read_super() function should really be able
	to do a fair amount of sanity-checking. If nothing else,
	then things like verifying that the root inode really is
	a directory with a proper size, for example.

Added.

	From: Christoph Hellwig

	I'd like to propose:
	s_nfree <= V7_NICFREE, s_ninode <= V7_NICINOD, s_time != 0

Added.

	From: Al Viro

	It shouldn't crash the box, though - I'll look into that.

Good!

	From: Alan

	Alternatively pass a flag to the mount command saying
	"this is a guesswork special" then V7 fs can just return 'not me'

Parse failure.

Below a patch.

Andries


diff -r -u ../linux-2.4.7/linux/fs/sysv/super.c linux/fs/sysv/super.c
--- ../linux-2.4.7/linux/fs/sysv/super.c	Sat Jul 28 17:08:46 2001
+++ linux/fs/sysv/super.c	Thu Aug  2 19:47:58 2001
@@ -197,6 +197,8 @@
 		sb->sv_bytesex = BYTESEX_BE;
 	else
 		return 0;
+
+	/* BUG? no endian conversion on s_time? */
 	if (sbd->s_time < JAN_1_1980) {
 		/* this is likely to happen on SystemV2 FS */
 		if (sbd->s_type > 3 || sbd->s_type < 1)
@@ -294,7 +296,8 @@
 	sb->sv_toobig_block = 10 + bsize_4 * (1 + bsize_4 * (1 + bsize_4));
 	sb->sv_ind_per_block_bits = n_bits-2;
 
-	sb->sv_ninodes = (sb->sv_firstdatazone - sb->sv_firstinodezone) << sb->sv_inodes_per_block_bits;
+	sb->sv_ninodes = (sb->sv_firstdatazone - sb->sv_firstinodezone)
+		<< sb->sv_inodes_per_block_bits;
 
 	sb->s_blocksize = bsize;
 	sb->s_blocksize_bits = n_bits;
@@ -346,13 +349,10 @@
 	sb->sv_block_base = 0;
 
 	for (i = 0; i < sizeof(flavours)/sizeof(flavours[0]) && !size; i++) {
-		struct buffer_head *next_bh;
-		next_bh = bread(dev, flavours[i].block, BLOCK_SIZE);
-		if (!next_bh)
-			continue;
 		brelse(bh);
-		bh = next_bh;
-
+		bh = bread(dev, flavours[i].block, BLOCK_SIZE);
+		if (!bh)
+			continue;
 		size = flavours[i].test(sb, bh);
 	}
 
@@ -411,8 +411,10 @@
 static struct super_block *v7_read_super(struct super_block *sb,void *data,
 				  int silent)
 {
-	struct buffer_head *bh;
+	struct buffer_head *bh, *bh2 = NULL;
 	kdev_t dev = sb->s_dev;
+	struct v7_super_block *v7sb;
+	struct sysv_inode *v7i;
 
 	if (440 != sizeof (struct v7_super_block))
 		panic("V7 FS: bad super-block size");
@@ -422,23 +424,41 @@
 	sb->sv_type = FSTYPE_V7;
 	sb->sv_bytesex = BYTESEX_PDP;
 
-	set_blocksize(dev,512);
+	set_blocksize(dev, 512);
 
 	if ((bh = bread(dev, 1, 512)) == NULL) {
 		if (!silent)
-			printk("VFS: unable to read V7 FS superblock on device "
-			       "%s.\n", bdevname(dev));
+			printk("VFS: unable to read V7 FS superblock on "
+			       "device %s.\n", bdevname(dev));
 		goto failed;
 	}
 
+	/* plausibility check on superblock */
+	v7sb = (struct v7_super_block *) bh->b_data;
+	if (fs16_to_cpu(sb,v7sb->s_nfree) > V7_NICFREE ||
+	    fs16_to_cpu(sb,v7sb->s_ninode) > V7_NICINOD ||
+	    fs32_to_cpu(sb,v7sb->s_time) == 0)
+		goto failed;
+
+	/* plausibility check on root inode: it is a directory,
+	   with a nonzero size that is a multiple of 16 */
+	if ((bh2 = bread(dev, 2, 512)) == NULL)
+		goto failed;
+	v7i = (struct sysv_inode *)(bh2->b_data + 64);
+	if ((fs16_to_cpu(sb,v7i->i_mode) & ~0777) != S_IFDIR ||
+	    (fs32_to_cpu(sb,v7i->i_size) == 0) ||
+	    (fs32_to_cpu(sb,v7i->i_size) & 017) != 0)
+		goto failed;
+	brelse(bh2);
 
 	sb->sv_bh1 = bh;
 	sb->sv_bh2 = bh;
 	if (complete_read_super(sb, silent, 1))
 		return sb;
 
-	brelse(bh);
 failed:
+	brelse(bh2);
+	brelse(bh);
 	return NULL;
 }
 

             reply	other threads:[~2001-08-02 19:16 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-08-02 19:15 Andries.Brouwer [this message]
  -- strict thread matches above, loose matches on Subject: below --
2001-08-02 20:25 [PATCH] vxfs fix Andries.Brouwer
     [not found] <no.id>
2001-08-02 19:41 ` Alan Cox
2001-08-02 20:57   ` Andreas Dilger
2001-08-01 21:03 Andries.Brouwer
2001-08-01 21:18 ` Christoph Hellwig
2001-08-01 21:19 ` Alexander Viro
2001-08-01 22:29 ` Linus Torvalds
2001-08-02  0:15   ` Alan Cox

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200108021915.TAA114350@vlet.cwi.nl \
    --to=andries.brouwer@cwi.nl \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=hch@caldera.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@transmeta.com \
    --cc=viro@math.psu.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).