[kernel] r13744 - in dists/lenny/linux-2.6/debian: . patches/bugfix/all patches/series

Dann Frazier dannf at alioth.debian.org
Tue Jun 9 06:22:47 UTC 2009


Author: dannf
Date: Tue Jun  9 06:22:38 2009
New Revision: 13744

Log:
splice: fix deadlock in ocfs2 (CVE-2009-1961)

Added:
   dists/lenny/linux-2.6/debian/patches/bugfix/all/ocfs2-splice-deadlock.patch
Modified:
   dists/lenny/linux-2.6/debian/changelog
   dists/lenny/linux-2.6/debian/patches/series/16

Modified: dists/lenny/linux-2.6/debian/changelog
==============================================================================
--- dists/lenny/linux-2.6/debian/changelog	Tue Jun  9 06:20:58 2009	(r13743)
+++ dists/lenny/linux-2.6/debian/changelog	Tue Jun  9 06:22:38 2009	(r13744)
@@ -44,6 +44,7 @@
     to sharing the same device (closes: #514627)
   * [sparc64] Fix crash when reading /proc/iomem w/ heap memory checking
     (CVE-2009-1914)
+  * splice: fix deadlock in ocfs2 (CVE-2009-1961)
   
   [ Ben Hutchings ]
   * sata_nv: avoid link reset on controllers where it's broken

Added: dists/lenny/linux-2.6/debian/patches/bugfix/all/ocfs2-splice-deadlock.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/lenny/linux-2.6/debian/patches/bugfix/all/ocfs2-splice-deadlock.patch	Tue Jun  9 06:22:38 2009	(r13744)
@@ -0,0 +1,113 @@
+commit 7bfac9ecf0585962fe13584f5cf526d8c8e76f17
+Author: Miklos Szeredi <mszeredi at suse.cz>
+Date:   Mon Apr 6 17:41:00 2009 +0200
+
+    splice: fix deadlock in splicing to file
+    
+    There's a possible deadlock in generic_file_splice_write(),
+    splice_from_pipe() and ocfs2_file_splice_write():
+    
+     - task A calls generic_file_splice_write()
+     - this calls inode_double_lock(), which locks i_mutex on both
+       pipe->inode and target inode
+     - ordering depends on inode pointers, can happen that pipe->inode is
+       locked first
+     - __splice_from_pipe() needs more data, calls pipe_wait()
+     - this releases lock on pipe->inode, goes to interruptible sleep
+     - task B calls generic_file_splice_write(), similarly to the first
+     - this locks pipe->inode, then tries to lock inode, but that is
+       already held by task A
+     - task A is interrupted, it tries to lock pipe->inode, but fails, as
+       it is already held by task B
+     - ABBA deadlock
+    
+    Fix this by explicitly ordering locks: the outer lock must be on
+    target inode and the inner lock (which is later unlocked and relocked)
+    must be on pipe->inode.  This is OK, pipe inodes and target inodes
+    form two nonoverlapping sets, generic_file_splice_write() and friends
+    are not called with a target which is a pipe.
+    
+    Signed-off-by: Miklos Szeredi <mszeredi at suse.cz>
+    Acked-by: Mark Fasheh <mfasheh at suse.com>
+    Acked-by: Jens Axboe <jens.axboe at oracle.com>
+    Cc: stable at kernel.org
+    Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+
+Adjusted to apply to Debian's 2.6.26 by dann frazier <dannf at debian.org>
+
+diff -urpN linux-source-2.6.26.orig/fs/ocfs2/file.c linux-source-2.6.26/fs/ocfs2/file.c
+--- linux-source-2.6.26.orig/fs/ocfs2/file.c	2008-07-13 15:51:29.000000000 -0600
++++ linux-source-2.6.26/fs/ocfs2/file.c	2009-06-09 00:15:54.000000000 -0600
+@@ -2089,7 +2089,7 @@ static ssize_t ocfs2_file_splice_write(s
+ 		   out->f_path.dentry->d_name.len,
+ 		   out->f_path.dentry->d_name.name);
+ 
+-	inode_double_lock(inode, pipe->inode);
++	mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT);
+ 
+ 	ret = ocfs2_rw_lock(inode, 1);
+ 	if (ret < 0) {
+@@ -2104,12 +2104,16 @@ static ssize_t ocfs2_file_splice_write(s
+ 		goto out_unlock;
+ 	}
+ 
++	if (pipe->inode)
++		mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD);
+ 	ret = generic_file_splice_write_nolock(pipe, out, ppos, len, flags);
++	if (pipe->inode)
++		mutex_unlock(&pipe->inode->i_mutex);
+ 
+ out_unlock:
+ 	ocfs2_rw_unlock(inode, 1);
+ out:
+-	inode_double_unlock(inode, pipe->inode);
++	mutex_unlock(&inode->i_mutex);
+ 
+ 	mlog_exit(ret);
+ 	return ret;
+diff -urpN linux-source-2.6.26.orig/fs/splice.c linux-source-2.6.26/fs/splice.c
+--- linux-source-2.6.26.orig/fs/splice.c	2009-05-11 12:06:55.000000000 -0600
++++ linux-source-2.6.26/fs/splice.c	2009-06-09 00:17:13.000000000 -0600
+@@ -726,10 +726,19 @@ ssize_t splice_from_pipe(struct pipe_ino
+ 	 * ->commit_write. Most of the time, these expect i_mutex to
+ 	 * be held. Since this may result in an ABBA deadlock with
+ 	 * pipe->inode, we have to order lock acquiry here.
++	 *
++	 * Outer lock must be inode->i_mutex, as pipe_wait() will
++	 * release and reacquire pipe->inode->i_mutex, AND inode must
++	 * never be a pipe.
+ 	 */
+-	inode_double_lock(inode, pipe->inode);
++	WARN_ON(S_ISFIFO(inode->i_mode));
++	mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT);
++	if (pipe->inode)
++		mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD);
+ 	ret = __splice_from_pipe(pipe, &sd, actor);
+-	inode_double_unlock(inode, pipe->inode);
++	if (pipe->inode)
++		mutex_unlock(&pipe->inode->i_mutex);
++	mutex_unlock(&inode->i_mutex);
+ 
+ 	return ret;
+ }
+@@ -820,11 +829,17 @@ generic_file_splice_write(struct pipe_in
+ 	};
+ 	ssize_t ret;
+ 
+-	inode_double_lock(inode, pipe->inode);
++	WARN_ON(S_ISFIFO(inode->i_mode));
++	mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT);
+ 	ret = remove_suid(out->f_path.dentry);
+-	if (likely(!ret))
++	if (likely(!ret)) {
++		if (pipe->inode)
++			mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD);
+ 		ret = __splice_from_pipe(pipe, &sd, pipe_to_file);
+-	inode_double_unlock(inode, pipe->inode);
++		if (pipe->inode)
++			mutex_unlock(&pipe->inode->i_mutex);
++	}
++	mutex_unlock(&inode->i_mutex);
+ 	if (ret > 0) {
+ 		unsigned long nr_pages;
+ 

Modified: dists/lenny/linux-2.6/debian/patches/series/16
==============================================================================
--- dists/lenny/linux-2.6/debian/patches/series/16	Tue Jun  9 06:20:58 2009	(r13743)
+++ dists/lenny/linux-2.6/debian/patches/series/16	Tue Jun  9 06:22:38 2009	(r13744)
@@ -13,3 +13,4 @@
 + bugfix/all/drivers-acpi-asus_acpi-unsupported-models.patch
 + bugfix/all/drivers-net-wireless-iwl4965-scan-cancel.patch
 + bugfix/sparc/sparc64-Fix-crash-with-proc-iomem.patch
++ bugfix/all/ocfs2-splice-deadlock.patch



More information about the Kernel-svn-changes mailing list