On Wed, May 29, 2019 at 05:42:14PM +0200, Yann Droneaud wrote: > Le mercredi 29 mai 2019 à 17:22 +0200, Christian Brauner a écrit : > > This adds the clone3 system call. > > > > > > diff --git a/kernel/fork.c b/kernel/fork.c > > index b4cba953040a..6bc3e3d17150 100644 > > --- a/kernel/fork.c > > +++ b/kernel/fork.c > > @@ -2472,7 +2475,96 @@ SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, > > unsigned long, tls) > > #endif > > { > > - return _do_fork(clone_flags, newsp, 0, parent_tidptr, child_tidptr, tls); > > + struct kernel_clone_args args = { > > + .flags = clone_flags, > > + .stack = newsp, > > + .pidfd = parent_tidptr, > > + .parent_tidptr = parent_tidptr, > > + .tls = tls, > > + .child_tidptr = child_tidptr, > > + }; > > + > > + /* clone(CLONE_PIDFD) uses parent_tidptr to return a pidfd */ > > + if ((clone_flags & CLONE_PIDFD) && (clone_flags & CLONE_PARENT_SETTID)) > > + return -EINVAL; > > + > > + return _do_fork(&args); > > +} > > + > > +static bool clone3_flags_valid(u64 flags) > > +{ > > + if (flags & CLONE_DETACHED) > > + return false; > > + > > + if (flags & ~CLONE_MAX) > > + return false; > > + > > + return true; > > +} > > + > > +static int copy_clone_args_from_user(struct kernel_clone_args *kargs, > > + struct clone_args __user *uargs, > > + size_t size) > > +{ > > + struct clone_args args; > > + > > + if (unlikely(size > PAGE_SIZE)) > > + return -E2BIG; > > + > > + if (unlikely(size < sizeof(struct clone_args))) > > + return -EINVAL; > > + > > + if (unlikely(!access_ok(uargs, size))) > > + return -EFAULT; > > + > > + if (size > sizeof(struct clone_args)) { > > + unsigned char __user *addr; > > + unsigned char __user *end; > > + unsigned char val; > > + > > + addr = (void __user *)uargs + sizeof(struct clone_args); > > + end = (void __user *)uargs + size; > > + > > + for (; addr < end; addr++) { > > + if (get_user(val, addr)) > > + return -EFAULT; > > + if (val) > > + return -E2BIG; > > Should be -EINVAL: having something after the structure should be > handled just like an invalid flags, while still allowing future > userspace program to probe for support for newer feature. (Traveling until Monday, so sorry for delayed responses.) This copies what: kernel/sched/core.c:sched_copy_attr() kernel/event/core.c:perf_copy_attr() are already doing. Consistency might be good here but, I think. Christian