Skip to content

Commit 2ae83bf

Browse files
committed
[CIFS] Fix setting time before epoch (negative time values)
xfstest generic/258 sets the time on a file to a negative value (before 1970) which fails since do_div can not handle negative numbers. In addition 'normal' division of 64 bit values does not build on 32 bit arch so have to workaround this by special casing negative values in cifs_NTtimeToUnix Samba server also has a bug with this (see samba bugzilla 7771) but it works to Windows server. Signed-off-by: Steve French <smfrench@gmail.com>
1 parent 1536340 commit 2ae83bf

File tree

1 file changed

+16
-4
lines changed

1 file changed

+16
-4
lines changed

fs/cifs/netmisc.c

+16-4
Original file line numberDiff line numberDiff line change
@@ -925,11 +925,23 @@ cifs_NTtimeToUnix(__le64 ntutc)
925925
/* BB what about the timezone? BB */
926926

927927
/* Subtract the NTFS time offset, then convert to 1s intervals. */
928-
u64 t;
928+
s64 t = le64_to_cpu(ntutc) - NTFS_TIME_OFFSET;
929+
930+
/*
931+
* Unfortunately can not use normal 64 bit division on 32 bit arch, but
932+
* the alternative, do_div, does not work with negative numbers so have
933+
* to special case them
934+
*/
935+
if (t < 0) {
936+
t = -t;
937+
ts.tv_nsec = (long)(do_div(t, 10000000) * 100);
938+
ts.tv_nsec = -ts.tv_nsec;
939+
ts.tv_sec = -t;
940+
} else {
941+
ts.tv_nsec = (long)do_div(t, 10000000) * 100;
942+
ts.tv_sec = t;
943+
}
929944

930-
t = le64_to_cpu(ntutc) - NTFS_TIME_OFFSET;
931-
ts.tv_nsec = do_div(t, 10000000) * 100;
932-
ts.tv_sec = t;
933945
return ts;
934946
}
935947

0 commit comments

Comments
 (0)