2007-02-06 21:30:28

by Markus Rechberger

[permalink] [raw]
Subject: [patch] x86-64 ext2/ext3 datestamp problem

diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index dd4e14c..9fa1bd6 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -1079,9 +1079,9 @@ void ext2_read_inode (struct inode * inode)
}
inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
inode->i_size = le32_to_cpu(raw_inode->i_size);
- inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime);
- inode->i_ctime.tv_sec = le32_to_cpu(raw_inode->i_ctime);
- inode->i_mtime.tv_sec = le32_to_cpu(raw_inode->i_mtime);
+ inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
+ inode->i_ctime.tv_sec = (signed)le32_to_cpu(raw_inode->i_ctime);
+ inode->i_mtime.tv_sec = (signed)le32_to_cpu(raw_inode->i_mtime);
inode->i_atime.tv_nsec = inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = 0;
ei->i_dtime = le32_to_cpu(raw_inode->i_dtime);
/* We now have enough fields to check if the inode was active or not.
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index beaf25f..5d171c0 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -2673,9 +2673,9 @@ void ext3_read_inode(struct inode * inode)
}
inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
inode->i_size = le32_to_cpu(raw_inode->i_size);
- inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime);
- inode->i_ctime.tv_sec = le32_to_cpu(raw_inode->i_ctime);
- inode->i_mtime.tv_sec = le32_to_cpu(raw_inode->i_mtime);
+ inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
+ inode->i_ctime.tv_sec = (signed)le32_to_cpu(raw_inode->i_ctime);
+ inode->i_mtime.tv_sec = (signed)le32_to_cpu(raw_inode->i_mtime);
inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_mtime.tv_nsec = 0;

ei->i_state = 0;


Attachments:
inode.diff (1.62 kB)

2007-02-06 21:37:58

by Markus Rechberger

[permalink] [raw]
Subject: Re: [patch] x86-64 ext2/ext3 datestamp problem

Signed-off-by: Markus Rechberger <[email protected]>

Markus Rechberger wrote:
> Hi,
>
> there is an issue with ext2/ext3 date stamps, if someone creates a file
> with a timestamp between 1902 and 1970(epoch 0) it will overflow and
> result in a higher date than 2038.
>
> $ touch --date "1905-01-01" test
> $ ls -lah test
> -rw-r--r-- 1 root root 0 Jan 1 1905 test (this is a cached value here)
> (remount the partition/clear the cache)
> $ ls -lah test
> -rw-r--r-- 1 root root 0 Feb 6 2041 test
>
> 10000101101111001100011001110000 .. -2051226000 (1905)
> 10000101101111001100011001110000 .. 2243741296 (2041)
>
> this was tested against linus git tree
>
> Markus
>
>
> ------------------------------------------------------------------------
>
> diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
> index dd4e14c..9fa1bd6 100644
> --- a/fs/ext2/inode.c
> +++ b/fs/ext2/inode.c
> @@ -1079,9 +1079,9 @@ void ext2_read_inode (struct inode * inode)
> }
> inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
> inode->i_size = le32_to_cpu(raw_inode->i_size);
> - inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime);
> - inode->i_ctime.tv_sec = le32_to_cpu(raw_inode->i_ctime);
> - inode->i_mtime.tv_sec = le32_to_cpu(raw_inode->i_mtime);
> + inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
> + inode->i_ctime.tv_sec = (signed)le32_to_cpu(raw_inode->i_ctime);
> + inode->i_mtime.tv_sec = (signed)le32_to_cpu(raw_inode->i_mtime);
> inode->i_atime.tv_nsec = inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = 0;
> ei->i_dtime = le32_to_cpu(raw_inode->i_dtime);
> /* We now have enough fields to check if the inode was active or not.
> diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
> index beaf25f..5d171c0 100644
> --- a/fs/ext3/inode.c
> +++ b/fs/ext3/inode.c
> @@ -2673,9 +2673,9 @@ void ext3_read_inode(struct inode * inode)
> }
> inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
> inode->i_size = le32_to_cpu(raw_inode->i_size);
> - inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime);
> - inode->i_ctime.tv_sec = le32_to_cpu(raw_inode->i_ctime);
> - inode->i_mtime.tv_sec = le32_to_cpu(raw_inode->i_mtime);
> + inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
> + inode->i_ctime.tv_sec = (signed)le32_to_cpu(raw_inode->i_ctime);
> + inode->i_mtime.tv_sec = (signed)le32_to_cpu(raw_inode->i_mtime);
> inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_mtime.tv_nsec = 0;
>
> ei->i_state = 0;
>


--
Markus Rechberger
Operating System Research Center
AMD Saxony LLC & Co. KG



2007-02-06 21:49:36

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [patch] x86-64 ext2/ext3 datestamp problem

Markus Rechberger wrote:
> Hi,
>
> there is an issue with ext2/ext3 date stamps, if someone creates a file
> with a timestamp between 1902 and 1970(epoch 0) it will overflow and
> result in a higher date than 2038.
>
> $ touch --date "1905-01-01" test
> $ ls -lah test
> -rw-r--r-- 1 root root 0 Jan 1 1905 test (this is a cached value here)
> (remount the partition/clear the cache)
> $ ls -lah test
> -rw-r--r-- 1 root root 0 Feb 6 2041 test
>
> 10000101101111001100011001110000 .. -2051226000 (1905)
> 10000101101111001100011001110000 .. 2243741296 (2041)
>
> this was tested against linus git tree
>

I believe the timestamp fields in ext2/ext3 are defined as unsigned.

-hpa

2007-02-06 21:54:59

by Markus Rechberger

[permalink] [raw]
Subject: Re: [patch] x86-64 ext2/ext3 datestamp problem

H. Peter Anvin wrote:
> Markus Rechberger wrote:
>> Hi,
>>
>> there is an issue with ext2/ext3 date stamps, if someone creates a file
>> with a timestamp between 1902 and 1970(epoch 0) it will overflow and
>> result in a higher date than 2038.
>>
>> $ touch --date "1905-01-01" test
>> $ ls -lah test
>> -rw-r--r-- 1 root root 0 Jan 1 1905 test (this is a cached value here)
>> (remount the partition/clear the cache)
>> $ ls -lah test
>> -rw-r--r-- 1 root root 0 Feb 6 2041 test
>>
>> 10000101101111001100011001110000 .. -2051226000 (1905)
>> 10000101101111001100011001110000 .. 2243741296 (2041)
>>
>> this was tested against linus git tree
>>
>
> I believe the timestamp fields in ext2/ext3 are defined as unsigned.
>
> -hpa
>
>
My debian system's coreutils package only allows dates between 1902 and
2038, but it might be interesting to get that right if it's wrong.

touch (GNU coreutils) 5.97 just says invalid dateformat to 2050-01-01

Markus

--
Markus Rechberger
Operating System Research Center
AMD Saxony LLC & Co. KG



2007-02-06 22:00:18

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [patch] x86-64 ext2/ext3 datestamp problem

Markus Rechberger wrote:
> My debian system's coreutils package only allows dates between 1902 and
> 2038, but it might be interesting to get that right if it's wrong.
>
> touch (GNU coreutils) 5.97 just says invalid dateformat to 2050-01-01

Lemme guess, you're on a 32-bit system...

-hpa

2007-02-06 22:04:32

by Markus Rechberger

[permalink] [raw]
Subject: Re: [patch] x86-64 ext2/ext3 datestamp problem

H. Peter Anvin wrote:
> Markus Rechberger wrote:
>> My debian system's coreutils package only allows dates between 1902 and
>> 2038, but it might be interesting to get that right if it's wrong.
>>
>> touch (GNU coreutils) 5.97 just says invalid dateformat to 2050-01-01
>
> Lemme guess, you're on a 32-bit system...
>

I have both here, 64 and 32bit
If I touch a file with 1905 on my 32bit system and remount the disk the
date will remain at 1905 without any patch.

Markus


2007-02-06 22:07:14

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [patch] x86-64 ext2/ext3 datestamp problem

Markus Rechberger wrote:
> H. Peter Anvin wrote:
>> Markus Rechberger wrote:
>>> My debian system's coreutils package only allows dates between 1902 and
>>> 2038, but it might be interesting to get that right if it's wrong.
>>>
>>> touch (GNU coreutils) 5.97 just says invalid dateformat to 2050-01-01
>> Lemme guess, you're on a 32-bit system...
>>
>
> I have both here, 64 and 32bit
> If I touch a file with 1905 on my 32bit system and remount the disk the
> date will remain at 1905 without any patch.
>

The reason is that most 32-bit systems (e.g. i386) only have a 32-bit
time_t, so the user space interface wraps around in 2038.

However, most 64-bit systems (e.g. x86_64) have 64-bit time_t, and thus
don't have that problem.

-hpa

2007-02-06 22:20:53

by Markus Rechberger

[permalink] [raw]
Subject: Re: [patch] x86-64 ext2/ext3 datestamp problem

H. Peter Anvin wrote:
> Markus Rechberger wrote:
>> H. Peter Anvin wrote:
>>> Markus Rechberger wrote:
>>>> My debian system's coreutils package only allows dates between 1902
>>>> and
>>>> 2038, but it might be interesting to get that right if it's wrong.
>>>>
>>>> touch (GNU coreutils) 5.97 just says invalid dateformat to 2050-01-01
>>> Lemme guess, you're on a 32-bit system...
>>>
>>
>> I have both here, 64 and 32bit
>> If I touch a file with 1905 on my 32bit system and remount the disk the
>> date will remain at 1905 without any patch.
>>
>
> The reason is that most 32-bit systems (e.g. i386) only have a 32-bit
> time_t, so the user space interface wraps around in 2038.
>
> However, most 64-bit systems (e.g. x86_64) have 64-bit time_t, and
> thus don't have that problem.
>
> -hpa
>
>
I know time_t expands to long, anyway the existing filesystem layout

cannot be changed so that problem would even remain with a 64bit system
unless the whole system would really treat it as unsigned. A 64 bit
system will cast the unsigned stamp over a signed long value which in
this case is bigger than 32 bit and behaves differently.


--
Markus Rechberger
Operating System Research Center
AMD Saxony LLC & Co. KG