summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinmao Li <lilinmao@kylinos.cn>2026-07-16 09:39:23 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-17 15:53:18 +0200
commit3c0cf801ea2fa40daa5e7d1e6d32adca5ff75ad9 (patch)
tree6284404be23e2f1f1d8396b17895d8858f785ad3
parent274259391c14166fcabae74f9fc0104223ff27a1 (diff)
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: 3b9ab374a1e6 ("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>
-rw-r--r--drivers/char/ppdev.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index 6da817b9849f..8803268b4cdc 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -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;