Message ID | 20240914100625.414013-2-ruanjinjie@huawei.com (mailing list archive) |
---|---|
State | Deferred |
Headers | show |
Series | posix-clock: Check timespec64 for PTP clock | expand |
On Sat, Sep 14, 2024 at 06:06:24PM +0800, Jinjie Ruan wrote: > As Andrew pointed out, it will make sense that the PTP core > checked timespec64 struct's tv_sec and tv_nsec range before calling > ptp->info->settime64(). > > As the man mannul of clock_settime() said, if tp.tv_sec is negative or > tp.tv_nsec is outside the range [0..999,999,999], it shuld return EINVAL, nit: should Flagged by checkpatch.pl --codespell ...
On Sat, Sep 14 2024 at 16:23, Simon Horman wrote: > On Sat, Sep 14, 2024 at 06:06:24PM +0800, Jinjie Ruan wrote: >> As Andrew pointed out, it will make sense that the PTP core >> checked timespec64 struct's tv_sec and tv_nsec range before calling >> ptp->info->settime64(). >> >> As the man mannul of clock_settime() said, if tp.tv_sec is negative or >> tp.tv_nsec is outside the range [0..999,999,999], it shuld return EINVAL, > > nit: should > > Flagged by checkpatch.pl --codespell ... man mannul Flagged by my taste sensors.
On Sat, Sep 14 2024 at 18:06, Jinjie Ruan wrote: > As Andrew pointed out, it will make sense that the PTP core > checked timespec64 struct's tv_sec and tv_nsec range before calling > ptp->info->settime64(). > > As the man mannul of clock_settime() said, if tp.tv_sec is negative or > tp.tv_nsec is outside the range [0..999,999,999], it shuld return EINVAL, > which include Dynamic clocks which handles PTP clock, and the condition is > consistent with timespec64_valid(). So check it ahead using > timespec64_valid() in pc_clock_settime() and return -EINVAL if not valid. > > There are some drivers that use tp->tv_sec and tp->tv_nsec directly to > write registers without validity checks and assume that the higher layer > has checked it, which is dangerous and will benefit from this, such as > hclge_ptp_settime(), igb_ptp_settime_i210(), _rcar_gen4_ptp_settime(), > and some drivers can remove the checks of itself. > + if (!timespec64_valid(ts)) > + return -EINVAL; This just makes sure, that the timespec is valid. But it does not ensure that the time is in a valid range. This should at least use timespec64_valid_strict() if not timespec64_valid_gettod(). Thanks, tglx
diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c index 4782edcbe7b9..89e39f9bd7ae 100644 --- a/kernel/time/posix-clock.c +++ b/kernel/time/posix-clock.c @@ -319,6 +319,9 @@ static int pc_clock_settime(clockid_t id, const struct timespec64 *ts) goto out; } + if (!timespec64_valid(ts)) + return -EINVAL; + if (cd.clk->ops.clock_settime) err = cd.clk->ops.clock_settime(cd.clk, ts); else
As Andrew pointed out, it will make sense that the PTP core checked timespec64 struct's tv_sec and tv_nsec range before calling ptp->info->settime64(). As the man mannul of clock_settime() said, if tp.tv_sec is negative or tp.tv_nsec is outside the range [0..999,999,999], it shuld return EINVAL, which include Dynamic clocks which handles PTP clock, and the condition is consistent with timespec64_valid(). So check it ahead using timespec64_valid() in pc_clock_settime() and return -EINVAL if not valid. There are some drivers that use tp->tv_sec and tp->tv_nsec directly to write registers without validity checks and assume that the higher layer has checked it, which is dangerous and will benefit from this, such as hclge_ptp_settime(), igb_ptp_settime_i210(), _rcar_gen4_ptp_settime(), and some drivers can remove the checks of itself. Suggested-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com> --- v4: - Check it in pc_clock_settime(). - Update the commit message. v3: - Adjust to check in more higher layer clock_settime(). - Remove the NULL check. - Update the commit message and subject. v2: - Adjust to check in ptp_clock_settime(). --- kernel/time/posix-clock.c | 3 +++ 1 file changed, 3 insertions(+)