Skip to content

Commit 90da2e3

Browse files
isilenceaxboe
authored andcommitted
splice: move f_mode checks to do_{splice,tee}()
do_splice() is used by io_uring, as will be do_tee(). Move f_mode checks from sys_{splice,tee}() to do_{splice,tee}(), so they're enforced for io_uring as well. Fixes: 7d67af2 ("io_uring: add splice(2) support") Reported-by: Jann Horn <[email protected]> Signed-off-by: Pavel Begunkov <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 7f13657 commit 90da2e3

File tree

1 file changed

+18
-27
lines changed

1 file changed

+18
-27
lines changed

fs/splice.c

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,19 +1118,17 @@ long do_splice(struct file *in, loff_t __user *off_in,
11181118
loff_t offset;
11191119
long ret;
11201120

1121+
if (unlikely(!(in->f_mode & FMODE_READ) ||
1122+
!(out->f_mode & FMODE_WRITE)))
1123+
return -EBADF;
1124+
11211125
ipipe = get_pipe_info(in);
11221126
opipe = get_pipe_info(out);
11231127

11241128
if (ipipe && opipe) {
11251129
if (off_in || off_out)
11261130
return -ESPIPE;
11271131

1128-
if (!(in->f_mode & FMODE_READ))
1129-
return -EBADF;
1130-
1131-
if (!(out->f_mode & FMODE_WRITE))
1132-
return -EBADF;
1133-
11341132
/* Splicing to self would be fun, but... */
11351133
if (ipipe == opipe)
11361134
return -EINVAL;
@@ -1153,9 +1151,6 @@ long do_splice(struct file *in, loff_t __user *off_in,
11531151
offset = out->f_pos;
11541152
}
11551153

1156-
if (unlikely(!(out->f_mode & FMODE_WRITE)))
1157-
return -EBADF;
1158-
11591154
if (unlikely(out->f_flags & O_APPEND))
11601155
return -EINVAL;
11611156

@@ -1440,15 +1435,11 @@ SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in,
14401435
error = -EBADF;
14411436
in = fdget(fd_in);
14421437
if (in.file) {
1443-
if (in.file->f_mode & FMODE_READ) {
1444-
out = fdget(fd_out);
1445-
if (out.file) {
1446-
if (out.file->f_mode & FMODE_WRITE)
1447-
error = do_splice(in.file, off_in,
1448-
out.file, off_out,
1449-
len, flags);
1450-
fdput(out);
1451-
}
1438+
out = fdget(fd_out);
1439+
if (out.file) {
1440+
error = do_splice(in.file, off_in, out.file, off_out,
1441+
len, flags);
1442+
fdput(out);
14521443
}
14531444
fdput(in);
14541445
}
@@ -1770,6 +1761,10 @@ static long do_tee(struct file *in, struct file *out, size_t len,
17701761
struct pipe_inode_info *opipe = get_pipe_info(out);
17711762
int ret = -EINVAL;
17721763

1764+
if (unlikely(!(in->f_mode & FMODE_READ) ||
1765+
!(out->f_mode & FMODE_WRITE)))
1766+
return -EBADF;
1767+
17731768
/*
17741769
* Duplicate the contents of ipipe to opipe without actually
17751770
* copying the data.
@@ -1795,7 +1790,7 @@ static long do_tee(struct file *in, struct file *out, size_t len,
17951790

17961791
SYSCALL_DEFINE4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags)
17971792
{
1798-
struct fd in;
1793+
struct fd in, out;
17991794
int error;
18001795

18011796
if (unlikely(flags & ~SPLICE_F_ALL))
@@ -1807,14 +1802,10 @@ SYSCALL_DEFINE4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags)
18071802
error = -EBADF;
18081803
in = fdget(fdin);
18091804
if (in.file) {
1810-
if (in.file->f_mode & FMODE_READ) {
1811-
struct fd out = fdget(fdout);
1812-
if (out.file) {
1813-
if (out.file->f_mode & FMODE_WRITE)
1814-
error = do_tee(in.file, out.file,
1815-
len, flags);
1816-
fdput(out);
1817-
}
1805+
out = fdget(fdout);
1806+
if (out.file) {
1807+
error = do_tee(in.file, out.file, len, flags);
1808+
fdput(out);
18181809
}
18191810
fdput(in);
18201811
}

0 commit comments

Comments
 (0)