mirror-linux/fs
Breno Leitao 859c199bb3
fs/select: reject negative timeval components in kern_select()
kern_select() normalises the user-supplied struct __kernel_old_timeval
with

	tv.tv_sec + (tv.tv_usec / USEC_PER_SEC)
	(tv.tv_usec % USEC_PER_SEC) * NSEC_PER_USEC

before calling poll_select_set_timeout() -> timespec64_valid().  Both
operands of the seconds sum are unbounded user-controlled signed long.
A crafted pair where tv_usec is a negative multiple of USEC_PER_SEC
drives the sum across the wrap boundary - e.g.

	{ .tv_sec = LONG_MIN, .tv_usec = -1000000 }

yields sec = LONG_MAX, nsec = 0, which passes timespec64_valid() and
then flows through timespec64_add_safe(), which saturates the absolute
deadline to TIME64_MAX (clamped further to KTIME_MAX downstream).
select(2) therefore blocks effectively forever instead of returning
-EINVAL as POSIX requires for a negative timeout.

Only the legacy __NR_select syscall takes this path.  pselect6, ppoll,
poll and epoll_pwait2 all hand the user's two fields directly to
poll_select_set_timeout(), which validates *before* doing any
arithmetic:

	/* fs/select.c:271 -- the validator */
	int poll_select_set_timeout(struct timespec64 *to, time64_t sec, long nsec)
	{
		struct timespec64 ts = {.tv_sec = sec, .tv_nsec = nsec};
		if (!timespec64_valid(&ts))
			return -EINVAL;
		...
	}

	/* include/linux/time64.h:97 -- timespec64_valid */
	if (ts->tv_sec < 0)                              return false;
	if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC)  return false;

	/* fs/select.c:744  do_pselect() (pselect6, pselect6_time32) */
	if (get_timespec64(&ts, tsp)) return -EFAULT;
	if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec)) return -EINVAL;

	/* fs/select.c:1097 ppoll */
	if (get_timespec64(&ts, tsp)) return -EFAULT;
	if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec)) return -EINVAL;

	/* fs/select.c:1065 poll -- timeout_msecs is int; >= 0 gates the math */
	if (timeout_msecs >= 0)
		poll_select_set_timeout(to, timeout_msecs / MSEC_PER_SEC,
		                        NSEC_PER_MSEC * (timeout_msecs % MSEC_PER_SEC));

	/* fs/eventpoll.c:2512 epoll_pwait2 */
	if (get_timespec64(&ts, timeout)) return -EFAULT;
	if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec)) return -EINVAL;

In every one of these the wrap-prone arithmetic from kern_select()
simply does not exist; the user fields reach timespec64_valid()
unmodified.  glibc routes the C-library select() through pselect6,
so the bug is reachable only via a direct syscall(__NR_select, ...).

The pre-validation negative check that used to live here was lost
when the syscall was switched to the poll_select_set_timeout() helper.
Restore it: reject tv_sec < 0 || tv_usec < 0 up front, mirroring what
glibc does in userspace.  do_compat_select() has the same arithmetic
pattern but is only reachable on 32-bit compat and from a different
syscall entry; left for a follow-up so this change stays minimal.

Reproducer (returns -1/EINVAL on a fixed kernel; blocks indefinitely
on an unfixed one):

	struct timeval tv = { .tv_sec = LONG_MIN, .tv_usec = -1000000 };
	fd_set r;
	int pfd[2];
	pipe(pfd);
	FD_ZERO(&r);
	FD_SET(pfd[0], &r);
	syscall(__NR_select, pfd[0] + 1, &r, NULL, NULL, &tv);

Fixes: 4d36a9e65d ("select: deal with math overflow from borderline valid userland data")
Signed-off-by: Breno Leitao <leitao@debian.org>
Link: https://patch.msgid.link/20260429-timeval-v1-1-4448e2588bbf@debian.org
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-05-12 14:41:40 +02:00
..
9p - 9p access flag fix (cannot change access flag since new mount API implem) 2026-04-24 13:37:26 -07:00
adfs ARM development for 7.1-rc1 2026-04-25 07:44:26 -07:00
affs Fixing livelocks in shrink_dcache_tree() 2026-04-21 07:30:44 -07:00
afs mm.git review status for linus..mm-stable 2026-04-15 12:59:16 -07:00
autofs vfs-7.1-rc1.misc 2026-04-13 14:20:11 -07:00
befs treewide: change inode->i_ino from unsigned long to u64 2026-03-06 14:31:28 +01:00
bfs vfs-7.1-rc1.bh.metadata 2026-04-13 12:46:42 -07:00
btrfs for-7.1-rc1-tag 2026-04-27 16:35:44 -07:00
cachefiles vfs-7.1-rc1.kino 2026-04-13 12:19:01 -07:00
ceph We have a series from Alex which extends CephFS client metrics with 2026-04-24 13:47:19 -07:00
coda coda cleanups and fixes 2026-04-21 14:03:10 -07:00
configfs Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
cramfs treewide: change inode->i_ino from unsigned long to u64 2026-03-06 14:31:28 +01:00
crypto fscrypt updates for 7.1 2026-04-13 17:29:12 -07:00
debugfs debugfs: fix placement of EXPORT_SYMBOL_GPL for debugfs_create_str() 2026-04-02 16:15:23 +02:00
devpts Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
dlm ipv6: convert CONFIG_IPV6 to built-in only and clean up Kconfigs 2026-03-29 11:21:22 -07:00
ecryptfs eCryptfs changes for 7.1-rc1 2026-04-20 10:54:17 -07:00
efivarfs efivarfs: use QSTR() in efivarfs_alloc_dentry 2026-04-28 12:30:59 +02:00
efs treewide: change inode->i_ino from unsigned long to u64 2026-03-06 14:31:28 +01:00
erofs Changes since the last update: 2026-04-21 11:16:04 -07:00
exfat Description for this pull request: 2026-04-13 16:57:31 -07:00
exportfs Fixing livelocks in shrink_dcache_tree() 2026-04-21 07:30:44 -07:00
ext2 \n 2026-04-15 19:22:16 -07:00
ext4 Various clean ups and bug fixes in ext4 for 7.1: 2026-04-17 17:08:31 -07:00
f2fs f2fs-for-7.1-rc1 2026-04-21 14:50:04 -07:00
fat vfs-7.1-rc1.bh.metadata 2026-04-13 12:46:42 -07:00
freevxfs treewide: change inode->i_ino from unsigned long to u64 2026-03-06 14:31:28 +01:00
fuse fuse: fix writeback array overflow when max_pages is one 2026-05-11 14:19:01 +02:00
gfs2 gfs2 changes 2026-04-15 19:12:04 -07:00
hfs vfs-7.1-rc1.misc 2026-04-13 14:20:11 -07:00
hfsplus hfs/hfsplus updates for v7.1 2026-04-13 16:50:38 -07:00
hostfs Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
hpfs treewide: change inode->i_ino from unsigned long to u64 2026-03-06 14:31:28 +01:00
hugetlbfs mm.git review status for linus..mm-stable 2026-04-15 12:59:16 -07:00
iomap fscrypt updates for 7.1 2026-04-13 17:29:12 -07:00
isofs isofs: use QSTR_LEN() in isofs_cmp 2026-04-20 17:27:28 +02:00
jbd2 Various clean ups and bug fixes in ext4 for 7.1: 2026-04-17 17:08:31 -07:00
jffs2 treewide: change inode->i_ino from unsigned long to u64 2026-03-06 14:31:28 +01:00
jfs fs: Fix return in jfs_mkdir and orangefs_mkdir 2026-05-11 14:19:01 +02:00
kernfs Driver core changes for 7.1-rc1 2026-04-13 19:03:11 -07:00
lockd NFSD 7.1 Release Notes 2026-04-20 10:44:02 -07:00
minix vfs-7.1-rc1.bh.metadata 2026-04-13 12:46:42 -07:00
netfs mm.git review status for linus..mm-stable 2026-04-15 12:59:16 -07:00
nfs NFS client updates for Linux 7.1 2026-04-24 14:20:03 -07:00
nfs_common NFSD: Remove NFSERR_EAGAIN 2026-01-02 13:43:41 -05:00
nfsd NFSD 7.1 Release Notes 2026-04-20 10:44:02 -07:00
nilfs2 mm.git review status for linus..mm-stable 2026-04-15 12:59:16 -07:00
nls fs/nls: Fix inconsistency between utf8_to_utf32() and utf32_to_utf8() 2025-12-01 11:58:06 +02:00
notify \n 2026-04-27 16:40:24 -07:00
ntfs ntfs: Use return instead of goto in ntfs_mapping_pairs_decompress() 2026-04-30 07:05:48 +09:00
ntfs3 Changes for 7.1-rc1 2026-04-20 10:59:47 -07:00
ocfs2 Fixing livelocks in shrink_dcache_tree() 2026-04-21 07:30:44 -07:00
omfs vfs-7.1-rc1.misc 2026-04-13 14:20:11 -07:00
openpromfs
orangefs fs: Fix return in jfs_mkdir and orangefs_mkdir 2026-05-11 14:19:01 +02:00
overlayfs ovl: fix verity lazy-load guard broken by fsverity_active() semantic change 2026-05-06 08:37:30 -07:00
proc mm.git review status for linus..mm-nonmm-stable 2026-04-16 20:11:56 -07:00
pstore mm.git review status for linus..mm-stable 2026-04-15 12:59:16 -07:00
qnx4 vfs-7.1-rc1.bh.metadata 2026-04-13 12:46:42 -07:00
qnx6 vfs-7.1-rc1.bh.metadata 2026-04-13 12:46:42 -07:00
quota quota: Fix race of dquot_scan_active() with quota deactivation 2026-03-25 13:15:36 +01:00
ramfs folio_batch: rename pagevec.h to folio_batch.h 2026-04-05 13:53:07 -07:00
resctrl mm.git review status for linus..mm-stable 2026-04-15 12:59:16 -07:00
romfs mm.git review status for linus..mm-stable 2026-02-18 20:50:32 -08:00
smb seven client fixes 2026-05-08 10:24:35 -07:00
squashfs Squashfs: check metadata block offset is within range 2026-02-24 11:13:27 -08:00
sysfs Driver core fixes for 7.1-rc1 2026-04-19 12:58:08 -07:00
tests fs/tests: exec: Remove bad test vector 2026-03-18 11:41:53 -07:00
tracefs tracefs fixes for v7.1: 2026-04-22 15:09:01 -07:00
ubifs mm.git review status for linus..mm-nonmm-stable 2026-04-16 20:11:56 -07:00
udf udf: reject descriptors with oversized CRC length 2026-04-22 17:14:48 +02:00
ufs vfs-7.1-rc1.bh.metadata 2026-04-13 12:46:42 -07:00
unicode Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
vboxsf Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
verity vfs-7.1-rc1.kino 2026-04-13 12:19:01 -07:00
xfs xfs: new code for Linux 7.1 2026-04-13 17:03:48 -07:00
zonefs mm.git review status for linus..mm-stable 2026-04-15 12:59:16 -07:00
Kconfig ntfs: add Kconfig and Makefile 2026-02-19 21:51:00 +09:00
Kconfig.binfmt
Makefile ntfs: add Kconfig and Makefile 2026-02-19 21:51:00 +09:00
aio.c fs: aio: reject partial mremap to avoid Null-pointer-dereference error 2026-04-24 00:34:59 +02:00
anon_inodes.c anon_inodes: convert to FD_ADD() 2025-11-28 12:42:31 +01:00
attr.c fs: attr: fix comment formatting and spelling issues 2026-04-07 11:26:11 +02:00
backing-file.c lsm: add backing_file LSM hooks 2026-04-03 16:53:50 -04:00
bad_inode.c fs: refactor ->update_time handling 2026-01-12 14:01:32 +01:00
binfmt_elf.c mm: unexport vm_brk_flags() and eliminate vm_flags parameter 2026-04-05 13:53:39 -07:00
binfmt_elf_fdpic.c vfs-7.1-rc1.kino 2026-04-13 12:19:01 -07:00
binfmt_flat.c
binfmt_misc.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
binfmt_script.c
bpf_fs_kfuncs.c bpf: Remove redundant KF_TRUSTED_ARGS flag from all kfuncs 2026-01-02 12:04:28 -08:00
buffer.c vfs-7.1-rc1.fixes 2026-04-23 17:08:04 -07:00
char_dev.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
compat_binfmt_elf.c
coredump.c vfs-7.1-rc1.misc 2026-04-13 14:20:11 -07:00
d_path.c dcache: permit dynamic_dname()s up to NAME_MAX 2026-04-07 12:32:22 +02:00
dax.c dax changes for 7.1 2026-04-21 14:12:01 -07:00
dcache.c Fixing livelocks in shrink_dcache_tree() 2026-04-21 07:30:44 -07:00
direct-io.c
drop_caches.c
eventfd.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
eventpoll.c eventpoll: drop vestigial epi->dying flag 2026-04-24 00:37:01 +02:00
exec.c exec: use strnlen() in __set_task_comm 2026-04-01 12:26:07 -07:00
fcntl.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
fhandle.c Convert more 'alloc_obj' cases to default GFP_KERNEL arguments 2026-02-21 20:03:00 -08:00
file.c vfs-7.1-rc1.misc 2026-04-13 14:20:11 -07:00
file_attr.c vfs-7.0-rc2.fixes 2026-02-25 10:34:23 -08:00
file_table.c lsm/stable-7.1 PR 20260410 2026-04-13 15:17:28 -07:00
filesystems.c sysfs(2): fs_index() argument is _not_ a pathname 2026-01-16 12:52:04 -05:00
fs-writeback.c vfs-7.1-rc1.fixes 2026-04-23 17:08:04 -07:00
fs_context.c vfs-7.1-rc1.misc 2026-04-13 14:20:11 -07:00
fs_dirent.c
fs_parser.c fs: remove fsparam_path / fs_param_is_path 2026-02-19 14:34:26 +01:00
fs_pin.c
fs_struct.c fs: add <linux/init_task.h> for 'init_fs' 2026-01-14 16:50:37 +01:00
fserror.c treewide: change inode->i_ino from unsigned long to u64 2026-03-06 14:31:28 +01:00
fsopen.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
init.c struct filename series 2026-02-09 16:58:28 -08:00
inode.c fs: fix forced iversion increment on lazytime timestamp updates 2026-05-11 15:32:12 +02:00
internal.h lsm/stable-7.1 PR 20260410 2026-04-13 15:17:28 -07:00
ioctl.c
kernel_read_file.c
libfs.c vfs-7.1-rc1.bh.metadata 2026-04-13 12:46:42 -07:00
locks.c NFSD 7.1 Release Notes 2026-04-20 10:44:02 -07:00
mbcache.c vfs-7.1-rc1.misc 2026-04-13 14:20:11 -07:00
mnt_idmapping.c fs/statmount: fix slab out-of-bounds write in statmount_mnt_idmap 2026-05-11 14:19:01 +02:00
mount.h fs: add immutable rootfs 2026-01-12 16:52:09 +01:00
mpage.c mm.git review status for linus..mm-stable 2026-04-15 12:59:16 -07:00
namei.c vfs-7.1-rc1.misc 2026-04-13 14:20:11 -07:00
namespace.c mount: always duplicate mount 2026-04-14 09:30:15 +02:00
nsfs.c nsfs: fix wrong error code returned for pidns ioctls 2026-05-11 15:59:14 +02:00
nullfs.c fs: add immutable rootfs 2026-01-12 16:52:09 +01:00
open.c fs: remove do_sys_truncate 2026-03-23 12:41:58 +01:00
pidfs.c vfs-7.1-rc1.pidfs 2026-04-13 13:27:11 -07:00
pipe.c treewide: change inode->i_ino from unsigned long to u64 2026-03-06 14:31:28 +01:00
pnode.c
pnode.h
posix_acl.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
proc_namespace.c
read_write.c fs: add setlease to generic_ro_fops and read-only filesystem directory operations 2026-01-12 10:55:45 +01:00
readdir.c fs: Replace user_access_{begin/end} by scoped user access 2026-03-24 14:44:02 +01:00
remap_range.c
select.c fs/select: reject negative timeval components in kern_select() 2026-05-12 14:41:40 +02:00
seq_file.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
signalfd.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
splice.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
stack.c
stat.c statx: switch to CLASS(filename_maybe_null) 2026-01-16 12:52:04 -05:00
statfs.c user_statfs(): switch to CLASS(filename) 2026-01-16 12:52:04 -05:00
super.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
sync.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
sysctls.c
timerfd.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
userfaultfd.c userfaultfd: allow registration of ranges below mmap_min_addr 2026-04-18 00:10:56 -07:00
utimes.c do_utimes_path(): switch to CLASS(filename_uflags) 2026-01-16 12:52:03 -05:00
xattr.c xattr: support extended attributes on sockets 2026-03-02 11:06:42 +01:00