On Wed, Sep 3, 2025 at 8:10 AM Arjun Shankar <arjun@xxxxxxxxxx> wrote: > > Hello! > > > > Earlier on in this thread, Aleksa mentioned sched_setattr as > > > establishing precedent for the kernel modifying non-const objects. It > > > looks like glibc actually does provide a sched_setattr wrapper since > > > 2.41. The relevant argument hasn't been marked as const and the kernel > > > does modify the contents, and glibc's syscall wrapper simply passes it > > > through. So we already do this. > > > > given that > > > > SYSCALL_DEFINE3(sched_setattr, pid_t, pid, struct sched_attr __user *, uattr, > > unsigned int, flags) > > > > calls sched_setattr(), which is defined thus: > > > > int sched_setattr(struct task_struct *p, const struct sched_attr *attr) > > { > > return __sched_setscheduler(p, attr, true, true); > > } > > > > i think that's just a copy & paste mistake in the kernel -- carefully > > preserved in glibc and bionic -- no? > > > > (i only see the kernel updating its own _copy_ of the passed-in struct.) > > Based on my understanding, it all happens before the call to the const > marked sched_setattr. Starting from line 986 (as of today) on the same > syscalls.c file [1]: > > retval = sched_copy_attr(uattr, &attr); > if (retval) > return retval; > > Which inside sched_copy_attr does: > > ret = copy_struct_from_user(attr, sizeof(*attr), uattr, size); > if (ret) { > if (ret == -E2BIG) > goto err_size; > > And that leads to: > > err_size: > put_user(sizeof(*attr), &uattr->size); > return -E2BIG; oh, wow. it didn't even occur to me to look inside a function called sched_copy_attr(), though the fact that it wasn't a direct call to copy_struct_from_user() should perhaps have been a clue :-( > Which writes to userspace. > > [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/sched/syscalls.c?id=e6b9dce0aeeb91dfc0974ab87f02454e24566182#n986 > > -- > Arjun Shankar > he/him/his >