rpms/kernel/F-12 ext4-fix-insufficient-checks-in-EXT4_IOC_MOVE_EXT.patch, NONE, 1.1 kernel.spec, 1.1951, 1.1952

Kyle McMartin kyle at fedoraproject.org
Wed Dec 9 14:29:02 UTC 2009


Author: kyle

Update of /cvs/pkgs/rpms/kernel/F-12
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv5652

Modified Files:
	kernel.spec 
Added Files:
	ext4-fix-insufficient-checks-in-EXT4_IOC_MOVE_EXT.patch 
Log Message:
* Wed Dec 09 2009 Kyle McMartin <kyle at redhat.com> 2.6.31.6-166
- ext4-fix-insufficient-checks-in-EXT4_IOC_MOVE_EXT.patch: CVE-2009-4131
  fix insufficient permission checking which could result in arbitrary
  data corruption by a local unprivileged user.


ext4-fix-insufficient-checks-in-EXT4_IOC_MOVE_EXT.patch:
 ioctl.c       |   33 ++++++++++++++++++++-------------
 move_extent.c |    7 +++++++
 2 files changed, 27 insertions(+), 13 deletions(-)

--- NEW FILE ext4-fix-insufficient-checks-in-EXT4_IOC_MOVE_EXT.patch ---
>From 910123ba363623f15ffb5d05dd87bdf06d08c609 Mon Sep 17 00:00:00 2001
From: Akira Fujita <a-fujita at rs.jp.nec.com>
Date: Sun, 6 Dec 2009 23:38:31 -0500
Subject: [PATCH] ext4: Fix insufficient checks in EXT4_IOC_MOVE_EXT

This patch fixes three problems in the handling of the
EXT4_IOC_MOVE_EXT ioctl:

1. In current EXT4_IOC_MOVE_EXT, there are read access mode checks for
original and donor files, but they allow the illegal write access to
donor file, since donor file is overwritten by original file data.  To
fix this problem, change access mode checks of original (r->r/w) and
donor (r->w) files.

2.  Disallow the use of donor files that have a setuid or setgid bits.

3.  Call mnt_want_write() and mnt_drop_write() before and after
ext4_move_extents() calling to get write access to a mount.

Signed-off-by: Akira Fujita <a-fujita at rs.jp.nec.com>
Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
---

 fs/ext4/ioctl.c       |   28 ++++++++++++++++++----------
 fs/ext4/move_extent.c |    7 +++++++
 2 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index 7050a9c..f5b1d3c 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -221,32 +221,39 @@ setversion_out:
 		struct file *donor_filp;
 		int err;
 
+		if (!(filp->f_mode & FMODE_READ) ||
+		    !(filp->f_mode & FMODE_WRITE))
+			return -EBADF;
+
 		if (copy_from_user(&me,
 			(struct move_extent __user *)arg, sizeof(me)))
 			return -EFAULT;
+		me.moved_len = 0;
 
 		donor_filp = fget(me.donor_fd);
 		if (!donor_filp)
 			return -EBADF;
 
-		if (!capable(CAP_DAC_OVERRIDE)) {
-			if ((current->real_cred->fsuid != inode->i_uid) ||
-				!(inode->i_mode & S_IRUSR) ||
-				!(donor_filp->f_dentry->d_inode->i_mode &
-				S_IRUSR)) {
-				fput(donor_filp);
-				return -EACCES;
-			}
+		if (!(donor_filp->f_mode & FMODE_WRITE)) {
+			err = -EBADF;
+			goto mext_out;
 		}
 
+		err = mnt_want_write(filp->f_path.mnt);
+		if (err)
+			goto mext_out;
+
 		err = ext4_move_extents(filp, donor_filp, me.orig_start,
 					me.donor_start, me.len, &me.moved_len);
-		fput(donor_filp);
+		mnt_drop_write(filp->f_path.mnt);
+		if (me.moved_len > 0)
+			file_remove_suid(donor_filp);
 
-		if (!err)
-			if (copy_to_user((struct move_extent *)arg,
-				&me, sizeof(me)))
-				return -EFAULT;
+		if (copy_to_user((struct move_extent *)arg, &me, sizeof(me)))
+			err = -EFAULT;
+
+mext_out:
+		fput(donor_filp);
 		return err;
 	}
 
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index bbf2dd9..c5250b5 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -905,6 +905,13 @@ mext_check_arguments(struct inode *orig_inode,
 		return -EINVAL;
 	}
 
+	if (donor_inode->i_mode & (S_ISUID|S_ISGID)) {
+		ext4_debug("ext4 move extent: suid or sgid is set"
+			   " to donor file [ino:orig %lu, donor %lu]\n",
+			   orig_inode->i_ino, donor_inode->i_ino);
+		return -EINVAL;
+	}
+
 	/* Ext4 move extent does not support swapfile */
 	if (IS_SWAPFILE(orig_inode) || IS_SWAPFILE(donor_inode)) {
 		ext4_debug("ext4 move extent: The argument files should "


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-12/kernel.spec,v
retrieving revision 1.1951
retrieving revision 1.1952
diff -u -p -r1.1951 -r1.1952
--- kernel.spec	8 Dec 2009 12:57:07 -0000	1.1951
+++ kernel.spec	9 Dec 2009 14:29:02 -0000	1.1952
@@ -812,6 +812,9 @@ Patch14463: dlm-fix-connection-close-han
 # rhbz#544144 [bbf31bf18d34caa87dd01f08bf713635593697f2]
 Patch14464: ipv4-fix-null-ptr-deref-in-ip_fragment.patch
 
+# rhbz#544471
+Patch14465: ext4-fix-insufficient-checks-in-EXT4_IOC_MOVE_EXT.patch
+
 %endif
 
 BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root
@@ -1518,6 +1521,9 @@ ApplyPatch dlm-fix-connection-close-hand
 # rhbz#544144
 ApplyPatch ipv4-fix-null-ptr-deref-in-ip_fragment.patch
 
+# rhbz#544471
+ApplyPatch ext4-fix-insufficient-checks-in-EXT4_IOC_MOVE_EXT.patch
+
 # END OF PATCH APPLICATIONS
 
 %endif
@@ -2167,6 +2173,11 @@ fi
 # and build.
 
 %changelog
+* Wed Dec 09 2009 Kyle McMartin <kyle at redhat.com> 2.6.31.6-166
+- ext4-fix-insufficient-checks-in-EXT4_IOC_MOVE_EXT.patch: CVE-2009-4131
+  fix insufficient permission checking which could result in arbitrary
+  data corruption by a local unprivileged user.
+
 * Tue Dec  8 2009 Steve Dickson <steved at redhat.com> 2.6.31.6-165
 - nfsd: Updated to latest pseudo root code fixing rhbz# 538609
 




More information about the scm-commits mailing list