Add check to avoid raw inode iblocks fields overflow in case of huge_file feature.
Use the Linux logic for now. Reviewed by: pfg (mentor) Approved by: pfg (mentor) MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D12131
This commit is contained in:
parent
0e492f2faa
commit
72530f91cf
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=324064
@ -56,7 +56,6 @@
|
||||
static daddr_t ext2_alloccg(struct inode *, int, daddr_t, int);
|
||||
static daddr_t ext2_clusteralloc(struct inode *, int, daddr_t, int);
|
||||
static u_long ext2_dirpref(struct inode *);
|
||||
static void ext2_fserr(struct m_ext2fs *, uid_t, char *);
|
||||
static u_long ext2_hashalloc(struct inode *, int, long, int,
|
||||
daddr_t (*)(struct inode *, int, daddr_t,
|
||||
int));
|
||||
@ -1303,7 +1302,7 @@ ext2_mapsearch(struct m_ext2fs *fs, char *bbp, daddr_t bpref)
|
||||
* The form of the error message is:
|
||||
* fs: error message
|
||||
*/
|
||||
static void
|
||||
void
|
||||
ext2_fserr(struct m_ext2fs *fs, uid_t uid, char *cp)
|
||||
{
|
||||
|
||||
|
@ -62,9 +62,10 @@ int ext2_bmap(struct vop_bmap_args *);
|
||||
int ext2_bmaparray(struct vnode *, daddr_t, daddr_t *, int *, int *);
|
||||
void ext2_clusteracct(struct m_ext2fs *, char *, int, daddr_t, int);
|
||||
void ext2_dirbad(struct inode *ip, doff_t offset, char *how);
|
||||
void ext2_fserr(struct m_ext2fs *, uid_t, char *);
|
||||
void ext2_ei2i(struct ext2fs_dinode *, struct inode *);
|
||||
int ext2_getlbns(struct vnode *, daddr_t, struct indir *, int *);
|
||||
void ext2_i2ei(struct inode *, struct ext2fs_dinode *);
|
||||
int ext2_i2ei(struct inode *, struct ext2fs_dinode *);
|
||||
void ext2_itimes(struct vnode *vp);
|
||||
int ext2_reallocblks(struct vop_reallocblks_args *);
|
||||
int ext2_reclaim(struct vop_reclaim_args *);
|
||||
|
@ -90,8 +90,12 @@ ext2_update(struct vnode *vp, int waitfor)
|
||||
brelse(bp);
|
||||
return (error);
|
||||
}
|
||||
ext2_i2ei(ip, (struct ext2fs_dinode *)((char *)bp->b_data +
|
||||
error = ext2_i2ei(ip, (struct ext2fs_dinode *)((char *)bp->b_data +
|
||||
EXT2_INODE_SIZE(fs) * ino_to_fsbo(fs, ip->i_number)));
|
||||
if (error) {
|
||||
brelse(bp);
|
||||
return (error);
|
||||
}
|
||||
if (waitfor && !DOINGASYNC(vp))
|
||||
return (bwrite(bp));
|
||||
else {
|
||||
|
@ -136,11 +136,13 @@ ext2_ei2i(struct ext2fs_dinode *ei, struct inode *ip)
|
||||
/*
|
||||
* inode to raw ext2 inode
|
||||
*/
|
||||
void
|
||||
int
|
||||
ext2_i2ei(struct inode *ip, struct ext2fs_dinode *ei)
|
||||
{
|
||||
struct m_ext2fs *fs;
|
||||
int i;
|
||||
|
||||
fs = ip->i_e2fs;
|
||||
ei->e2di_mode = ip->i_mode;
|
||||
ei->e2di_nlink = ip->i_nlink;
|
||||
/*
|
||||
@ -167,8 +169,19 @@ ext2_i2ei(struct inode *ip, struct ext2fs_dinode *ei)
|
||||
ei->e2di_flags |= (ip->i_flags & UF_NODUMP) ? EXT2_NODUMP : 0;
|
||||
ei->e2di_flags |= (ip->i_flag & IN_E3INDEX) ? EXT3_INDEX : 0;
|
||||
ei->e2di_flags |= (ip->i_flag & IN_E4EXTENTS) ? EXT4_EXTENTS : 0;
|
||||
ei->e2di_nblock = ip->i_blocks & 0xffffffff;
|
||||
ei->e2di_nblock_high = ip->i_blocks >> 32 & 0xffff;
|
||||
if (ip->i_blocks > ~0U &&
|
||||
!EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_HUGE_FILE)) {
|
||||
ext2_fserr(fs, ip->i_uid, "i_blocks value is out of range");
|
||||
return (EIO);
|
||||
}
|
||||
if (ip->i_blocks <= 0xffffffffffffULL) {
|
||||
ei->e2di_nblock = ip->i_blocks & 0xffffffff;
|
||||
ei->e2di_nblock_high = ip->i_blocks >> 32 & 0xffff;
|
||||
} else {
|
||||
ei->e2di_flags |= EXT4_HUGE_FILE;
|
||||
ei->e2di_nblock = dbtofsb(fs, ip->i_blocks);
|
||||
ei->e2di_nblock_high = dbtofsb(fs, ip->i_blocks) >> 32 & 0xffff;
|
||||
}
|
||||
ei->e2di_facl = ip->i_facl & 0xffffffff;
|
||||
ei->e2di_facl_high = ip->i_facl >> 32 & 0xffff;
|
||||
ei->e2di_gen = ip->i_gen;
|
||||
@ -181,4 +194,6 @@ ext2_i2ei(struct inode *ip, struct ext2fs_dinode *ei)
|
||||
ei->e2di_blocks[i] = ip->i_db[i];
|
||||
for (i = 0; i < EXT2_NIADDR; i++)
|
||||
ei->e2di_blocks[EXT2_NDIR_BLOCKS + i] = ip->i_ib[i];
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user