lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1383981551.8994.27.camel@chiang>
Date:	Sat, 09 Nov 2013 02:19:11 -0500
From:	David Turner <novalis@...alis.org>
To:	Andreas Dilger <adilger@...ger.ca>
Cc:	Jan Kara <jack@...e.cz>,
	Ext4 Developers List <linux-ext4@...r.kernel.org>,
	Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
	Theodore Ts'o <tytso@....edu>
Subject: [PATCH] ext4: explain encoding of 34-bit a,c,mtime values

On Fri, 2013-11-08 at 14:37 -0700, Andreas Dilger wrote:
> On Nov 7, 2013, at 4:26 PM, David Turner <novalis@...alis.org> wrote:
> > On Fri, 2013-11-08 at 00:14 +0100, Jan Kara wrote:
> >> Still unnecessary type cast here (but that's a cosmetic issue).
> > ...
> >> Otherwise the patch looks good. You can add:
> >> Reviewed-by: Jan Kara <jack@...e.cz>
> > 
> > Thanks.  A version with this correction and the reviewed-by follows.
> 
> Thanks for working on this.  It was (seriously) in my list of things to
> get done, but I figured I still had a few years to work on it...
> 
> My (unfinished) version of this patch had a nice comment at ext4_encode_time()
> that explained the encoding that is being used very clearly:
> 
> /*
>  * We need is an encoding that preserves the times for extra epoch "00":
>  *
>  * extra  msb of                         adjust for signed
>  * epoch  32-bit                         32-bit tv_sec to
>  * bits   time    decoded 64-bit tv_sec  64-bit tv_sec      valid time range
>  * 0 0    1    -0x80000000..-0x00000001  0x000000000     1901-12-13..1969-12-31
>  * 0 0    0    0x000000000..0x07fffffff  0x000000000     1970-01-01..2038-01-19
>  * 0 1    1    0x080000000..0x0ffffffff  0x100000000     2038-01-19..2106-02-07
>  * 0 1    0    0x100000000..0x17fffffff  0x100000000     2106-02-07..2174-02-25
>  * 1 0    1    0x180000000..0x1ffffffff  0x200000000     2174-02-25..2242-03-16
>  * 1 0    0    0x200000000..0x27fffffff  0x200000000     2242-03-16..2310-04-04
>  * 1 1    1    0x280000000..0x2ffffffff  0x300000000     2310-04-04..2378-04-22
>  * 1 1    0    0x300000000..0x37fffffff  0x300000000     2378-04-22..2446-05-10
>  */
> 
> It seems that your version of the patch seems to use a different encoding.  Not
> that this is a problem, per-se, since my patch wasn’t in use anywhere, but it
> would be nice to have a similarly clear explanation of what the mapping is so
> that it can be clearly understood.

I have included a patch with an explanation (the patch is against
tytso/dev -- I hope that's the correct place).  

> My ext4_{encode,decode}_extra_time() used add/subtract instead of mask/OR ops,
> which changed the on-disk format for times beyond 2038, but those were already
> broken, and presumably not in use by anyone yet. 

They were actually correct according to my patch's encoding (that is, my
patch used the existing encoding).  The existing encoding was written
correctly, but read wrongly.  As you say, this should not matter, since
nobody should be writing these timestamps, but I assumed that the
existing encoding had happened for a reason, and wanted to make the
minimal change.

If you believe it is important, I would be happy to change it.

>  However, it seemed to me this
> was easier to produce the correct results.  Have you tested your patch with
> a variety of timestamps to verify its correctness? 

I tested by using touch -d to create one file in each year between 1902
and 2446.  Then I unmounted and remounted the FS, and did ls -l and
manually verified that each file's date matched its name.

> It looks to me like you
> have mapped the 1901-1969 range onto 0x3 for the epoch bits, instead 
> of the (IMHO) natural 0x0 bits. The critical time ranges are listed 
> above.

I think the idea of this is that it is the bottom 34 bits of the 64-bit
signed time.  However, it occurs to me that this relies on a two's
complement machine.  Even though the C standard does not guarantee this,
I believe the kernel requires it, so that's probably OK.

Patch follows:

--
Add a comment explaining the encoding of ext4's extra {a,c,m}time
bits.

Signed-off-by: David Turner <novalis@...alis.org>
---
 fs/ext4/ext4.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 121da383..ab69f14 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -713,6 +713,24 @@ struct move_extent {
 	  sizeof((ext4_inode)->field))			\
 	<= (EXT4_GOOD_OLD_INODE_SIZE +			\
 	    (einode)->i_extra_isize))			\
+/*
+ * We use the bottom 34 bits of the signed 64-bit time value, with
+ * the top two of these bits in the bottom of extra.  This leads
+ * to a slightly odd encoding, which works like this:
+ *
+ * extra  msb of
+ * epoch  32-bit
+ * bits   time    decoded 64-bit tv_sec   valid time range
+ * 0 0    0    0x000000000..0x07fffffff  1970-01-01..2038-01-19
+ * 0 0    1    0x080000000..0x0ffffffff  2038-01-19..2106-02-07
+ * 0 1    0    0x100000000..0x17fffffff  2106-02-07..2174-02-25
+ * 0 1    1    0x180000000..0x1ffffffff  2174-02-25..2242-03-16
+ * 1 0    0    0x200000000..0x27fffffff  2242-03-16..2310-04-04
+ * 1 0    1    0x280000000..0x2ffffffff  2310-04-04..2378-04-22
+ * 1 1    0    0x300000000..0x37fffffff  2378-04-22..2446-05-10
+
+ * 1 1    1    -0x80000000..-0x00000001  1901-12-13..1969-12-31
+ */
 
 static inline __le32 ext4_encode_extra_time(struct timespec *time)
 {
-- 
1.8.1.2



--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists