USB: EHCI: Fix isochronous URB leak
[safe/jmp/linux-2.6] / kernel / time.c
index cbe0d5a..2951194 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/math64.h>
+#include <linux/ptrace.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -59,14 +60,15 @@ EXPORT_SYMBOL(sys_tz);
  * why not move it into the appropriate arch directory (for those
  * architectures that need it).
  */
-asmlinkage long sys_time(time_t __user * tloc)
+SYSCALL_DEFINE1(time, time_t __user *, tloc)
 {
        time_t i = get_seconds();
 
        if (tloc) {
                if (put_user(i,tloc))
-                       i = -EFAULT;
+                       return -EFAULT;
        }
+       force_successful_syscall_return();
        return i;
 }
 
@@ -77,7 +79,7 @@ asmlinkage long sys_time(time_t __user * tloc)
  * architectures that need it).
  */
 
-asmlinkage long sys_stime(time_t __user *tptr)
+SYSCALL_DEFINE1(stime, time_t __user *, tptr)
 {
        struct timespec tv;
        int err;
@@ -97,8 +99,8 @@ asmlinkage long sys_stime(time_t __user *tptr)
 
 #endif /* __ARCH_WANT_SYS_TIME */
 
-asmlinkage long sys_gettimeofday(struct timeval __user *tv,
-                                struct timezone __user *tz)
+SYSCALL_DEFINE2(gettimeofday, struct timeval __user *, tv,
+               struct timezone __user *, tz)
 {
        if (likely(tv != NULL)) {
                struct timeval ktv;
@@ -182,8 +184,8 @@ int do_sys_settimeofday(struct timespec *tv, struct timezone *tz)
        return 0;
 }
 
-asmlinkage long sys_settimeofday(struct timeval __user *tv,
-                               struct timezone __user *tz)
+SYSCALL_DEFINE2(settimeofday, struct timeval __user *, tv,
+               struct timezone __user *, tz)
 {
        struct timeval user_tv;
        struct timespec new_ts;
@@ -203,7 +205,7 @@ asmlinkage long sys_settimeofday(struct timeval __user *tv,
        return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
 }
 
-asmlinkage long sys_adjtimex(struct timex __user *txc_p)
+SYSCALL_DEFINE1(adjtimex, struct timex __user *, txc_p)
 {
        struct timex txc;               /* Local copy of parameter */
        int ret;
@@ -246,7 +248,7 @@ unsigned int inline jiffies_to_msecs(const unsigned long j)
        return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC);
 #else
 # if BITS_PER_LONG == 32
-       return ((u64)HZ_TO_MSEC_MUL32 * j) >> HZ_TO_MSEC_SHR32;
+       return (HZ_TO_MSEC_MUL32 * j) >> HZ_TO_MSEC_SHR32;
 # else
        return (j * HZ_TO_MSEC_NUM) / HZ_TO_MSEC_DEN;
 # endif
@@ -262,7 +264,7 @@ unsigned int inline jiffies_to_usecs(const unsigned long j)
        return (j + (HZ / USEC_PER_SEC) - 1)/(HZ / USEC_PER_SEC);
 #else
 # if BITS_PER_LONG == 32
-       return ((u64)HZ_TO_USEC_MUL32 * j) >> HZ_TO_USEC_SHR32;
+       return (HZ_TO_USEC_MUL32 * j) >> HZ_TO_USEC_SHR32;
 # else
        return (j * HZ_TO_USEC_NUM) / HZ_TO_USEC_DEN;
 # endif
@@ -476,7 +478,7 @@ unsigned long msecs_to_jiffies(const unsigned int m)
        if (HZ > MSEC_PER_SEC && m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
                return MAX_JIFFY_OFFSET;
 
-       return ((u64)MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32)
+       return (MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32)
                >> MSEC_TO_HZ_SHR32;
 #endif
 }
@@ -491,7 +493,7 @@ unsigned long usecs_to_jiffies(const unsigned int u)
 #elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
        return u * (HZ / USEC_PER_SEC);
 #else
-       return ((u64)USEC_TO_HZ_MUL32 * u + USEC_TO_HZ_ADJ32)
+       return (USEC_TO_HZ_MUL32 * u + USEC_TO_HZ_ADJ32)
                >> USEC_TO_HZ_SHR32;
 #endif
 }
@@ -669,3 +671,21 @@ EXPORT_SYMBOL(get_jiffies_64);
 #endif
 
 EXPORT_SYMBOL(jiffies);
+
+/*
+ * Add two timespec values and do a safety check for overflow.
+ * It's assumed that both values are valid (>= 0)
+ */
+struct timespec timespec_add_safe(const struct timespec lhs,
+                                 const struct timespec rhs)
+{
+       struct timespec res;
+
+       set_normalized_timespec(&res, lhs.tv_sec + rhs.tv_sec,
+                               lhs.tv_nsec + rhs.tv_nsec);
+
+       if (res.tv_sec < lhs.tv_sec || res.tv_sec < rhs.tv_sec)
+               res.tv_sec = TIME_T_MAX;
+
+       return res;
+}