Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 1177

kernel-2.6.18-238.el5.src.rpm

From: Eric Sandeen <sandeen@redhat.com>
Date: Thu, 2 Oct 2008 14:46:52 -0500
Subject: [fs] remove SUID when splicing into an inode
Message-id: 48E5252C.8010003@redhat.com
O-Subject: [RHEL5.3 PATCH] Remove SUID when splicing into an inode
Bugzilla: 464452
RH-Acked-by: Peter Staubach <staubach@redhat.com>
RH-Acked-by: Alan Cox <alan@redhat.com>
RH-Acked-by: Eugene Teo <eteo@redhat.com>

This is for Bug 464452 - kernel: remove SUID when splicing into an inode [rhel-5.3]

(I'm not sure how Eugene is handling this, it may be part of CVE CVE-2008-4210?)
(Note also that this depends on Eugene's earlier patch,
BZ#463687 kernel: open() call allows setgid bit	when user is not in new file's group [v2],
which provides should_remove_suid())

Without this change, one can use splice to create a binary which has the effective
group id of the sgid directory it is created in:
(see https://bugzilla.redhat.com/show_bug.cgi?id=464450#c3)

[fsgqa@inode setgid_dir]$ ./splice_copy /bin/sh sh
copied /bin/sh to sh via splice

[fsgqa@inode setgid_dir]$ ls -l sh
-rwxr-s--- 1 fsgqa root 801504 Oct  2 13:12 sh

[fsgqa@inode setgid_dir]$ ./sh -p
sh-3.2$ id
uid=500(fsgqa) gid=500(fsgqa) egid=0(root) groups=500(fsgqa)

This is a backport of:

From: Jens Axboe <jens.axboe@oracle.com>
Date: Tue, 17 Oct 2006 17:43:22 +0000 (+0200)
Subject: [PATCH] Remove SUID when splicing into an inode
X-Git-Tag: v2.6.19-rc3~32^2
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=8c34e2d63231d4bf4852bac8521883944d770fe3

[PATCH] Remove SUID when splicing into an inode

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>

diff --git a/fs/splice.c b/fs/splice.c
index cee12d8..32e0cc1 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -827,12 +827,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;
 
 		/*
@@ -840,8 +849,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);