]> granicus.if.org Git - zfs/commitdiff
Fix integer overflow of ZTOI(zp)->i_generation
authorTom Caputi <tcaputi@datto.com>
Thu, 6 Jun 2019 19:59:39 +0000 (15:59 -0400)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 7 Jun 2019 19:45:40 +0000 (12:45 -0700)
The ZFS on-disk format stores each inode's generation ID as a 64
bit number on disk and in-core. However, the Linux kernel's inode
is only a 32 bit number. In most places, the code handles this
correctly, but the cast is missing in zfs_rezget(). For many pools,
this isn't an issue since the generation ID is computed as the
current txg when the inode is created and many pools don't have
more than 2^32 txgs.

For the pools that have more txgs, this issue causes any inode with
a high enough generation number to report IO errors after a call to
"zfs rollback" while holding the file or directory open. This patch
simply adds the missing cast.

Reviewed-by: Alek Pinchuk <apinchuk@datto.com>
Reviewed-by: George Melikov <mail@gmelikov.ru>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tom Caputi <tcaputi@datto.com>
Closes #8858

module/zfs/zfs_znode.c

index 77eb8bb9126fbb40150c85f7bb85a559f6989a02..d5ed4af7029d09e0733ac395b8753051c15fc50b 100644 (file)
@@ -1255,7 +1255,7 @@ zfs_rezget(znode_t *zp)
        ZFS_TIME_DECODE(&ZTOI(zp)->i_mtime, mtime);
        ZFS_TIME_DECODE(&ZTOI(zp)->i_ctime, ctime);
 
-       if (gen != ZTOI(zp)->i_generation) {
+       if ((uint32_t)gen != ZTOI(zp)->i_generation) {
                zfs_znode_dmu_fini(zp);
                zfs_znode_hold_exit(zfsvfs, zh);
                return (SET_ERROR(EIO));