On Mon, Apr 27, 2020 at 9:53 PM Jens Axboe <axboe@xxxxxxxxx> wrote: > On 4/27/20 1:29 PM, Jens Axboe wrote: > > On 4/27/20 1:20 PM, Jann Horn wrote: > >> On Sat, Apr 25, 2020 at 10:23 PM Jens Axboe <axboe@xxxxxxxxx> wrote: > >>> On 4/25/20 11:29 AM, Andreas Smas wrote: > >>>> Hi, > >>>> > >>>> Tried to use io_uring with OP_RECVMSG with ancillary buffers (for my > >>>> particular use case I'm using SO_TIMESTAMP for incoming UDP packets). > >>>> > >>>> These submissions fail with EINVAL due to the check in __sys_recvmsg_sock(). > >>>> > >>>> The following hack fixes the problem for me and I get valid timestamps > >>>> back. Not suggesting this is the real fix as I'm not sure what the > >>>> implications of this is. > >>>> > >>>> Any insight into this would be much appreciated. > >>> > >>> It was originally disabled because of a security issue, but I do think > >>> it's safe to enable again. > >>> > >>> Adding the io-uring list and Jann as well, leaving patch intact below. > >>> > >>>> diff --git a/net/socket.c b/net/socket.c > >>>> index 2dd739fba866..689f41f4156e 100644 > >>>> --- a/net/socket.c > >>>> +++ b/net/socket.c > >>>> @@ -2637,10 +2637,6 @@ long __sys_recvmsg_sock(struct socket *sock, > >>>> struct msghdr *msg, > >>>> struct user_msghdr __user *umsg, > >>>> struct sockaddr __user *uaddr, unsigned int flags) > >>>> { > >>>> - /* disallow ancillary data requests from this path */ > >>>> - if (msg->msg_control || msg->msg_controllen) > >>>> - return -EINVAL; > >>>> - > >>>> return ____sys_recvmsg(sock, msg, umsg, uaddr, flags, 0); > >>>> } > >> > >> I think that's hard to get right. In particular, unix domain sockets > >> can currently pass file descriptors in control data - so you'd need to > >> set the file_table flag for recvmsg and sendmsg. And I'm not sure > >> whether, to make this robust, there should be a whitelist of types of > >> control messages that are permitted to be used with io_uring, or > >> something like that... > >> > >> I think of ancillary buffers as being kind of like ioctl handlers in > >> this regard. > > > > Good point. I'll send out something that hopefully will be enough to > > be useful, whole not allowing anything randomly. > > That things is a bit of a mess... How about something like this for > starters? [...] > +static bool io_net_allow_cmsg(struct msghdr *msg) > +{ > + struct cmsghdr *cmsg; > + > + for_each_cmsghdr(cmsg, msg) { Isn't this going to dereference a userspace pointer? ->msg_control has not been copied into the kernel at this point, right? > + if (!__io_net_allow_cmsg(cmsg)) > + return false; > + } [...] > @@ -3604,6 +3635,11 @@ static int io_sendmsg(struct io_kiocb *req, bool force_nonblock) [...] > + if (!io_net_allow_cmsg(&kmsg->msg)) { > + ret = -EINVAL; > + goto err; > + } [...] > @@ -3840,6 +3877,11 @@ static int io_recvmsg(struct io_kiocb *req, bool force_nonblock) [...] > + if (!io_net_allow_cmsg(&kmsg->msg)) { > + ret = -EINVAL; > + goto err; > + } > +