From 1904591561496046db76a7fed4aeeca690042d13 Mon Sep 17 00:00:00 2001 From: iedowse Date: Wed, 31 Jan 2001 15:16:56 +0000 Subject: Fsck_ffs did not properly range-check the inode 'di_size' field, so it was possible for a filesystem marked clean by fsck_ffs to cause kernel crashes later when mounted. This could occur when fsck_ffs was used to repair a badly corrupted filesystem. As pointed out by bde, it is not sufficient to restrict di_size to just the superblock fs_maxfilesize limit. The use of 32-bit logical block numbers (both in fsck and the kernel) induces another file size limit which is usually lower than fs_maxfilesize. Also, the old 4.3BSD filesystem does not have fs_maxfilesize initialised. Following this change, fsck_ffs will enforce exactly the same file size limits as are used by the kernel. PR: kern/15065 Discussed with: bde Reviewed by: bde, mckusick --- sbin/fsck_ffs/pass1.c | 9 ++++++--- sbin/fsck_ffs/setup.c | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'sbin/fsck_ffs') diff --git a/sbin/fsck_ffs/pass1.c b/sbin/fsck_ffs/pass1.c index e6bd215..2772ec1 100644 --- a/sbin/fsck_ffs/pass1.c +++ b/sbin/fsck_ffs/pass1.c @@ -183,7 +183,8 @@ checkinode(inumber, idesc) { register struct dinode *dp; struct zlncnt *zlnp; - int ndb, j; + u_int64_t kernmaxfilesize; + ufs_daddr_t ndb, j; mode_t mode; char *symbuf; @@ -206,8 +207,10 @@ checkinode(inumber, idesc) return; } lastino = inumber; - if (/* dp->di_size < 0 || */ - dp->di_size + sblock.fs_bsize - 1 < dp->di_size || + /* This should match the file size limit in ffs_mountfs(). */ + kernmaxfilesize = (u_int64_t)0x40000000 * sblock.fs_bsize - 1; + if (dp->di_size > kernmaxfilesize || + dp->di_size > sblock.fs_maxfilesize || (mode == IFDIR && dp->di_size > MAXDIRSIZE)) { if (debug) printf("bad size %qu:", dp->di_size); diff --git a/sbin/fsck_ffs/setup.c b/sbin/fsck_ffs/setup.c index 0c2e8ac..24000be 100644 --- a/sbin/fsck_ffs/setup.c +++ b/sbin/fsck_ffs/setup.c @@ -205,6 +205,8 @@ setup(dev) } else { sblock.fs_qbmask = ~sblock.fs_bmask; sblock.fs_qfmask = ~sblock.fs_fmask; + /* This should match the kernel limit in ffs_oldfscompat(). */ + sblock.fs_maxfilesize = (u_int64_t)1 << 39; newinofmt = 0; } /* -- cgit v1.1