Messages in this thread Patch in this message | | | From | Dmitry Monakhov <> | Subject | [PATCH 16/16] splice: fix race beween splice_write vs fcntl(,F_SETFL,) | Date | Sat, 4 Apr 2015 23:13:25 +0400 |
| |
file->f_flags & O_APPEND is checked twice -> do_splice_direct or do_splice: return EINVAL if O_APPEND enabled -> generic_write_checks: seek to end in case of O_APPEND This is obviously whong and result in unpredictable behaviour if raced with fcntl. It is reasonable to recheck append flag after kiocb was constructed ( f_flags becomes stable), for that reason we should use special analog of vfs_write_iter()
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org> --- fs/splice.c | 23 ++++++++++++++++++++++- 1 files changed, 22 insertions(+), 1 deletions(-)
diff --git a/fs/splice.c b/fs/splice.c index 41cbb16..7ac43db 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -922,6 +922,27 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, return ret; } +ssize_t splice_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos) +{ + struct kiocb kiocb; + ssize_t ret; + + if (!file->f_op->write_iter) + return -EINVAL; + + init_sync_kiocb(&kiocb, file); + if (is_append_kiocb(&kiocb)) + return -EINVAL; + + kiocb.ki_pos = *ppos; + iter->type |= WRITE; + ret = file->f_op->write_iter(&kiocb, iter); + BUG_ON(ret == -EIOCBQUEUED); + if (ret > 0) + *ppos = kiocb.ki_pos; + return ret; +} + /** * iter_file_splice_write - splice data from a pipe to a file @@ -1005,7 +1026,7 @@ iter_file_splice_write(struct pipe_inode_info *pipe, struct file *out, iov_iter_bvec(&from, ITER_BVEC | WRITE, array, n, sd.total_len - left); - ret = vfs_iter_write(out, &from, &sd.pos); + ret = splice_iter_write(out, &from, &sd.pos); if (ret <= 0) break; -- 1.7.1
| |