From nobody Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Thu, 28 Sep 2006 16:10:37 -0700 Subject: [PATCH] Remove SUID when splicing into an inode generic_file_splice_write() does not remove S_ISUID or S_ISGID. This is inconsistent with the way we generally write to files. This patch changes the locking in that it holds inode->i_mutex across splice_from_pipe() as remove_suid() might call ->setattr() which typically expects i_mutex to be held. I'm pretty sure that most file systems expect i_mutex to be held across ->prepare_write() and ->commit_write() which this patch should then fix as well. Signed-off-by: Mark Fasheh --- fs/splice.c | 15 +++++++++------ 1 files changed, 9 insertions(+), 6 deletions(-) 0c285bf789f0e004ea2cd7cf9d3e206835a5241b diff --git a/fs/splice.c b/fs/splice.c index 684bca3..a1296c2 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -714,7 +714,10 @@ ssize_t splice_from_pipe(struct pipe_ino int ret, do_wakeup, err; struct splice_desc sd; - ret = 0; + ret = remove_suid(out->f_dentry); + if (ret) + return ret; + do_wakeup = 0; sd.total_len = len; @@ -826,12 +829,13 @@ generic_file_splice_write(struct pipe_in loff_t *ppos, size_t len, unsigned int flags) { struct address_space *mapping = out->f_mapping; + struct inode *inode = mapping->host; ssize_t ret; + mutex_lock(&inode->i_mutex); + ret = splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); if (ret > 0) { - struct inode *inode = mapping->host; - *ppos += ret; /* @@ -841,16 +845,15 @@ generic_file_splice_write(struct pipe_in if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) { int err; - mutex_lock(&inode->i_mutex); err = generic_osync_inode(inode, mapping, OSYNC_METADATA|OSYNC_DATA); - mutex_unlock(&inode->i_mutex); - if (err) ret = err; } } + mutex_unlock(&inode->i_mutex); + return ret; } -- 1.3.3