[kernel] r9705 - in dists/etch/linux-2.6/debian: . patches/bugfix patches/series
Dann Frazier
dannf at alioth.debian.org
Fri Nov 9 17:44:30 UTC 2007
Author: dannf
Date: Fri Nov 9 17:44:29 2007
New Revision: 9705
Log:
* [futex] Fix address computation in compat code, fixing hangs
on sparc64. (closes: #433187)
Added:
dists/etch/linux-2.6/debian/patches/bugfix/futex-fix-compat-addr-compute.patch
dists/etch/linux-2.6/debian/patches/series/17
Modified:
dists/etch/linux-2.6/debian/changelog
Modified: dists/etch/linux-2.6/debian/changelog
==============================================================================
--- dists/etch/linux-2.6/debian/changelog (original)
+++ dists/etch/linux-2.6/debian/changelog Fri Nov 9 17:44:29 2007
@@ -1,3 +1,10 @@
+linux-2.6 (2.6.18.dfsg.1-17) UNRELEASED-stable; urgency=low
+
+ * [futex] Fix address computation in compat code, fixing hangs
+ on sparc64. (closes: #433187)
+
+ -- dann frazier <dannf at debian.org> Thu, 08 Nov 2007 09:43:49 -0700
+
linux-2.6 (2.6.18.dfsg.1-16) stable; urgency=high
[ Bastian Blank ]
Added: dists/etch/linux-2.6/debian/patches/bugfix/futex-fix-compat-addr-compute.patch
==============================================================================
--- (empty file)
+++ dists/etch/linux-2.6/debian/patches/bugfix/futex-fix-compat-addr-compute.patch Fri Nov 9 17:44:29 2007
@@ -0,0 +1,117 @@
+From: davem at davemloft.net Wed Nov 7 06:14:01 2007
+Date: Tue, 06 Nov 2007 21:13:56 -0800 (PST)
+Message-Id: <20071106.211356.60087540.davem at davemloft.net>
+To: torvalds at linux-foundation.org
+Cc: linux-kernel at vger.kernel.org, sparclinux at vger.kernel.org, linux-arch at vger.kernel.org, bernd at bzed.de, joy at entuzijast.net, fabbione at ubuntu.com, arnd at arndb.de
+Subject: Re: Fix for sparc64 cpu hangs.
+From: David Miller <davem at davemloft.net>
+In-Reply-To: <20071106.203433.144763156.davem at davemloft.net>
+References: <20071106.203433.144763156.davem at davemloft.net>
+X-Mailer: Mew version 5.2 on Emacs 22.1 / Mule 5.0 (SAKAKI)
+Mime-Version: 1.0
+Content-Type: Text/Plain; charset=us-ascii
+Content-Transfer-Encoding: 7bit
+
+From: David Miller <davem at davemloft.net>
+Date: Tue, 06 Nov 2007 20:34:33 -0800 (PST)
+
+> [FUTEX]: Fix address computation in compat code.
+
+Sorry, I just noticed there is a second handle_futex_death()
+call in compat_exit_robust_list() which has the same
+address computation bug.
+
+Here is an updated patch:
+
+[FUTEX]: Fix address computation in compat code.
+
+compat_exit_robust_list() computes a pointer to the
+futex entry in userspace as follows:
+
+ (void __user *)entry + futex_offset
+
+'entry' is a 'struct robust_list __user *', and
+'futex_offset' is a 'compat_long_t' (typically a 's32').
+
+Things explode if the 32-bit sign bit is set in futex_offset.
+
+Type promotion sign extends futex_offset to a 64-bit value before
+adding it to 'entry'.
+
+This triggered a problem on sparc64 running 32-bit applications which
+would lock up a cpu looping forever in the fault handling for the
+userspace load in handle_futex_death().
+
+Compat userspace runs with address masking (wherein the cpu zeros out
+the top 32-bits of every effective address given to a memory operation
+instruction) so the sparc64 fault handler accounts for this by
+zero'ing out the top 32-bits of the fault address too.
+
+Since the kernel properly uses the compat_uptr interfaces, kernel side
+accesses to compat userspace work too since they will only use
+addresses with the top 32-bit clear.
+
+Because of this compat futex layer bug we get into the following loop
+when executing the get_user() load near the top of handle_futex_death():
+
+1) load from address '0xfffffffff7f16bd8', FAULT
+2) fault handler clears upper 32-bits, processes fault
+ for address '0xf7f16bd8' which succeeds
+3) goto #1
+
+I want to thank Bernd Zeimetz, Josip Rodin, and Fabio Massimo Di Nitto
+for their tireless efforts helping me track down this bug.
+
+Signed-off-by: David S. Miller <davem at davemloft.net>
+
+Backported to Debian's 2.6.18 by dann frazier <dannf at hp.com>
+
+--- linux-source-2.6.18/kernel/futex_compat.c.orig 2006-09-19 21:42:06.000000000 -0600
++++ linux-source-2.6.18/kernel/futex_compat.c 2007-11-07 10:30:44.000000000 -0700
+@@ -29,6 +29,15 @@ fetch_robust_entry(compat_uptr_t *uentry
+ return 0;
+ }
+
++static void __user *futex_uaddr(struct robust_list *entry,
++ compat_long_t futex_offset)
++{
++ compat_uptr_t base = ptr_to_compat(entry);
++ void __user *uaddr = compat_ptr(base + futex_offset);
++
++ return uaddr;
++}
++
+ /*
+ * Walk curr->robust_list (very carefully, it's a userspace list!)
+ * and mark any locks found there dead, and notify any waiters.
+@@ -61,19 +70,24 @@ void compat_exit_robust_list(struct task
+ if (fetch_robust_entry(&upending, &pending,
+ &head->list_op_pending, &pip))
+ return;
+- if (upending)
+- handle_futex_death((void *)pending + futex_offset, curr, pip);
++ if (upending) {
++ void __user *uaddr = futex_uaddr(pending, futex_offset);
++
++ handle_futex_death(uaddr, curr, pip);
++ }
+
+ while (compat_ptr(uentry) != &head->list) {
+ /*
+ * A pending lock might already be on the list, so
+ * dont process it twice:
+ */
+- if (entry != pending)
+- if (handle_futex_death((void *)entry + futex_offset,
+- curr, pi))
+- return;
++ if (entry != pending) {
++ void __user *uaddr = futex_uaddr(entry,
++ futex_offset);
+
++ if (handle_futex_death(uaddr, curr, pi))
++ return;
++ }
+ /*
+ * Fetch the next entry in the list:
+ */
Added: dists/etch/linux-2.6/debian/patches/series/17
==============================================================================
--- (empty file)
+++ dists/etch/linux-2.6/debian/patches/series/17 Fri Nov 9 17:44:29 2007
@@ -0,0 +1 @@
++ bugfix/futex-fix-compat-addr-compute.patch
More information about the Kernel-svn-changes
mailing list