public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ptp: Limit time setting of PTP clocks
@ 2024-09-09 13:09 Miroslav Lichvar
  2024-09-09 15:48 ` Richard Cochran
  0 siblings, 1 reply; 3+ messages in thread
From: Miroslav Lichvar @ 2024-09-09 13:09 UTC (permalink / raw)
  To: linux-kernel
  Cc: Miroslav Lichvar, Richard Cochran, Thomas Gleixner, John Stultz,
	Arnd Bergmann

Networking drivers implementing PTP clocks and kernel socket code
handling hardware timestamps use the 64-bit signed ktime_t type counting
nanoseconds. When a PTP clock reaches the maximum value in year 2262,
the timestamps returned to applications will overflow into year 1667.
The same thing happens when injecting a large offset with
clock_adjtime(ADJ_SETOFFSET).

The commit 7a8e61f84786 ("timekeeping: Force upper bound for setting
CLOCK_REALTIME") limited the maximum accepted value setting the system
clock to 30 years before the maximum representable value (i.e. year
2232) to avoid the overflow, assuming the system will not run for more
than 30 years.

Enforce the same limit for PTP clocks. Don't allow negative values and
values closer than 30 years to the maximum value. Drivers may implement
an even lower limit if the hardware registers cannot represent the whole
interval between years 1970 and 2262 in the required resolution.

Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: John Stultz <jstultz@google.com>
Cc: Arnd Bergmann <arnd@arndb.de>
---
 drivers/ptp/ptp_clock.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c
index c56cd0f63909..bd7c5f534be6 100644
--- a/drivers/ptp/ptp_clock.c
+++ b/drivers/ptp/ptp_clock.c
@@ -100,6 +100,9 @@ static int ptp_clock_settime(struct posix_clock *pc, const struct timespec64 *tp
 		return -EBUSY;
 	}
 
+	if (!timespec64_valid_settod(tp))
+		return -EINVAL;
+
 	return  ptp->info->settime64(ptp->info, tp);
 }
 
@@ -129,7 +132,7 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct __kernel_timex *tx)
 	ops = ptp->info;
 
 	if (tx->modes & ADJ_SETOFFSET) {
-		struct timespec64 ts;
+		struct timespec64 ts, ts2;
 		ktime_t kt;
 		s64 delta;
 
@@ -139,7 +142,14 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct __kernel_timex *tx)
 		if (!(tx->modes & ADJ_NANO))
 			ts.tv_nsec *= 1000;
 
-		if ((unsigned long) ts.tv_nsec >= NSEC_PER_SEC)
+		/* Make sure the offset is valid */
+		err = ptp_clock_gettime(pc, &ts2);
+		if (err)
+			return err;
+		ts2 = timespec64_add(ts2, ts);
+
+		if ((unsigned long) ts.tv_nsec >= NSEC_PER_SEC ||
+		    !timespec64_valid_settod(&ts2))
 			return -EINVAL;
 
 		kt = timespec64_to_ktime(ts);
-- 
2.46.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] ptp: Limit time setting of PTP clocks
  2024-09-09 13:09 [PATCH] ptp: Limit time setting of PTP clocks Miroslav Lichvar
@ 2024-09-09 15:48 ` Richard Cochran
  2024-09-10 12:00   ` Miroslav Lichvar
  0 siblings, 1 reply; 3+ messages in thread
From: Richard Cochran @ 2024-09-09 15:48 UTC (permalink / raw)
  To: Miroslav Lichvar
  Cc: linux-kernel, Thomas Gleixner, John Stultz, Arnd Bergmann


> diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c
> index c56cd0f63909..bd7c5f534be6 100644
> --- a/drivers/ptp/ptp_clock.c
> +++ b/drivers/ptp/ptp_clock.c
> @@ -100,6 +100,9 @@ static int ptp_clock_settime(struct posix_clock *pc, const struct timespec64 *tp
>  		return -EBUSY;
>  	}
>  
> +	if (!timespec64_valid_settod(tp))
> +		return -EINVAL;

Why not perform the test earlier, in SYSCALL_DEFINE2(clock_settime, ...) ?

Thanks,
Richard

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] ptp: Limit time setting of PTP clocks
  2024-09-09 15:48 ` Richard Cochran
@ 2024-09-10 12:00   ` Miroslav Lichvar
  0 siblings, 0 replies; 3+ messages in thread
From: Miroslav Lichvar @ 2024-09-10 12:00 UTC (permalink / raw)
  To: Richard Cochran; +Cc: linux-kernel, Thomas Gleixner, John Stultz, Arnd Bergmann

On Mon, Sep 09, 2024 at 08:48:24AM -0700, Richard Cochran wrote:
> > diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c
> > index c56cd0f63909..bd7c5f534be6 100644
> > --- a/drivers/ptp/ptp_clock.c
> > +++ b/drivers/ptp/ptp_clock.c
> > @@ -100,6 +100,9 @@ static int ptp_clock_settime(struct posix_clock *pc, const struct timespec64 *tp
> >  		return -EBUSY;
> >  	}
> >  
> > +	if (!timespec64_valid_settod(tp))
> > +		return -EINVAL;
> 
> Why not perform the test earlier, in SYSCALL_DEFINE2(clock_settime, ...) ?

It would be more code as there are also the 32-bit compat variants of
the functions. The adjtime function would probably need to handle
missing gettime.

The limit would apply to all clocks, not just PTP clocks. If nothing
else, I suspect it would change returned errors for other clocks
trying to set the an unacceptable timespec value.

-- 
Miroslav Lichvar


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-09-10 12:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-09 13:09 [PATCH] ptp: Limit time setting of PTP clocks Miroslav Lichvar
2024-09-09 15:48 ` Richard Cochran
2024-09-10 12:00   ` Miroslav Lichvar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox