]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
select: store end_time as timespec64 in restart block
authorThomas Weißschuh <thomas.weissschuh@linutronix.de>
Tue, 23 Dec 2025 07:00:39 +0000 (08:00 +0100)
committerChristian Brauner <brauner@kernel.org>
Wed, 24 Dec 2025 13:01:57 +0000 (14:01 +0100)
Storing the end time seconds as 'unsigned long' can lead to truncation
on 32-bit architectures if assigned from the 64-bit timespec64::tv_sec.
As the select() core uses timespec64 consistently, also use that in the
restart block.

This also allows the simplification of the accessors.

Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Link: https://patch.msgid.link/20251223-restart-block-expiration-v2-1-8e33e5df7359@linutronix.de
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/select.c
include/linux/restart_block.h

index 65019b8ba3f74b6741f8af01a1221d912325e955..78a1508c84d3d7a0a78d7b21058e1f4d3912772c 100644 (file)
@@ -1038,14 +1038,11 @@ static long do_restart_poll(struct restart_block *restart_block)
 {
        struct pollfd __user *ufds = restart_block->poll.ufds;
        int nfds = restart_block->poll.nfds;
-       struct timespec64 *to = NULL, end_time;
+       struct timespec64 *to = NULL;
        int ret;
 
-       if (restart_block->poll.has_timeout) {
-               end_time.tv_sec = restart_block->poll.tv_sec;
-               end_time.tv_nsec = restart_block->poll.tv_nsec;
-               to = &end_time;
-       }
+       if (restart_block->poll.has_timeout)
+               to = &restart_block->poll.end_time;
 
        ret = do_sys_poll(ufds, nfds, to);
 
@@ -1077,8 +1074,7 @@ SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds,
                restart_block->poll.nfds = nfds;
 
                if (timeout_msecs >= 0) {
-                       restart_block->poll.tv_sec = end_time.tv_sec;
-                       restart_block->poll.tv_nsec = end_time.tv_nsec;
+                       restart_block->poll.end_time = end_time;
                        restart_block->poll.has_timeout = 1;
                } else
                        restart_block->poll.has_timeout = 0;
index 67d2bf5799428d4c12a0db171ecf5f42ceb8445a..9b262109726d25ca1d7871d916280a7bf336355a 100644 (file)
@@ -6,6 +6,7 @@
 #define __LINUX_RESTART_BLOCK_H
 
 #include <linux/compiler.h>
+#include <linux/time64.h>
 #include <linux/types.h>
 
 struct __kernel_timespec;
@@ -50,8 +51,7 @@ struct restart_block {
                        struct pollfd __user *ufds;
                        int nfds;
                        int has_timeout;
-                       unsigned long tv_sec;
-                       unsigned long tv_nsec;
+                       struct timespec64 end_time;
                } poll;
        };
 };