SecurityTracker.com
Keep Track of the Latest Vulnerabilities
with SecurityTracker!
    Home    |    View Topics    |    Search    |    Contact Us    |    Help    |   

SecurityTracker
Archives


Welcome to SecurityTracker!
 
Click to Sign Up
Sign Up
Sign Up for Your FREE Weekly SecurityTracker E-mail Alert Summary
Instant Alerts
Buy our Premium Vulnerability Notification Service to receive customized, instant alerts
Affiliates
Put SecurityTracker Vulnerability Alerts on Your Web Site -- It's Free!
Partners
Become a Partner and License Our Database or Notification Service
Report a Bug
Report a vulnerability that you have found to SecurityTracker
bugs
@
securitytracker.com

Sign Up!





Category:  OS (Linux)  >  Linux Kernel Vendors:  kernel.org
Linux Kernel Deadlock Error in futex Functions Let Local Users Deny Service
SecurityTracker Alert ID:  1013616
SecurityTracker URL:  http://securitytracker.com/id?1013616
CVE Reference:  CAN-2005-0937   (Links to External Site)
Date:  Mar 31 2005
Impact:  Denial of service via local system
Fix Available:  Yes   Vendor Confirmed:  Yes  
Version(s): 2.6
Description:  A vulnerability was reported in the LInux kernel futex functions. A local user can cause the kernel to crash.

Some kernel futex functions invoke get_user() calls while holding mmap_sem for reading. If a get_user() function fails while another thread is in mmap, then the do_page_fault() function will deadlock.

Another similar deadlock condition may occur.

A local user can exploit this to cause denial of service conditions on the target system.

The flaw resides in 'kernel/futex.c'.

Olof Johansson reported this vulnerability.

Impact:  A local user can cause the target system to crash.
Solution:  A development patch (and changeset) is available, as described at:

http://lkml.org/lkml/2005/2/22/185

Vendor URL:  www.kernel.org/ (Links to External Site)
Cause:  State error
Underlying OS:  Linux (Caldera/SCO), Linux (Conectiva), Linux (Debian), Linux (EnGarde), Linux (Gentoo), Linux (HP Secure OS), Linux (Immunix), Linux (Mandrake), Linux (Progeny Debian), Linux (Red Hat Enterprise), Linux (Red Hat Fedora), Linux (Red Hat Linux), Linux (SGI), Linux (Slackware), Linux (Sun), Linux (SuSE), Linux (Trustix), Linux (Turbo Linux), Linux (Ubuntu), Linux (Xandros)
Reported By:  Olof Johansson <user@domain.name>
Message History:   None.


 Source Message Contents

Date:  Tue, 22 Feb 2005 16:42:56 -0600
From:  Olof Johansson <user@domain.name>
Subject:  Re: [PATCH/RFC] Futex mmap_sem deadlock

 
 
On Tue, Feb 22, 2005 at 10:34:57PM +0000, Jamie Lokier wrote:
> There is one small but important error: the "return ret" mustn't just
> return.  It must call unqueue_me(&q) just like the code at out_unqueue,
> _including_ the conditional "ret = 0", but _excluding_ the up_read().
Not only that, but someone might already have dequeued us, right? It's
probably a pathological case though, i.e. someone did a wake on the same
(bad) address.
 
How's this patch? It's closer to Linus' pseudo-code than Andrew's, to
avoid the extra get_user() at function entry and keep the common case
path short.
 
It also includes the feedback from Andrew on the sys_get_mempolicy(),
making the patch even simpler there.
 
----
 
Some futex functions do get_user calls while holding mmap_sem for
reading. If get_user() faults, and another thread happens to be in mmap
(or somewhere else holding waiting on down_write for the same semaphore),
then do_page_fault will deadlock. Most architectures seem to be exposed
to this.
 
To avoid it, make sure the page is available. If not, release the
semaphore, fault it in and retry.
 
I also found another exposure by inspection, moving some of the code
around avoids the possible deadlock there.
 
Signed-off-by: Olof Johansson <olof@austin.ibm.com>
 
 
Index: linux-2.5/kernel/futex.c
===================================================================
--- linux-2.5.orig/kernel/futex.c	2005-02-21 16:09:38.000000000 -0600
+++ linux-2.5/kernel/futex.c	2005-02-22 16:38:24.000000000 -0600
@@ -329,6 +329,7 @@
 	int ret, drop_count = 0;
 	unsigned int nqueued;
 
+ retry:
 	down_read(&current->mm->mmap_sem);
 
 	ret = get_futex_key(uaddr1, &key1);
@@ -355,9 +356,19 @@
 		   before *uaddr1.  */
 		smp_mb();
 
-		if (get_user(curval, (int __user *)uaddr1) != 0) {
-			ret = -EFAULT;
-			goto out;
+		inc_preempt_count();
+		ret = get_user(curval, (int __user *)uaddr1);
+		dec_preempt_count();
+
+		if (unlikely(ret)) {
+			up_read(&current->mm->mmap_sem);
+			/* Re-do the access outside the lock */
+			ret = get_user(curval, (int __user *)uaddr1);
+
+			if (!ret)
+				goto retry;
+
+			return ret;
 		}
 		if (curval != *valp) {
 			ret = -EAGAIN;
@@ -480,6 +491,7 @@
 	int ret, curval;
 	struct futex_q q;
 
+ retry:
 	down_read(&current->mm->mmap_sem);
 
 	ret = get_futex_key(uaddr, &q.key);
@@ -508,9 +520,21 @@
 	 * We hold the mmap semaphore, so the mapping cannot have changed
 	 * since we looked it up in get_futex_key.
 	 */
-	if (get_user(curval, (int __user *)uaddr) != 0) {
-		ret = -EFAULT;
-		goto out_unqueue;
+	inc_preempt_count();
+	ret = get_user(curval, (int __user *)uaddr);
+	dec_preempt_count();
+	if (unlikely(ret)) {
+		up_read(&current->mm->mmap_sem);
+
+		if (!unqueue_me(&q)) /* There's a chance we got woken already */
+			return 0;
+
+		/* Re-do the access outside the lock */
+		ret = get_user(curval, (int __user *)uaddr);
+
+		if (!ret)
+			goto retry;
+		return ret;
 	}
 	if (curval != val) {
 		ret = -EWOULDBLOCK;
Index: linux-2.5/mm/mempolicy.c
===================================================================
--- linux-2.5.orig/mm/mempolicy.c	2005-02-04 00:27:40.000000000 -0600
+++ linux-2.5/mm/mempolicy.c	2005-02-22 14:34:19.000000000 -0600
@@ -524,9 +524,13 @@
 	} else
 		pval = pol->policy;
 
-	err = -EFAULT;
+	if (vma) {
+		up_read(&current->mm->mmap_sem);
+		vma = NULL;
+	}
+
 	if (policy && put_user(pval, policy))
-		goto out;
+		return -EFAULT;
 
 	err = 0;
 	if (nmask) {
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
 


Go to the Top of This SecurityTracker Archive Page





Home   |    View Topics   |    Search   |    Contact Us   |    Help

Copyright 2005, SecurityGlobal.net LLC