Skip to content

Commit dff3a85

Browse files
cypharChristian Brauner
authored andcommitted
sched_setattr: switch to copy_struct_from_user()
Switch sched_setattr() syscall from it's own copying struct sched_attr from userspace to the new dedicated copy_struct_from_user() helper. The change is very straightforward, and helps unify the syscall interface for struct-from-userspace syscalls. Ideally we could also unify sched_getattr(2)-style syscalls as well, but unfortunately the correct semantics for such syscalls are much less clear (see [1] for more detail). In future we could come up with a more sane idea for how the syscall interface should look. [1]: commit 1251201 ("sched/core: Fix uclamp ABI bug, clean up and robustify sched_read_attr() ABI logic and code") Signed-off-by: Aleksa Sarai <[email protected]> Reviewed-by: Kees Cook <[email protected]> Reviewed-by: Christian Brauner <[email protected]> [[email protected]: improve commit message] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Christian Brauner <[email protected]>
1 parent f14c234 commit dff3a85

File tree

1 file changed

+7
-36
lines changed

1 file changed

+7
-36
lines changed

kernel/sched/core.c

Lines changed: 7 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5106,55 +5106,26 @@ static int sched_copy_attr(struct sched_attr __user *uattr, struct sched_attr *a
51065106
u32 size;
51075107
int ret;
51085108

5109-
if (!access_ok(uattr, SCHED_ATTR_SIZE_VER0))
5110-
return -EFAULT;
5111-
51125109
/* Zero the full structure, so that a short copy will be nice: */
51135110
memset(attr, 0, sizeof(*attr));
51145111

51155112
ret = get_user(size, &uattr->size);
51165113
if (ret)
51175114
return ret;
51185115

5119-
/* Bail out on silly large: */
5120-
if (size > PAGE_SIZE)
5121-
goto err_size;
5122-
51235116
/* ABI compatibility quirk: */
51245117
if (!size)
51255118
size = SCHED_ATTR_SIZE_VER0;
5126-
5127-
if (size < SCHED_ATTR_SIZE_VER0)
5119+
if (size < SCHED_ATTR_SIZE_VER0 || size > PAGE_SIZE)
51285120
goto err_size;
51295121

5130-
/*
5131-
* If we're handed a bigger struct than we know of,
5132-
* ensure all the unknown bits are 0 - i.e. new
5133-
* user-space does not rely on any kernel feature
5134-
* extensions we dont know about yet.
5135-
*/
5136-
if (size > sizeof(*attr)) {
5137-
unsigned char __user *addr;
5138-
unsigned char __user *end;
5139-
unsigned char val;
5140-
5141-
addr = (void __user *)uattr + sizeof(*attr);
5142-
end = (void __user *)uattr + size;
5143-
5144-
for (; addr < end; addr++) {
5145-
ret = get_user(val, addr);
5146-
if (ret)
5147-
return ret;
5148-
if (val)
5149-
goto err_size;
5150-
}
5151-
size = sizeof(*attr);
5122+
ret = copy_struct_from_user(attr, sizeof(*attr), uattr, size);
5123+
if (ret) {
5124+
if (ret == -E2BIG)
5125+
goto err_size;
5126+
return ret;
51525127
}
51535128

5154-
ret = copy_from_user(attr, uattr, size);
5155-
if (ret)
5156-
return -EFAULT;
5157-
51585129
if ((attr->sched_flags & SCHED_FLAG_UTIL_CLAMP) &&
51595130
size < SCHED_ATTR_SIZE_VER1)
51605131
return -EINVAL;
@@ -5354,7 +5325,7 @@ sched_attr_copy_to_user(struct sched_attr __user *uattr,
53545325
* sys_sched_getattr - similar to sched_getparam, but with sched_attr
53555326
* @pid: the pid in question.
53565327
* @uattr: structure containing the extended parameters.
5357-
* @usize: sizeof(attr) that user-space knows about, for forwards and backwards compatibility.
5328+
* @usize: sizeof(attr) for fwd/bwd comp.
53585329
* @flags: for future extension.
53595330
*/
53605331
SYSCALL_DEFINE4(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr,

0 commit comments

Comments
 (0)