summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoriedowse <iedowse@FreeBSD.org>2001-01-31 15:16:56 +0000
committeriedowse <iedowse@FreeBSD.org>2001-01-31 15:16:56 +0000
commit1904591561496046db76a7fed4aeeca690042d13 (patch)
treeef636c0a52aac6793f045981adae1fe0bf96d9d8
parente8881fd42645233f9fbaa07357fcab52f7af647d (diff)
downloadFreeBSD-src-1904591561496046db76a7fed4aeeca690042d13.zip
FreeBSD-src-1904591561496046db76a7fed4aeeca690042d13.tar.gz
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
-rw-r--r--sbin/fsck_ffs/pass1.c9
-rw-r--r--sbin/fsck_ffs/setup.c2
2 files changed, 8 insertions, 3 deletions
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;
}
/*
OpenPOWER on IntegriCloud