[merged mm-nonmm-stable] pps-dont-try-to-wait-for-negative-timeouts-in-pps_fetch.patch removed from -mm tree
Andrew Morton <[email protected]> Mon, 03 Aug 2026 21:05:07 -0700
| Newsgroups | org.kernel.vger.mm-commits |
|---|---|
| Message-ID | <[email protected]> |
The quilt patch titled
Subject: pps: don't try to wait for negative timeouts in PPS_FETCH
has been removed from the -mm tree. Its filename was
pps-dont-try-to-wait-for-negative-timeouts-in-pps_fetch.patch
This patch was dropped because it was merged into the mm-nonmm-stable branch
of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
------------------------------------------------------
From: Calvin Owens <[email protected]>
Subject: pps: don't try to wait for negative timeouts in PPS_FETCH
Date: Fri, 12 Jun 2026 11:52:09 -0700
If userspace passes a negative timeout to PPS_FETCH, it triggers a kernel
splat from schedule_timeout():
schedule_timeout: wrong timeout value fffffffffff0bfb4
CPU: 17 UID: 0 PID: 4720 Comm: a.out Not tainted 7.1.0-rc5-x86-kvm-00150-g331d97e36b37 #1 PREEMPT_RT
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-20240910_120124-localhost 04/01/2014
Call Trace:
<TASK>
dump_stack_lvl+0x4b/0x70
schedule_timeout+0xb7/0xe0
pps_cdev_pps_fetch.isra.0+0x93/0x150
pps_cdev_ioctl+0x70/0x310
__x64_sys_ioctl+0x7b/0xc0
do_syscall_64+0xb6/0xfc0
entry_SYSCALL_64_after_hwframe+0x4b/0x53
Here is a trivial reproducer that works with the PPS_CLIENT_KTIMER test
device enabled in the kernel:
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/pps.h>
#include <err.h>
int main() {
struct pps_fdata fdata;
int fd;
fd = open("/dev/pps0", O_RDWR);
if (fd == -1)
err(1, "Failed to open /dev/pps0");
fdata.timeout.sec = -1;
fdata.timeout.nsec = 0;
if (ioctl(fd, PPS_FETCH, &fdata))
err(2, "PPS_FETCH failed");
close(fd);
return 0;
}
Sashiko imagines this to be some sort of security problem, which is
obviously really silly. But I think it is still worth fixing, so buggy
userspace code can't trigger the splat.
Silence the splat by using timespec64_to_jiffies(), which hard limits the
timeout to LONG_MAX jiffies. To be safe, explicitly preserve the
-ETIMEDOUT return value userspace sees today if it passes a negative
timeout.
If you really squint, this is still a slight behavior change in that there
are "denormalized" combinations of tv_sec and tv_nsec which used to work
but will now return -ETIMEDOUT. I can't imagine anybody will care about
that...
Link: https://lore.kernel.org/c5c97c3b3c9d66010382094fd538e59a38f4aacf.1781289959.git.calvin@wbinvd.org
Fixes: eae9d2ba0cfc ("LinuxPPS: core support")
Signed-off-by: Calvin Owens <[email protected]>
Reported-by: Sashiko <[email protected]>
Closes: https://sashiko.dev/#/patchset/cover.1779733602.git.calvin%40wbinvd.org?part=3
Acked-by: Rodolfo Giometti <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
---
drivers/pps/pps.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
--- a/drivers/pps/pps.c~pps-dont-try-to-wait-for-negative-timeouts-in-pps_fetch
+++ a/drivers/pps/pps.c
@@ -66,13 +66,19 @@ static int pps_cdev_pps_fetch(struct pps
err = wait_event_interruptible(pps->queue,
ev != pps->last_ev);
else {
+ struct timespec64 ts;
unsigned long ticks;
dev_dbg(&pps->dev, "timeout %lld.%09d\n",
(long long) fdata->timeout.sec,
fdata->timeout.nsec);
- ticks = fdata->timeout.sec * HZ;
- ticks += fdata->timeout.nsec / (NSEC_PER_SEC / HZ);
+
+ if (fdata->timeout.sec < 0)
+ return -ETIMEDOUT;
+
+ ts.tv_sec = fdata->timeout.sec;
+ ts.tv_nsec = fdata->timeout.nsec;
+ ticks = timespec64_to_jiffies(&ts);
if (ticks != 0) {
err = wait_event_interruptible_timeout(
_
Patches currently in -mm which might be from [email protected] are