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
This commit is contained in:
parent
d13241e146
commit
16241a05dd
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=71884
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user