On Sun, Jan 26, 2020 at 03:14:39PM +1100, Aleksa Sarai wrote: > On 2020-01-26, Aleksa Sarai <cyphar@xxxxxxxxxx> wrote: > > On 2020-01-24, Sargun Dhillon <sargun@xxxxxxxxx> wrote: > > > static long seccomp_notify_recv(struct seccomp_filter *filter, > > > void __user *buf) > > > { > > > struct seccomp_knotif *knotif = NULL, *cur; > > > struct seccomp_notif unotif; > > > + struct task_struct *group_leader; > > > + bool send_pidfd; > > > ssize_t ret; > > > > > > + if (copy_from_user(&unotif, buf, sizeof(unotif))) > > > + return -EFAULT; > > > /* Verify that we're not given garbage to keep struct extensible. */ > > > - ret = check_zeroed_user(buf, sizeof(unotif)); > > > - if (ret < 0) > > > - return ret; > > > - if (!ret) > > > + if (unotif.id || > > > + unotif.pid || > > > + memchr_inv(&unotif.data, 0, sizeof(unotif.data)) || > > > + unotif.pidfd) > > > + return -EINVAL; > > > > IMHO this check is more confusing than the original check_zeroed_user(). > > Something like the following is simpler and less prone to forgetting to > > add a new field in the future: > > I'm all for this, originally my patch read: __u32 flags = 0; swap(unotif.flags, flags); if (memchr(&unotif, 0, sizeof(unotif)) return -EINVAL; --- And then check flags appropriately. I'm not sure if this is "better", as I didn't see any other implementations that look like this in the kernel. What do you think? It could even look "simpler", as in: __u32 flags; if (copy_from_user(....)) return -EFAULT; flags = unotif.flags; unotif.flags = 0; if (memchr_inv(&unotif, 0, sizeof(unotif))) return -EINVAL; Are either of those preferential, reasonable, or at a minimum inoffensive? > > if (memchr_inv(&unotif, 0, sizeof(unotif))) > > return -EINVAL; > Wouldn't this fail if flags was set to any value? We either need to zero out flags prior to checking, or split it into range checks that exclude flags. > Also the check in the patch doesn't ensure that any unnamed padding is > zeroed -- memchr_inv(&unotif, 0, sizeof(unotif)) does. > > -- > Aleksa Sarai > Senior Software Engineer (Containers) > SUSE Linux GmbH > <https://www.cyphar.com/>