]> Pileus Git - ~andy/linux/blobdiff - include/linux/time.h
time: Improve sanity checking of timekeeping inputs
[~andy/linux] / include / linux / time.h
index 179f4d6755fc6f3b9e3c99f67e424b8c1e52bef2..b0bbd8f0130d52305d2ee945824327011f269e01 100644 (file)
@@ -107,11 +107,29 @@ static inline struct timespec timespec_sub(struct timespec lhs,
        return ts_delta;
 }
 
+#define KTIME_MAX                      ((s64)~((u64)1 << 63))
+#if (BITS_PER_LONG == 64)
+# define KTIME_SEC_MAX                 (KTIME_MAX / NSEC_PER_SEC)
+#else
+# define KTIME_SEC_MAX                 LONG_MAX
+#endif
+
 /*
  * Returns true if the timespec is norm, false if denorm:
  */
-#define timespec_valid(ts) \
-       (((ts)->tv_sec >= 0) && (((unsigned long) (ts)->tv_nsec) < NSEC_PER_SEC))
+static inline bool timespec_valid(const struct timespec *ts)
+{
+       /* Dates before 1970 are bogus */
+       if (ts->tv_sec < 0)
+               return false;
+       /* Can't have more nanoseconds then a second */
+       if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC)
+               return false;
+       /* Disallow values that could overflow ktime_t */
+       if ((unsigned long long)ts->tv_sec >= KTIME_SEC_MAX)
+               return false;
+       return true;
+}
 
 extern void read_persistent_clock(struct timespec *ts);
 extern void read_boot_clock(struct timespec *ts);
@@ -257,14 +275,6 @@ static __always_inline void timespec_add_ns(struct timespec *a, u64 ns)
 
 #endif /* __KERNEL__ */
 
-#define NFDBITS                        __NFDBITS
-
-#define FD_SETSIZE             __FD_SETSIZE
-#define FD_SET(fd,fdsetp)      __FD_SET(fd,fdsetp)
-#define FD_CLR(fd,fdsetp)      __FD_CLR(fd,fdsetp)
-#define FD_ISSET(fd,fdsetp)    __FD_ISSET(fd,fdsetp)
-#define FD_ZERO(fdsetp)                __FD_ZERO(fdsetp)
-
 /*
  * Names of the interval timers, and structure
  * defining a timer setting: