ppdev: prevent overflow when setting port timeout

PPSETTIME64 supplies the timeval fields as s64 values, but
pp_set_timeout() narrows tv_usec to int and calculates tv_sec * HZ in a
signed long. Large positive values can therefore be truncated or overflow
and install an unintended timeout.

Keep both fields as s64, reject a non-canonical microsecond value, and
use timespec64_to_jiffies() to cap excessively large timeouts at
MAX_JIFFY_OFFSET. This is a behavior change because both PPSETTIME
ioctls could previously accept values with tv_usec >= USEC_PER_SEC.
The validation follows the precedent set by sock_set_timeout().

Fixes: 3b9ab374a1 ("ppdev: convert to y2038 safe")
Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Link: https://patch.msgid.link/20260716013923.19494-1-lilinmao@kylinos.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Linmao Li
2026-07-17 15:53:18 +02:00
committed by Greg Kroah-Hartman
parent 274259391c
commit 3c0cf801ea
+6 -4
View File
@@ -340,15 +340,17 @@ static enum ieee1284_phase init_phase(int mode)
return IEEE1284_PH_FWD_IDLE;
}
static int pp_set_timeout(struct pardevice *pdev, long tv_sec, int tv_usec)
static int pp_set_timeout(struct pardevice *pdev, s64 tv_sec, s64 tv_usec)
{
struct timespec64 ts;
long to_jiffies;
if ((tv_sec < 0) || (tv_usec < 0))
if (tv_sec < 0 || tv_usec < 0 || tv_usec >= USEC_PER_SEC)
return -EINVAL;
to_jiffies = usecs_to_jiffies(tv_usec);
to_jiffies += tv_sec * HZ;
ts.tv_sec = tv_sec;
ts.tv_nsec = tv_usec * NSEC_PER_USEC;
to_jiffies = timespec64_to_jiffies(&ts);
if (to_jiffies <= 0)
return -EINVAL;