[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