Remove ufs fragments logic.

The ext2fs fragments are different from ufs fragments.
In case of ext2fs the fragment should be equal or more then block size.
The values more than block size are used only in case of bigalloc feature, which is does not supported for now.

Reported by:    Christopher Krah, Thomas Barabosch, and Jan-Niclas Hilgert of Fraunhofer FKIE
Reported as:    FS-22-EXT2-9: Denial of service in ftruncate-0 (ext2_balloc)

MFC after:	2 weeks
This commit is contained in:
Fedor Uporov 2019-07-07 08:56:13 +00:00
parent 590517d05a
commit c008656263

View File

@ -62,7 +62,7 @@ ext2_ext_balloc(struct inode *ip, uint32_t lbn, int size,
struct buf *bp = NULL;
struct vnode *vp = ITOV(ip);
daddr_t newblk;
int osize, nsize, blks, error, allocated;
int blks, error, allocated;
fs = ip->i_e2fs;
blks = howmany(size, fs->e2fs_bsize);
@ -72,47 +72,22 @@ ext2_ext_balloc(struct inode *ip, uint32_t lbn, int size,
return (error);
if (allocated) {
if (ip->i_size < (lbn + 1) * fs->e2fs_bsize)
nsize = fragroundup(fs, size);
else
nsize = fs->e2fs_bsize;
bp = getblk(vp, lbn, nsize, 0, 0, 0);
bp = getblk(vp, lbn, fs->e2fs_bsize, 0, 0, 0);
if(!bp)
return (EIO);
bp->b_blkno = fsbtodb(fs, newblk);
if (flags & BA_CLRBUF)
vfs_bio_clrbuf(bp);
} else {
if (ip->i_size >= (lbn + 1) * fs->e2fs_bsize) {
error = bread(vp, lbn, fs->e2fs_bsize, NOCRED, &bp);
if (error) {
brelse(bp);
return (error);
}
bp->b_blkno = fsbtodb(fs, newblk);
*bpp = bp;
return (0);
}
/*
* Consider need to reallocate a fragment.
*/
osize = fragroundup(fs, blkoff(fs, ip->i_size));
nsize = fragroundup(fs, size);
if (nsize <= osize)
error = bread(vp, lbn, osize, NOCRED, &bp);
else
error = bread(vp, lbn, fs->e2fs_bsize, NOCRED, &bp);
error = bread(vp, lbn, fs->e2fs_bsize, NOCRED, &bp);
if (error) {
brelse(bp);
return (error);
}
bp->b_blkno = fsbtodb(fs, newblk);
}
bp->b_blkno = fsbtodb(fs, newblk);
if (flags & BA_CLRBUF)
vfs_bio_clrbuf(bp);
*bpp = bp;
return (error);
@ -134,7 +109,7 @@ ext2_balloc(struct inode *ip, e2fs_lbn_t lbn, int size, struct ucred *cred,
struct indir indirs[EXT2_NIADDR + 2];
e4fs_daddr_t nb, newb;
e2fs_daddr_t *bap, pref;
int osize, nsize, num, i, error;
int num, i, error;
*bpp = NULL;
if (lbn < 0)
@ -164,53 +139,22 @@ ext2_balloc(struct inode *ip, e2fs_lbn_t lbn, int size, struct ucred *cred,
* no new block is to be allocated, and no need to expand
* the file
*/
if (nb != 0 && ip->i_size >= (lbn + 1) * fs->e2fs_bsize) {
if (nb != 0) {
error = bread(vp, lbn, fs->e2fs_bsize, NOCRED, &bp);
if (error) {
brelse(bp);
return (error);
}
bp->b_blkno = fsbtodb(fs, nb);
*bpp = bp;
return (0);
}
if (nb != 0) {
/*
* Consider need to reallocate a fragment.
*/
osize = fragroundup(fs, blkoff(fs, ip->i_size));
nsize = fragroundup(fs, size);
if (nsize <= osize) {
error = bread(vp, lbn, osize, NOCRED, &bp);
if (error) {
brelse(bp);
return (error);
}
bp->b_blkno = fsbtodb(fs, nb);
} else {
/*
* Godmar thinks: this shouldn't happen w/o
* fragments
*/
printf("nsize %d(%d) > osize %d(%d) nb %d\n",
(int)nsize, (int)size, (int)osize,
(int)ip->i_size, (int)nb);
panic(
"ext2_balloc: Something is terribly wrong");
/*
* please note there haven't been any changes from here on -
* FFS seems to work.
*/
if (ip->i_size >= (lbn + 1) * fs->e2fs_bsize) {
*bpp = bp;
return (0);
}
} else {
if (ip->i_size < (lbn + 1) * fs->e2fs_bsize)
nsize = fragroundup(fs, size);
else
nsize = fs->e2fs_bsize;
EXT2_LOCK(ump);
error = ext2_alloc(ip, lbn,
ext2_blkpref(ip, lbn, (int)lbn, &ip->i_db[0], 0),
nsize, cred, &newb);
fs->e2fs_bsize, cred, &newb);
if (error)
return (error);
/*
@ -219,7 +163,7 @@ ext2_balloc(struct inode *ip, e2fs_lbn_t lbn, int size, struct ucred *cred,
*/
if (newb > UINT_MAX)
return (EFBIG);
bp = getblk(vp, lbn, nsize, 0, 0, 0);
bp = getblk(vp, lbn, fs->e2fs_bsize, 0, 0, 0);
bp->b_blkno = fsbtodb(fs, newb);
if (flags & BA_CLRBUF)
vfs_bio_clrbuf(bp);