aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-09-19 12:42:37 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-09-19 12:42:37 -0400
commitcfb82e1df8b7c76991ea12958855897c2fb4debc (patch)
tree7419ef2cef9ec1ea43b78619af6ddd3471152a44 /fs/cifs
parentb41dae061bbd722b9d7fa828f35d22035b218e18 (diff)
parentcba465b4f9820b0d929822a70341dde14909fc18 (diff)
Merge tag 'y2038-vfs' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground
Pull y2038 vfs updates from Arnd Bergmann: "Add inode timestamp clamping. This series from Deepa Dinamani adds a per-superblock minimum/maximum timestamp limit for a file system, and clamps timestamps as they are written, to avoid random behavior from integer overflow as well as having different time stamps on disk vs in memory. At mount time, a warning is now printed for any file system that can represent current timestamps but not future timestamps more than 30 years into the future, similar to the arbitrary 30 year limit that was added to settimeofday(). This was picked as a compromise to warn users to migrate to other file systems (e.g. ext4 instead of ext3) when they need the file system to survive beyond 2038 (or similar limits in other file systems), but not get in the way of normal usage" * tag 'y2038-vfs' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground: ext4: Reduce ext4 timestamp warnings isofs: Initialize filesystem timestamp ranges pstore: fs superblock limits fs: omfs: Initialize filesystem timestamp ranges fs: hpfs: Initialize filesystem timestamp ranges fs: ceph: Initialize filesystem timestamp ranges fs: sysv: Initialize filesystem timestamp ranges fs: affs: Initialize filesystem timestamp ranges fs: fat: Initialize filesystem timestamp ranges fs: cifs: Initialize filesystem timestamp ranges fs: nfs: Initialize filesystem timestamp ranges ext4: Initialize timestamps limits 9p: Fill min and max timestamps in sb fs: Fill in max and min timestamps in superblock utimes: Clamp the timestamps before update mount: Add mount warning for impending timestamp expiry timestamp_truncate: Replace users of timespec64_trunc vfs: Add timestamp_truncate() api vfs: Add file timestamp range support
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifsfs.c22
-rw-r--r--fs/cifs/netmisc.c14
2 files changed, 29 insertions, 7 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 4e2f74894e9b..e8afff702bb8 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -56,6 +56,15 @@
56#include "dfs_cache.h" 56#include "dfs_cache.h"
57#endif 57#endif
58 58
59/*
60 * DOS dates from 1980/1/1 through 2107/12/31
61 * Protocol specifications indicate the range should be to 119, which
62 * limits maximum year to 2099. But this range has not been checked.
63 */
64#define SMB_DATE_MAX (127<<9 | 12<<5 | 31)
65#define SMB_DATE_MIN (0<<9 | 1<<5 | 1)
66#define SMB_TIME_MAX (23<<11 | 59<<5 | 29)
67
59int cifsFYI = 0; 68int cifsFYI = 0;
60bool traceSMB; 69bool traceSMB;
61bool enable_oplocks = true; 70bool enable_oplocks = true;
@@ -142,6 +151,7 @@ cifs_read_super(struct super_block *sb)
142 struct inode *inode; 151 struct inode *inode;
143 struct cifs_sb_info *cifs_sb; 152 struct cifs_sb_info *cifs_sb;
144 struct cifs_tcon *tcon; 153 struct cifs_tcon *tcon;
154 struct timespec64 ts;
145 int rc = 0; 155 int rc = 0;
146 156
147 cifs_sb = CIFS_SB(sb); 157 cifs_sb = CIFS_SB(sb);
@@ -161,6 +171,18 @@ cifs_read_super(struct super_block *sb)
161 /* BB FIXME fix time_gran to be larger for LANMAN sessions */ 171 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
162 sb->s_time_gran = 100; 172 sb->s_time_gran = 100;
163 173
174 if (tcon->unix_ext) {
175 ts = cifs_NTtimeToUnix(0);
176 sb->s_time_min = ts.tv_sec;
177 ts = cifs_NTtimeToUnix(cpu_to_le64(S64_MAX));
178 sb->s_time_max = ts.tv_sec;
179 } else {
180 ts = cnvrtDosUnixTm(cpu_to_le16(SMB_DATE_MIN), 0, 0);
181 sb->s_time_min = ts.tv_sec;
182 ts = cnvrtDosUnixTm(cpu_to_le16(SMB_DATE_MAX), cpu_to_le16(SMB_TIME_MAX), 0);
183 sb->s_time_max = ts.tv_sec;
184 }
185
164 sb->s_magic = CIFS_MAGIC_NUMBER; 186 sb->s_magic = CIFS_MAGIC_NUMBER;
165 sb->s_op = &cifs_super_ops; 187 sb->s_op = &cifs_super_ops;
166 sb->s_xattr = cifs_xattr_handlers; 188 sb->s_xattr = cifs_xattr_handlers;
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index ed92958e842d..49c17ee18254 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -949,8 +949,8 @@ static const int total_days_of_prev_months[] = {
949struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset) 949struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset)
950{ 950{
951 struct timespec64 ts; 951 struct timespec64 ts;
952 time64_t sec; 952 time64_t sec, days;
953 int min, days, month, year; 953 int min, day, month, year;
954 u16 date = le16_to_cpu(le_date); 954 u16 date = le16_to_cpu(le_date);
955 u16 time = le16_to_cpu(le_time); 955 u16 time = le16_to_cpu(le_time);
956 SMB_TIME *st = (SMB_TIME *)&time; 956 SMB_TIME *st = (SMB_TIME *)&time;
@@ -966,15 +966,15 @@ struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset)
966 sec += 60 * 60 * st->Hours; 966 sec += 60 * 60 * st->Hours;
967 if (st->Hours > 24) 967 if (st->Hours > 24)
968 cifs_dbg(VFS, "illegal hours %d\n", st->Hours); 968 cifs_dbg(VFS, "illegal hours %d\n", st->Hours);
969 days = sd->Day; 969 day = sd->Day;
970 month = sd->Month; 970 month = sd->Month;
971 if (days < 1 || days > 31 || month < 1 || month > 12) { 971 if (day < 1 || day > 31 || month < 1 || month > 12) {
972 cifs_dbg(VFS, "illegal date, month %d day: %d\n", month, days); 972 cifs_dbg(VFS, "illegal date, month %d day: %d\n", month, day);
973 days = clamp(days, 1, 31); 973 day = clamp(day, 1, 31);
974 month = clamp(month, 1, 12); 974 month = clamp(month, 1, 12);
975 } 975 }
976 month -= 1; 976 month -= 1;
977 days += total_days_of_prev_months[month]; 977 days = day + total_days_of_prev_months[month];
978 days += 3652; /* account for difference in days between 1980 and 1970 */ 978 days += 3652; /* account for difference in days between 1980 and 1970 */
979 year = sd->Year; 979 year = sd->Year;
980 days += year * 365; 980 days += year * 365;