Author: fsu Date: Sun Oct 15 14:03:53 2017 New Revision: 324627 URL: https://svnweb.freebsd.org/changeset/base/324627
Log: MFC r324064: Add check to avoid raw inode iblocks fields overflow in case of huge_file feature. Use the Linux logic for now. Approved by: pfg (mentor) Differential Revision: https://reviews.freebsd.org/D12131 Modified: stable/11/sys/fs/ext2fs/ext2_alloc.c stable/11/sys/fs/ext2fs/ext2_extern.h stable/11/sys/fs/ext2fs/ext2_inode.c stable/11/sys/fs/ext2fs/ext2_inode_cnv.c Modified: stable/11/sys/fs/ext2fs/ext2_alloc.c ============================================================================== --- stable/11/sys/fs/ext2fs/ext2_alloc.c Sun Oct 15 11:46:11 2017 (r324626) +++ stable/11/sys/fs/ext2fs/ext2_alloc.c Sun Oct 15 14:03:53 2017 (r324627) @@ -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 * The form of the error message is: * fs: error message */ -static void +void ext2_fserr(struct m_ext2fs *fs, uid_t uid, char *cp) { Modified: stable/11/sys/fs/ext2fs/ext2_extern.h ============================================================================== --- stable/11/sys/fs/ext2fs/ext2_extern.h Sun Oct 15 11:46:11 2017 (r324626) +++ stable/11/sys/fs/ext2fs/ext2_extern.h Sun Oct 15 14:03:53 2017 (r324627) @@ -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 *); Modified: stable/11/sys/fs/ext2fs/ext2_inode.c ============================================================================== --- stable/11/sys/fs/ext2fs/ext2_inode.c Sun Oct 15 11:46:11 2017 (r324626) +++ stable/11/sys/fs/ext2fs/ext2_inode.c Sun Oct 15 14:03:53 2017 (r324627) @@ -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 { Modified: stable/11/sys/fs/ext2fs/ext2_inode_cnv.c ============================================================================== --- stable/11/sys/fs/ext2fs/ext2_inode_cnv.c Sun Oct 15 11:46:11 2017 (r324626) +++ stable/11/sys/fs/ext2fs/ext2_inode_cnv.c Sun Oct 15 14:03:53 2017 (r324627) @@ -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 < NIADDR; i++) ei->e2di_blocks[EXT2_NDIR_BLOCKS + i] = ip->i_ib[i]; + + return (0); } _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"