sched_getattr: port to copy_struct_to_user
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>
This commit is contained in:
committed by
Christian Brauner
parent
424a55a4a9
commit
112cca098a
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user