Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 18 Aug 2022 01:46:42 GMT
From:      Jessica Clarke <jrtc27@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: b0ce7dfc5e28 - main - makefs: Fix 32-bit issues in ZFS time attributes setting
Message-ID:  <202208180146.27I1kg5P095015@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by jrtc27:

URL: https://cgit.FreeBSD.org/src/commit/?id=b0ce7dfc5e28650980d52f45aadd79e10012c291

commit b0ce7dfc5e28650980d52f45aadd79e10012c291
Author:     Jessica Clarke <jrtc27@FreeBSD.org>
AuthorDate: 2022-08-18 01:46:27 +0000
Commit:     Jessica Clarke <jrtc27@FreeBSD.org>
CommitDate: 2022-08-18 01:46:27 +0000

    makefs: Fix 32-bit issues in ZFS time attributes setting
    
    Currently the code copies a struct timespec's raw bits as a pair of
    uint64_t. On 64-bit systems this has the same representation, but on
    32-bit issues there are two issues:
    
    1. tv_sec is a time_t which is 32-bit on i386 specifically
    2. tv_nsec is a long not a 64-bit integer
    
    On i386, this means the assertion should fire as the size doesn't match.
    On other 32-bit systems there are 4 bytes of padding after tv_nsec,
    which in practice are probably 0, as this data is ultimately coming from
    the kernel, so it's deterministic (though the padding bytes are not
    required to be preserved by the compiler, so are strictly unspecified).
    However, on 32-bit big-endian systems, the padding bytes are in the
    wrong half to be harmless, resulting in the nanoseconds being multiplied
    by 2^32.
    
    Fix this all by marshalling via a real uint64_t pair like is done by the
    real ZFS_TIME_ENCODE.
    
    Reviewed by:    markj
    Fixes:          240afd8c1fcc ("makefs: Add ZFS support")
    Differential Revision:  https://reviews.freebsd.org/D36131
---
 usr.sbin/makefs/zfs/fs.c | 27 +++++++++++++++++++--------
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/usr.sbin/makefs/zfs/fs.c b/usr.sbin/makefs/zfs/fs.c
index b246a8e23f4e..bf8d5483d610 100644
--- a/usr.sbin/makefs/zfs/fs.c
+++ b/usr.sbin/makefs/zfs/fs.c
@@ -301,6 +301,21 @@ fs_readlink(const fsnode *cur, struct fs_populate_arg *arg,
 	buf[n] = '\0';
 }
 
+static void
+fs_populate_time(zfs_fs_t *fs, char *attrbuf, struct timespec *ts,
+    uint16_t ind, size_t *szp)
+{
+	uint64_t timebuf[2];
+
+	assert(ind < fs->sacnt);
+	assert(fs->saoffs[ind] != 0xffff);
+	assert(fs->satab[ind].size == sizeof(timebuf));
+
+	timebuf[0] = ts->tv_sec;
+	timebuf[1] = ts->tv_nsec;
+	fs_populate_attr(fs, attrbuf, timebuf, ind, szp);
+}
+
 static void
 fs_populate_sattrs(struct fs_populate_arg *arg, const fsnode *cur,
     dnode_phys_t *dnode)
@@ -438,14 +453,10 @@ fs_populate_sattrs(struct fs_populate_arg *arg, const fsnode *cur,
 	 * We deliberately set atime = mtime here to ensure that images are
 	 * reproducible.
 	 */
-	assert(sizeof(sb->st_mtim) == fs->satab[ZPL_ATIME].size);
-	fs_populate_attr(fs, attrbuf, &sb->st_mtim, ZPL_ATIME, &bonussz);
-	assert(sizeof(sb->st_ctim) == fs->satab[ZPL_CTIME].size);
-	fs_populate_attr(fs, attrbuf, &sb->st_ctim, ZPL_CTIME, &bonussz);
-	assert(sizeof(sb->st_mtim) == fs->satab[ZPL_MTIME].size);
-	fs_populate_attr(fs, attrbuf, &sb->st_mtim, ZPL_MTIME, &bonussz);
-	assert(sizeof(sb->st_birthtim) == fs->satab[ZPL_CRTIME].size);
-	fs_populate_attr(fs, attrbuf, &sb->st_birthtim, ZPL_CRTIME, &bonussz);
+	fs_populate_time(fs, attrbuf, &sb->st_mtim, ZPL_ATIME, &bonussz);
+	fs_populate_time(fs, attrbuf, &sb->st_ctim, ZPL_CTIME, &bonussz);
+	fs_populate_time(fs, attrbuf, &sb->st_mtim, ZPL_MTIME, &bonussz);
+	fs_populate_time(fs, attrbuf, &sb->st_birthtim, ZPL_CRTIME, &bonussz);
 
 	fs_populate_varszattr(fs, attrbuf, aces, sizeof(aces), 0,
 	    ZPL_DACL_ACES, &bonussz);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202208180146.27I1kg5P095015>