mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-03 23:28:58 +00:00
Fix a bug in fsck_ffs(8) triggered by corrupted filesystems.
Reported-by: Robert Morris
PR: 271378
Sponsored-by: The FreeBSD Foundation
(cherry picked from commit 101a9ac071
)
This commit is contained in:
parent
fbfbd0638a
commit
3035f98d56
|
@ -471,6 +471,7 @@ void check_blkcnt(struct inode *ip);
|
|||
int check_cgmagic(int cg, struct bufarea *cgbp);
|
||||
void rebuild_cg(int cg, struct bufarea *cgbp);
|
||||
void check_dirdepth(struct inoinfo *inp);
|
||||
int chkfilesize(mode_t mode, u_int64_t filesize);
|
||||
int chkrange(ufs2_daddr_t blk, int cnt);
|
||||
void ckfini(int markclean);
|
||||
int ckinode(union dinode *dp, struct inodesc *);
|
||||
|
|
|
@ -1206,6 +1206,31 @@ std_checkblkavail(ufs2_daddr_t blkno, long frags)
|
|||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether a file size is within the limits for the filesystem.
|
||||
* Return 1 when valid and 0 when too big.
|
||||
*
|
||||
* This should match the file size limit in ffs_mountfs().
|
||||
*/
|
||||
int
|
||||
chkfilesize(mode_t mode, u_int64_t filesize)
|
||||
{
|
||||
u_int64_t kernmaxfilesize;
|
||||
|
||||
if (sblock.fs_magic == FS_UFS1_MAGIC)
|
||||
kernmaxfilesize = (off_t)0x40000000 * sblock.fs_bsize - 1;
|
||||
else
|
||||
kernmaxfilesize = sblock.fs_maxfilesize;
|
||||
if (filesize > kernmaxfilesize ||
|
||||
filesize > sblock.fs_maxfilesize ||
|
||||
(mode == IFDIR && filesize > MAXDIRSIZE)) {
|
||||
if (debug)
|
||||
printf("bad file size %ju:", (uintmax_t)filesize);
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Slow down IO so as to leave some disk bandwidth for other processes
|
||||
*/
|
||||
|
|
|
@ -256,7 +256,6 @@ checkinode(ino_t inumber, struct inodesc *idesc, int rebuiltcg)
|
|||
{
|
||||
struct inode ip;
|
||||
union dinode *dp;
|
||||
off_t kernmaxfilesize;
|
||||
ufs2_daddr_t ndb;
|
||||
mode_t mode;
|
||||
intmax_t size, fixsize;
|
||||
|
@ -293,16 +292,7 @@ checkinode(ino_t inumber, struct inodesc *idesc, int rebuiltcg)
|
|||
return (1);
|
||||
}
|
||||
lastino = inumber;
|
||||
/* This should match the file size limit in ffs_mountfs(). */
|
||||
if (sblock.fs_magic == FS_UFS1_MAGIC)
|
||||
kernmaxfilesize = (off_t)0x40000000 * sblock.fs_bsize - 1;
|
||||
else
|
||||
kernmaxfilesize = sblock.fs_maxfilesize;
|
||||
if (DIP(dp, di_size) > kernmaxfilesize ||
|
||||
DIP(dp, di_size) > sblock.fs_maxfilesize ||
|
||||
(mode == IFDIR && DIP(dp, di_size) > MAXDIRSIZE)) {
|
||||
if (debug)
|
||||
printf("bad size %ju:", (uintmax_t)DIP(dp, di_size));
|
||||
if (chkfilesize(mode, DIP(dp, di_size)) == 0) {
|
||||
pfatal("BAD FILE SIZE");
|
||||
goto unknown;
|
||||
}
|
||||
|
|
|
@ -1963,6 +1963,9 @@ ino_build_trunc(struct jtrncrec *rec)
|
|||
printf("ino_build_trunc: op %d ino %ju, size %jd\n",
|
||||
rec->jt_op, (uintmax_t)rec->jt_ino,
|
||||
(uintmax_t)rec->jt_size);
|
||||
if (chkfilesize(IFREG, rec->jt_size) == 0)
|
||||
err_suj("ino_build: truncation size too large %ju\n",
|
||||
(intmax_t)rec->jt_size);
|
||||
sino = ino_lookup(rec->jt_ino, 1);
|
||||
if (rec->jt_op == JOP_SYNC) {
|
||||
sino->si_trunc = NULL;
|
||||
|
|
Loading…
Reference in a new issue