From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753419Ab3KGWyg (ORCPT ); Thu, 7 Nov 2013 17:54:36 -0500 Received: from caiajhbdcahe.dreamhost.com ([208.97.132.74]:57199 "EHLO homiemail-a101.g.dreamhost.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1754034Ab3KGWy0 (ORCPT ); Thu, 7 Nov 2013 17:54:26 -0500 X-Greylist: delayed 56274 seconds by postgrey-1.27 at vger.kernel.org; Thu, 07 Nov 2013 17:54:26 EST DomainKey-Signature: a=rsa-sha1; c=nofws; d=novalis.org; h=message-id:subject :from:to:cc:date:in-reply-to:references:content-type :mime-version:content-transfer-encoding; q=dns; s=novalis.org; b=Z9DDSkEnNBw+WJudfpHbbX3Vu8ZrmNlzQzbepRDcGYb5EU3tFG0HJpygHj7lh 2UICesKTVkYXZ97IStt7R0JhvAEsCjAcQ8Qf4Lvd+VkWCb3vxOzFwjbw/0oPuLXi s3AP+bp/ot+HDA72F+pPIUCCwLhj/e9X7/eLMvSIacxLpQ= Message-ID: <1383864864.23882.33.camel@chiang> Subject: [PATCH v2] ext4: Fix reading of extended tv_sec (bug 23732) From: David Turner To: Jan Kara Cc: linux-ext4@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Dilger , "Theodore Ts'o" Date: Thu, 07 Nov 2013 17:54:24 -0500 In-Reply-To: <20131107160341.GA3850@quack.suse.cz> References: <1383808590.23882.13.camel@chiang> <20131107160341.GA3850@quack.suse.cz> Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.6.4-0ubuntu1 Mime-Version: 1.0 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, 2013-11-07 at 17:03 +0100, Jan Kara wrote: > So I'm somewhat wondering: Previously we decoded tv_nsec regardless of > tv_sec size. After your patch we do it only if sizeof(time->tv_sec) > 4. Is > this an intended change? Why is it OK? This is an error. Here is a corrected version of the patch. -- In ext4, the bottom two bits of {a,c,m}time_extra are used to extend the {a,c,m}time fields, deferring the year 2038 problem to the year 2446. The representation (which this patch does not alter) is a bit hackish, in that the most-significant bit is no longer (alone) sufficient to indicate the sign. That's because we're representing an asymmetric range, with seven times as many positive values as negative. When decoding these extended fields, for times whose bottom 32 bits would represent a negative number, sign extension causes the 64-bit extended timestamp to be negative as well, which is not what's intended. This patch corrects that issue, so that the only negative {a,c,m}times are those between 1901 and 1970 (as per 32-bit signed timestamps). Signed-off-by: David Turner Reported-by: Mark Harris Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=23732 --- fs/ext4/ext4.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index af815ea..3c2d0b3 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -722,10 +722,15 @@ static inline __le32 ext4_encode_extra_time(struct timespec *time) static inline void ext4_decode_extra_time(struct timespec *time, __le32 extra) { - if (sizeof(time->tv_sec) > 4) - time->tv_sec |= (__u64)(le32_to_cpu(extra) & EXT4_EPOCH_MASK) - << 32; - time->tv_nsec = (le32_to_cpu(extra) & EXT4_NSEC_MASK) >> EXT4_EPOCH_BITS; + if (sizeof(time->tv_sec) > 4) { + u64 extra_bits = (__u64)(le32_to_cpu(extra) & EXT4_EPOCH_MASK); + if (time->tv_sec > 0 || extra_bits != EXT4_EPOCH_MASK) { + time->tv_sec &= 0xFFFFFFFF; + time->tv_sec |= extra_bits << 32; + } + } + time->tv_nsec = (le32_to_cpu(extra) & EXT4_NSEC_MASK) >> + EXT4_EPOCH_BITS; } #define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode) \ -- 1.8.1.2