svn commit: r324064 - head/sys/fs/ext2fs

Fedor Uporov fsu at FreeBSD.org
Wed Sep 27 16:12:15 UTC 2017


Author: fsu
Date: Wed Sep 27 16:12:13 2017
New Revision: 324064
URL: https://svnweb.freebsd.org/changeset/base/324064

Log:
  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

Modified:
  head/sys/fs/ext2fs/ext2_alloc.c
  head/sys/fs/ext2fs/ext2_extern.h
  head/sys/fs/ext2fs/ext2_inode.c
  head/sys/fs/ext2fs/ext2_inode_cnv.c

Modified: head/sys/fs/ext2fs/ext2_alloc.c
==============================================================================
--- head/sys/fs/ext2fs/ext2_alloc.c	Wed Sep 27 15:29:17 2017	(r324063)
+++ head/sys/fs/ext2fs/ext2_alloc.c	Wed Sep 27 16:12:13 2017	(r324064)
@@ -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: head/sys/fs/ext2fs/ext2_extern.h
==============================================================================
--- head/sys/fs/ext2fs/ext2_extern.h	Wed Sep 27 15:29:17 2017	(r324063)
+++ head/sys/fs/ext2fs/ext2_extern.h	Wed Sep 27 16:12:13 2017	(r324064)
@@ -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: head/sys/fs/ext2fs/ext2_inode.c
==============================================================================
--- head/sys/fs/ext2fs/ext2_inode.c	Wed Sep 27 15:29:17 2017	(r324063)
+++ head/sys/fs/ext2fs/ext2_inode.c	Wed Sep 27 16:12:13 2017	(r324064)
@@ -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: head/sys/fs/ext2fs/ext2_inode_cnv.c
==============================================================================
--- head/sys/fs/ext2fs/ext2_inode_cnv.c	Wed Sep 27 15:29:17 2017	(r324063)
+++ head/sys/fs/ext2fs/ext2_inode_cnv.c	Wed Sep 27 16:12:13 2017	(r324064)
@@ -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);
 }


More information about the svn-src-head mailing list