use proper on-disk inode size: no more, no less.
authorpelikan <pelikan@openbsd.org>
Thu, 31 Jul 2014 17:37:52 +0000 (17:37 +0000)
committerpelikan <pelikan@openbsd.org>
Thu, 31 Jul 2014 17:37:52 +0000 (17:37 +0000)
Reported by Roman Yakovlev, thanks!

"do it now" deraadt

sys/ufs/ext2fs/ext2fs_bswap.c
sys/ufs/ext2fs/ext2fs_dinode.h
sys/ufs/ext2fs/ext2fs_inode.c
sys/ufs/ext2fs/ext2fs_vfsops.c

index 720310c..c4f36ba 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ext2fs_bswap.c,v 1.7 2014/07/14 08:54:13 pelikan Exp $        */
+/*     $OpenBSD: ext2fs_bswap.c,v 1.8 2014/07/31 17:37:52 pelikan Exp $        */
 /*     $NetBSD: ext2fs_bswap.c,v 1.6 2000/07/24 00:23:10 mycroft Exp $ */
 
 /*
@@ -110,7 +110,8 @@ e2fs_cg_bswap(struct ext2_gd *old, struct ext2_gd *new, int size)
 }
 
 void
-e2fs_i_bswap(struct ext2fs_dinode *old, struct ext2fs_dinode *new)
+e2fs_i_bswap(struct m_ext2fs *fs, struct ext2fs_dinode *old,
+    struct ext2fs_dinode *new)
 {
        new->e2di_mode          =       swap16(old->e2di_mode);
        new->e2di_uid_low       =       swap16(old->e2di_uid_low);
@@ -133,5 +134,9 @@ e2fs_i_bswap(struct ext2fs_dinode *old, struct ext2fs_dinode *new)
        new->e2di_facl_hi       =       swap16(old->e2di_facl_hi);
        memcpy(&new->e2di_blocks[0], &old->e2di_blocks[0],
                (NDADDR+NIADDR) * sizeof(int));
+
+       if (EXT2_DINODE_SIZE(fs) <= EXT2_REV0_DINODE_SIZE)
+               return;
+       new->e2di_isize         =       swap16(old->e2di_isize);
 }
 #endif
index 456e695..4357be5 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ext2fs_dinode.h,v 1.16 2014/07/11 12:53:19 pelikan Exp $      */
+/*     $OpenBSD: ext2fs_dinode.h,v 1.17 2014/07/31 17:37:52 pelikan Exp $      */
 /*     $NetBSD: ext2fs_dinode.h,v 1.6 2000/01/26 16:21:33 bouyer Exp $ */
 
 /*
@@ -154,10 +154,13 @@ struct ext2fs_dinode {
 
 /* e2fs needs byte swapping on big-endian systems */
 #if BYTE_ORDER == LITTLE_ENDIAN
-#      define e2fs_iload(old, new) memcpy((new),(old),sizeof(struct ext2fs_dinode))
-#      define e2fs_isave(old, new) memcpy((new),(old),sizeof(struct ext2fs_dinode))
+#      define e2fs_iload(fs, old, new) \
+               memcpy((new),(old), MIN(EXT2_DINODE_SIZE(fs), sizeof(*new)))
+#      define e2fs_isave(fs, old, new) \
+               memcpy((new),(old), MIN(EXT2_DINODE_SIZE(fs), sizeof(*new)))
 #else
-void e2fs_i_bswap(struct ext2fs_dinode *, struct ext2fs_dinode *);
-#      define e2fs_iload(old, new) e2fs_i_bswap((old), (new))
-#      define e2fs_isave(old, new) e2fs_i_bswap((old), (new))
+struct m_ext2fs;
+void e2fs_i_bswap(struct m_ext2fs *, struct ext2fs_dinode *, struct ext2fs_dinode *);
+#      define e2fs_iload(fs, old, new) e2fs_i_bswap((fs), (old), (new))
+#      define e2fs_isave(fs, old, new) e2fs_i_bswap((fs), (old), (new))
 #endif
index 6f88349..41d72bc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ext2fs_inode.c,v 1.54 2014/07/13 16:59:35 pelikan Exp $       */
+/*     $OpenBSD: ext2fs_inode.c,v 1.55 2014/07/31 17:37:52 pelikan Exp $       */
 /*     $NetBSD: ext2fs_inode.c,v 1.24 2001/06/19 12:59:18 wiz Exp $    */
 
 /*
@@ -189,7 +189,7 @@ ext2fs_update(struct inode *ip, int waitfor)
        ip->i_e2fs_uid_high = ip->i_e2fs_uid >> 16;
        ip->i_e2fs_gid_high = ip->i_e2fs_gid >> 16;
 
-       e2fs_isave(ip->i_e2din, (struct ext2fs_dinode *)cp);
+       e2fs_isave(fs, ip->i_e2din, (struct ext2fs_dinode *)cp);
        if (waitfor)
                return (bwrite(bp));
        else {
index 5db4395..e4f54fb 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ext2fs_vfsops.c,v 1.81 2014/07/13 15:07:01 pelikan Exp $      */
+/*     $OpenBSD: ext2fs_vfsops.c,v 1.82 2014/07/31 17:37:52 pelikan Exp $      */
 /*     $NetBSD: ext2fs_vfsops.c,v 1.1 1997/06/11 09:34:07 bouyer Exp $ */
 
 /*
@@ -365,7 +365,7 @@ ext2fs_reload_vnode(struct vnode *vp, void *args)
        }
        cp = (caddr_t)bp->b_data +
            (ino_to_fsbo(era->fs, ip->i_number) * EXT2_DINODE_SIZE(era->fs));
-       e2fs_iload((struct ext2fs_dinode *)cp, ip->i_e2din);
+       e2fs_iload(era->fs, (struct ext2fs_dinode *)cp, ip->i_e2din);
        brelse(bp);
        vput(vp);
        return (0);
@@ -891,7 +891,7 @@ ext2fs_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
            + EXT2_DINODE_SIZE(fs) * ino_to_fsbo(fs, ino));
 
        ip->i_e2din = pool_get(&ext2fs_dinode_pool, PR_WAITOK);
-       e2fs_iload(dp, ip->i_e2din);
+       e2fs_iload(fs, dp, ip->i_e2din);
        brelse(bp);
 
        ip->i_effnlink = ip->i_e2fs_nlink;