On 04/05/2020 14:09, Jann Horn wrote: > On Sat, May 2, 2020 at 2:10 PM Pavel Begunkov <asml.silence@xxxxxxxxx> wrote: >> export do_tee() for use in io_uring > [...] >> diff --git a/fs/splice.c b/fs/splice.c > [...] >> * The 'flags' used are the SPLICE_F_* variants, currently the only >> * applicable one is SPLICE_F_NONBLOCK. >> */ >> -static long do_tee(struct file *in, struct file *out, size_t len, >> - unsigned int flags) >> +long do_tee(struct file *in, struct file *out, size_t len, unsigned int flags) >> { >> struct pipe_inode_info *ipipe = get_pipe_info(in); >> struct pipe_inode_info *opipe = get_pipe_info(out); > > AFAICS do_tee() in its current form is not something you should be > making available to anything else, because the file mode checks are > performed in sys_tee() instead of in do_tee(). (And I don't see any > check for file modes in your uring patch, but maybe I missed it?) If > you want to make do_tee() available elsewhere, please refactor the > file mode checks over into do_tee(). Overlooked it indeed. Glad you found it > > The same thing seems to be true for the splice support, which luckily > hasn't landed in a kernel release yet... while do_splice() does a > random assortment of checks, the checks that actually consistently > enforce the rules happen in sys_splice(). From a quick look, > do_splice() doesn't seem to check: > > - when splicing from a pipe to a non-pipe: whether read access to the > input pipe exists > - when splicing from a non-pipe to a pipe: whether write access to > the output pipe exists > > ... which AFAICS means that io_uring probably lets you get full R/W > access to any pipe to which you're supposed to have either read or > write access. (Although admittedly it is rare in practice that you get > one end of a pipe and can't access the other one.) > > When you expose previously internal helpers to io_uring, please have a > look at their callers and see whether they perform any checks that > look relevant. > -- Pavel Begunkov