[PATCH] Remove SUID when splicing into an inode
Jens Axboe [Tue, 17 Oct 2006 17:43:22 +0000 (19:43 +0200)]
Originally from Mark Fasheh <mark.fasheh@oracle.com>

generic_file_splice_write() does not remove S_ISUID or S_ISGID. This is
inconsistent with the way we generally write to files.

Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>

fs/splice.c

index 68e20e6..49fb9f1 100644 (file)
@@ -845,6 +845,10 @@ generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out,
        ssize_t ret;
        int err;
 
+       err = remove_suid(out->f_dentry);
+       if (unlikely(err))
+               return err;
+
        ret = __splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file);
        if (ret > 0) {
                *ppos += ret;
@@ -883,12 +887,21 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
                          loff_t *ppos, size_t len, unsigned int flags)
 {
        struct address_space *mapping = out->f_mapping;
+       struct inode *inode = mapping->host;
        ssize_t ret;
+       int err;
+
+       err = should_remove_suid(out->f_dentry);
+       if (unlikely(err)) {
+               mutex_lock(&inode->i_mutex);
+               err = __remove_suid(out->f_dentry, err);
+               mutex_unlock(&inode->i_mutex);
+               if (err)
+                       return err;
+       }
 
        ret = splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file);
        if (ret > 0) {
-               struct inode *inode = mapping->host;
-
                *ppos += ret;
 
                /*
@@ -896,8 +909,6 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
                 * sync it.
                 */
                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);