timex: use __kernel_timex internally
authorDeepa Dinamani <deepa.kernel@gmail.com>
Tue, 3 Jul 2018 05:44:21 +0000 (22:44 -0700)
committerArnd Bergmann <arnd@arndb.de>
Wed, 6 Feb 2019 23:13:27 +0000 (00:13 +0100)
struct timex is not y2038 safe.
Replace all uses of timex with y2038 safe __kernel_timex.

Note that struct __kernel_timex is an ABI interface definition.
We could define a new structure based on __kernel_timex that
is only available internally instead. Right now, there isn't
a strong motivation for this as the structure is isolated to
a few defined struct timex interfaces and such a structure would
be exactly the same as struct timex.

The patch was generated by the following coccinelle script:

virtual patch

@depends on patch forall@
identifier ts;
expression e;
@@
(
- struct timex ts;
+ struct __kernel_timex ts;
|
- struct timex ts = {};
+ struct __kernel_timex ts = {};
|
- struct timex ts = e;
+ struct __kernel_timex ts = e;
|
- struct timex *ts;
+ struct __kernel_timex *ts;
|
(memset \| copy_from_user \| copy_to_user \)(...,
- sizeof(struct timex))
+ sizeof(struct __kernel_timex))
)

@depends on patch forall@
identifier ts;
identifier fn;
@@
fn(...,
- struct timex *ts,
+ struct __kernel_timex *ts,
...) {
...
}

@depends on patch forall@
identifier ts;
identifier fn;
@@
fn(...,
- struct timex *ts) {
+ struct __kernel_timex *ts) {
...
}

Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
Cc: linux-alpha@vger.kernel.org
Cc: netdev@vger.kernel.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
13 files changed:
arch/alpha/kernel/osf_sys.c
arch/sparc/kernel/sys_sparc_64.c
drivers/ptp/ptp_clock.c
include/linux/posix-clock.h
include/linux/time32.h
include/linux/timex.h
kernel/time/ntp.c
kernel/time/ntp_internal.h
kernel/time/posix-clock.c
kernel/time/posix-timers.c
kernel/time/posix-timers.h
kernel/time/time.c
kernel/time/timekeeping.c

index 7925860..bf497b8 100644 (file)
@@ -1253,7 +1253,7 @@ struct timex32 {
 
 SYSCALL_DEFINE1(old_adjtimex, struct timex32 __user *, txc_p)
 {
-        struct timex txc;
+       struct __kernel_timex txc;
        int ret;
 
        /* copy relevant bits of struct timex. */
@@ -1270,7 +1270,8 @@ SYSCALL_DEFINE1(old_adjtimex, struct timex32 __user *, txc_p)
        if (copy_to_user(txc_p, &txc, offsetof(struct timex32, time)) ||
            (copy_to_user(&txc_p->tick, &txc.tick, sizeof(struct timex32) - 
                          offsetof(struct timex32, tick))) ||
-           (put_tv_to_tv32(&txc_p->time, &txc.time)))
+           (put_user(txc.time.tv_sec, &txc_p->time.tv_sec)) ||
+           (put_user(txc.time.tv_usec, &txc_p->time.tv_usec)))
          return -EFAULT;
 
        return ret;
index 37de18a..9825ca6 100644 (file)
@@ -548,7 +548,7 @@ out_unlock:
 SYSCALL_DEFINE1(sparc_adjtimex, struct timex __user *, txc_p)
 {
        struct timex txc;               /* Local copy of parameter */
-       struct timex *kt = (void *)&txc;
+       struct __kernel_timex *kt = (void *)&txc;
        int ret;
 
        /* Copy the user data space into the kernel copy
@@ -572,7 +572,7 @@ SYSCALL_DEFINE1(sparc_adjtimex, struct timex __user *, txc_p)
 SYSCALL_DEFINE2(sparc_clock_adjtime, const clockid_t, which_clock,struct timex __user *, txc_p)
 {
        struct timex txc;               /* Local copy of parameter */
-       struct timex *kt = (void *)&txc;
+       struct __kernel_timex *kt = (void *)&txc;
        int ret;
 
        if (!IS_ENABLED(CONFIG_POSIX_TIMERS)) {
index 48f3594..79bd102 100644 (file)
@@ -124,7 +124,7 @@ static int ptp_clock_gettime(struct posix_clock *pc, struct timespec64 *tp)
        return err;
 }
 
-static int ptp_clock_adjtime(struct posix_clock *pc, struct timex *tx)
+static int ptp_clock_adjtime(struct posix_clock *pc, struct __kernel_timex *tx)
 {
        struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
        struct ptp_clock_info *ops;
index 3a3bc71..18674d7 100644 (file)
@@ -51,7 +51,7 @@ struct posix_clock;
 struct posix_clock_operations {
        struct module *owner;
 
-       int  (*clock_adjtime)(struct posix_clock *pc, struct timex *tx);
+       int  (*clock_adjtime)(struct posix_clock *pc, struct __kernel_timex *tx);
 
        int  (*clock_gettime)(struct posix_clock *pc, struct timespec64 *ts);
 
index 820a22e..0a1f302 100644 (file)
@@ -69,9 +69,9 @@ extern int get_old_itimerspec32(struct itimerspec64 *its,
                        const struct old_itimerspec32 __user *uits);
 extern int put_old_itimerspec32(const struct itimerspec64 *its,
                        struct old_itimerspec32 __user *uits);
-struct timex;
-int get_old_timex32(struct timex *, const struct old_timex32 __user *);
-int put_old_timex32(struct old_timex32 __user *, const struct timex *);
+struct __kernel_timex;
+int get_old_timex32(struct __kernel_timex *, const struct old_timex32 __user *);
+int put_old_timex32(struct old_timex32 __user *, const struct __kernel_timex *);
 
 #if __BITS_PER_LONG == 64
 
index a15e6ae..4aff9f0 100644 (file)
@@ -158,8 +158,8 @@ extern unsigned long tick_nsec;             /* SHIFTED_HZ period (nsec) */
 #define NTP_INTERVAL_FREQ  (HZ)
 #define NTP_INTERVAL_LENGTH (NSEC_PER_SEC/NTP_INTERVAL_FREQ)
 
-extern int do_adjtimex(struct timex *);
-extern int do_clock_adjtime(const clockid_t which_clock, struct timex * ktx);
+extern int do_adjtimex(struct __kernel_timex *);
+extern int do_clock_adjtime(const clockid_t which_clock, struct __kernel_timex * ktx);
 
 extern void hardpps(const struct timespec64 *, const struct timespec64 *);
 
index 36a2bef..92a9001 100644 (file)
@@ -188,13 +188,13 @@ static inline int is_error_status(int status)
                        && (status & (STA_PPSWANDER|STA_PPSERROR)));
 }
 
-static inline void pps_fill_timex(struct timex *txc)
+static inline void pps_fill_timex(struct __kernel_timex *txc)
 {
        txc->ppsfreq       = shift_right((pps_freq >> PPM_SCALE_INV_SHIFT) *
                                         PPM_SCALE_INV, NTP_SCALE_SHIFT);
        txc->jitter        = pps_jitter;
        if (!(time_status & STA_NANO))
-               txc->jitter /= NSEC_PER_USEC;
+               txc->jitter = pps_jitter / NSEC_PER_USEC;
        txc->shift         = pps_shift;
        txc->stabil        = pps_stabil;
        txc->jitcnt        = pps_jitcnt;
@@ -220,7 +220,7 @@ static inline int is_error_status(int status)
        return status & (STA_UNSYNC|STA_CLOCKERR);
 }
 
-static inline void pps_fill_timex(struct timex *txc)
+static inline void pps_fill_timex(struct __kernel_timex *txc)
 {
        /* PPS is not implemented, so these are zero */
        txc->ppsfreq       = 0;
@@ -633,7 +633,7 @@ void ntp_notify_cmos_timer(void)
 /*
  * Propagate a new txc->status value into the NTP state:
  */
-static inline void process_adj_status(const struct timex *txc)
+static inline void process_adj_status(const struct __kernel_timex *txc)
 {
        if ((time_status & STA_PLL) && !(txc->status & STA_PLL)) {
                time_state = TIME_OK;
@@ -656,7 +656,8 @@ static inline void process_adj_status(const struct timex *txc)
 }
 
 
-static inline void process_adjtimex_modes(const struct timex *txc, s32 *time_tai)
+static inline void process_adjtimex_modes(const struct __kernel_timex *txc,
+                                         s32 *time_tai)
 {
        if (txc->modes & ADJ_STATUS)
                process_adj_status(txc);
@@ -707,7 +708,8 @@ static inline void process_adjtimex_modes(const struct timex *txc, s32 *time_tai
  * adjtimex mainly allows reading (and writing, if superuser) of
  * kernel time-keeping variables. used by xntpd.
  */
-int __do_adjtimex(struct timex *txc, const struct timespec64 *ts, s32 *time_tai)
+int __do_adjtimex(struct __kernel_timex *txc, const struct timespec64 *ts,
+                 s32 *time_tai)
 {
        int result;
 
@@ -729,7 +731,7 @@ int __do_adjtimex(struct timex *txc, const struct timespec64 *ts, s32 *time_tai)
                txc->offset = shift_right(time_offset * NTP_INTERVAL_FREQ,
                                  NTP_SCALE_SHIFT);
                if (!(time_status & STA_NANO))
-                       txc->offset /= NSEC_PER_USEC;
+                       txc->offset = (u32)txc->offset / NSEC_PER_USEC;
        }
 
        result = time_state;    /* mostly `TIME_OK' */
@@ -754,7 +756,7 @@ int __do_adjtimex(struct timex *txc, const struct timespec64 *ts, s32 *time_tai)
        txc->time.tv_sec = (time_t)ts->tv_sec;
        txc->time.tv_usec = ts->tv_nsec;
        if (!(time_status & STA_NANO))
-               txc->time.tv_usec /= NSEC_PER_USEC;
+               txc->time.tv_usec = ts->tv_nsec / NSEC_PER_USEC;
 
        /* Handle leapsec adjustments */
        if (unlikely(ts->tv_sec >= ntp_next_leap_sec)) {
index c24b0e1..40e6122 100644 (file)
@@ -8,6 +8,6 @@ extern void ntp_clear(void);
 extern u64 ntp_tick_length(void);
 extern ktime_t ntp_get_next_leap(void);
 extern int second_overflow(time64_t secs);
-extern int __do_adjtimex(struct timex *txc, const struct timespec64 *ts, s32 *time_tai);
+extern int __do_adjtimex(struct __kernel_timex *txc, const struct timespec64 *ts, s32 *time_tai);
 extern void __hardpps(const struct timespec64 *phase_ts, const struct timespec64 *raw_ts);
 #endif /* _LINUX_NTP_INTERNAL_H */
index 425bbfc..ec960bb 100644 (file)
@@ -228,7 +228,7 @@ static void put_clock_desc(struct posix_clock_desc *cd)
        fput(cd->fp);
 }
 
-static int pc_clock_adjtime(clockid_t id, struct timex *tx)
+static int pc_clock_adjtime(clockid_t id, struct __kernel_timex *tx)
 {
        struct posix_clock_desc cd;
        int err;
index 8f7f1dd..2d84b3d 100644 (file)
@@ -179,7 +179,7 @@ static int posix_clock_realtime_set(const clockid_t which_clock,
 }
 
 static int posix_clock_realtime_adj(const clockid_t which_clock,
-                                   struct timex *t)
+                                   struct __kernel_timex *t)
 {
        return do_adjtimex(t);
 }
@@ -1047,7 +1047,7 @@ SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
        return error;
 }
 
-int do_clock_adjtime(const clockid_t which_clock, struct timex * ktx)
+int do_clock_adjtime(const clockid_t which_clock, struct __kernel_timex * ktx)
 {
        const struct k_clock *kc = clockid_to_kclock(which_clock);
 
@@ -1062,7 +1062,7 @@ int do_clock_adjtime(const clockid_t which_clock, struct timex * ktx)
 SYSCALL_DEFINE2(clock_adjtime, const clockid_t, which_clock,
                struct timex __user *, utx)
 {
-       struct timex ktx;
+       struct __kernel_timex ktx;
        int err;
 
        if (copy_from_user(&ktx, utx, sizeof(ktx)))
@@ -1132,7 +1132,7 @@ COMPAT_SYSCALL_DEFINE2(clock_gettime, clockid_t, which_clock,
 COMPAT_SYSCALL_DEFINE2(clock_adjtime, clockid_t, which_clock,
                       struct old_timex32 __user *, utp)
 {
-       struct timex ktx;
+       struct __kernel_timex ktx;
        int err;
 
        err = get_old_timex32(&ktx, utp);
index ddb2114..de5daa6 100644 (file)
@@ -8,7 +8,7 @@ struct k_clock {
                             const struct timespec64 *tp);
        int     (*clock_get)(const clockid_t which_clock,
                             struct timespec64 *tp);
-       int     (*clock_adj)(const clockid_t which_clock, struct timex *tx);
+       int     (*clock_adj)(const clockid_t which_clock, struct __kernel_timex *tx);
        int     (*timer_create)(struct k_itimer *timer);
        int     (*nsleep)(const clockid_t which_clock, int flags,
                          const struct timespec64 *);
index 2d013bc..d179d33 100644 (file)
@@ -265,25 +265,25 @@ COMPAT_SYSCALL_DEFINE2(settimeofday, struct old_timeval32 __user *, tv,
 
 SYSCALL_DEFINE1(adjtimex, struct timex __user *, txc_p)
 {
-       struct timex txc;               /* Local copy of parameter */
+       struct __kernel_timex txc;              /* Local copy of parameter */
        int ret;
 
        /* Copy the user data space into the kernel copy
         * structure. But bear in mind that the structures
         * may change
         */
-       if (copy_from_user(&txc, txc_p, sizeof(struct timex)))
+       if (copy_from_user(&txc, txc_p, sizeof(struct __kernel_timex)))
                return -EFAULT;
        ret = do_adjtimex(&txc);
-       return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : ret;
+       return copy_to_user(txc_p, &txc, sizeof(struct __kernel_timex)) ? -EFAULT : ret;
 }
 
 #ifdef CONFIG_COMPAT_32BIT_TIME
-int get_old_timex32(struct timex *txc, const struct old_timex32 __user *utp)
+int get_old_timex32(struct __kernel_timex *txc, const struct old_timex32 __user *utp)
 {
        struct old_timex32 tx32;
 
-       memset(txc, 0, sizeof(struct timex));
+       memset(txc, 0, sizeof(struct __kernel_timex));
        if (copy_from_user(&tx32, utp, sizeof(struct old_timex32)))
                return -EFAULT;
 
@@ -311,7 +311,7 @@ int get_old_timex32(struct timex *txc, const struct old_timex32 __user *utp)
        return 0;
 }
 
-int put_old_timex32(struct old_timex32 __user *utp, const struct timex *txc)
+int put_old_timex32(struct old_timex32 __user *utp, const struct __kernel_timex *txc)
 {
        struct old_timex32 tx32;
 
@@ -344,7 +344,7 @@ int put_old_timex32(struct old_timex32 __user *utp, const struct timex *txc)
 
 COMPAT_SYSCALL_DEFINE1(adjtimex, struct old_timex32 __user *, utp)
 {
-       struct timex txc;
+       struct __kernel_timex txc;
        int err, ret;
 
        err = get_old_timex32(&txc, utp);
index ac5dbf2..f986e19 100644 (file)
@@ -2234,7 +2234,7 @@ ktime_t ktime_get_update_offsets_now(unsigned int *cwsseq, ktime_t *offs_real,
 /**
  * timekeeping_validate_timex - Ensures the timex is ok for use in do_adjtimex
  */
-static int timekeeping_validate_timex(const struct timex *txc)
+static int timekeeping_validate_timex(const struct __kernel_timex *txc)
 {
        if (txc->modes & ADJ_ADJTIME) {
                /* singleshot must not be used with any other mode bits */
@@ -2300,7 +2300,7 @@ static int timekeeping_validate_timex(const struct timex *txc)
 /**
  * do_adjtimex() - Accessor function to NTP __do_adjtimex function
  */
-int do_adjtimex(struct timex *txc)
+int do_adjtimex(struct __kernel_timex *txc)
 {
        struct timekeeper *tk = &tk_core.timekeeper;
        unsigned long flags;