]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
sched_getattr: port to copy_struct_to_user
authorAleksa Sarai <cyphar@cyphar.com>
Wed, 9 Oct 2024 20:40:35 +0000 (07:40 +1100)
committerChristian Brauner <brauner@kernel.org>
Mon, 21 Oct 2024 14:51:31 +0000 (16:51 +0200)
sched_getattr(2) doesn't care about trailing non-zero bytes in the
(ksize > usize) case, so just use copy_struct_to_user() without checking
ignored_trailing.

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
Link: https://lore.kernel.org/r/20241010-extensible-structs-check_fields-v3-2-d2833dfe6edd@cyphar.com
Signed-off-by: Christian Brauner <brauner@kernel.org>
kernel/sched/syscalls.c

index aa70beee9895de48685ac22ba48b97b706c5e395..a168d614fddbb16dd25b7481f0bf52e1b576c63a 100644 (file)
@@ -1076,45 +1076,6 @@ SYSCALL_DEFINE2(sched_getparam, pid_t, pid, struct sched_param __user *, param)
        return copy_to_user(param, &lp, sizeof(*param)) ? -EFAULT : 0;
 }
 
-/*
- * Copy the kernel size attribute structure (which might be larger
- * than what user-space knows about) to user-space.
- *
- * Note that all cases are valid: user-space buffer can be larger or
- * smaller than the kernel-space buffer. The usual case is that both
- * have the same size.
- */
-static int
-sched_attr_copy_to_user(struct sched_attr __user *uattr,
-                       struct sched_attr *kattr,
-                       unsigned int usize)
-{
-       unsigned int ksize = sizeof(*kattr);
-
-       if (!access_ok(uattr, usize))
-               return -EFAULT;
-
-       /*
-        * sched_getattr() ABI forwards and backwards compatibility:
-        *
-        * If usize == ksize then we just copy everything to user-space and all is good.
-        *
-        * If usize < ksize then we only copy as much as user-space has space for,
-        * this keeps ABI compatibility as well. We skip the rest.
-        *
-        * If usize > ksize then user-space is using a newer version of the ABI,
-        * which part the kernel doesn't know about. Just ignore it - tooling can
-        * detect the kernel's knowledge of attributes from the attr->size value
-        * which is set to ksize in this case.
-        */
-       kattr->size = min(usize, ksize);
-
-       if (copy_to_user(uattr, kattr, kattr->size))
-               return -EFAULT;
-
-       return 0;
-}
-
 /**
  * sys_sched_getattr - similar to sched_getparam, but with sched_attr
  * @pid: the pid in question.
@@ -1159,7 +1120,8 @@ SYSCALL_DEFINE4(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr,
 #endif
        }
 
-       return sched_attr_copy_to_user(uattr, &kattr, usize);
+       kattr.size = min(usize, sizeof(kattr));
+       return copy_struct_to_user(uattr, usize, &kattr, sizeof(kattr), NULL);
 }
 
 #ifdef CONFIG_SMP