+ sysfs-fix-deadlock.patch added to -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled
     sysfs: fix deadlock
has been added to the -mm tree.  Its filename is
     sysfs-fix-deadlock.patch

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/SubmitChecklist when testing your code ***

See http://userweb.kernel.org/~akpm/added-to-mm.txt to find
out what to do about this

The current -mm tree may be found at http://userweb.kernel.org/~akpm/mmotm/

------------------------------------------------------
Subject: sysfs: fix deadlock
From: Nick Piggin <npiggin@xxxxxxx>

=======================================================
[ INFO: possible circular locking dependency detected ]
2.6.27-rc6-tip #1
-------------------------------------------------------
X/4873 is trying to acquire lock:
 (&bb->mutex){--..}, at: [<c020ba20>] mmap+0x40/0xa0

but task is already holding lock:
 (&mm->mmap_sem){----}, at: [<c0125a1e>] sys_mmap2+0x8e/0xc0

which lock already depends on the new lock.


the existing dependency chain (in reverse order) is:

-> #1 (&mm->mmap_sem){----}:
       [<c017dc96>] validate_chain+0xa96/0xf50
       [<c017ef2b>] __lock_acquire+0x2cb/0x5b0
       [<c017f299>] lock_acquire+0x89/0xc0
       [<c01aa8fb>] might_fault+0x6b/0x90
       [<c040b618>] copy_to_user+0x38/0x60
       [<c020bcfb>] read+0xfb/0x170
       [<c01c09a5>] vfs_read+0x95/0x110
       [<c01c1443>] sys_pread64+0x63/0x80
       [<c012146f>] sysenter_do_call+0x12/0x43
       [<ffffffff>] 0xffffffff

-> #0 (&bb->mutex){--..}:
       [<c017d8b7>] validate_chain+0x6b7/0xf50
       [<c017ef2b>] __lock_acquire+0x2cb/0x5b0
       [<c017f299>] lock_acquire+0x89/0xc0
       [<c0d6f2ab>] __mutex_lock_common+0xab/0x3c0
       [<c0d6f698>] mutex_lock_nested+0x38/0x50
       [<c020ba20>] mmap+0x40/0xa0
       [<c01b111e>] mmap_region+0x14e/0x450
       [<c01b170f>] do_mmap_pgoff+0x2ef/0x310
       [<c0125a3d>] sys_mmap2+0xad/0xc0
       [<c012146f>] sysenter_do_call+0x12/0x43
       [<ffffffff>] 0xffffffff

other info that might help us debug this:

1 lock held by X/4873:
 #0:  (&mm->mmap_sem){----}, at: [<c0125a1e>] sys_mmap2+0x8e/0xc0

stack backtrace:
Pid: 4873, comm: X Not tainted 2.6.27-rc6-tip #1
 [<c017cd09>] print_circular_bug_tail+0x79/0xc0
 [<c017d8b7>] validate_chain+0x6b7/0xf50
 [<c017a5b5>] ? trace_hardirqs_off_caller+0x15/0xb0
 [<c017ef2b>] __lock_acquire+0x2cb/0x5b0
 [<c017f299>] lock_acquire+0x89/0xc0
 [<c020ba20>] ? mmap+0x40/0xa0
 [<c0d6f2ab>] __mutex_lock_common+0xab/0x3c0
 [<c020ba20>] ? mmap+0x40/0xa0
 [<c0d6f698>] mutex_lock_nested+0x38/0x50
 [<c020ba20>] ? mmap+0x40/0xa0
 [<c020ba20>] mmap+0x40/0xa0
 [<c01b111e>] mmap_region+0x14e/0x450
 [<c01afb88>] ? arch_get_unmapped_area_topdown+0xf8/0x160
 [<c01b170f>] do_mmap_pgoff+0x2ef/0x310
 [<c0125a3d>] sys_mmap2+0xad/0xc0
 [<c012146f>] sysenter_do_call+0x12/0x43
 [<c0120000>] ? __switch_to+0x130/0x220
 =======================
evbug.c: Event. Dev: input3, Type: 20, Code: 0, Value: 500
warning: `sudo' uses deprecated v2 capabilities in a way that may be insecure.


bin.c takes bb->mutex under mmap_sem when it is mmapped, and then does its
copy_*_user under bb->mutex too.

Signed-off-by: Nick Piggin <npiggin@xxxxxxx>
Reported-by: Ingo Molnar <mingo@xxxxxxx>
Cc: Peter Zijlstra <a.p.zijlstra@xxxxxxxxx>
Cc: Greg KH <greg@xxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
---

 fs/sysfs/bin.c |   42 +++++++++++++++++++++++++++++++-----------
 1 file changed, 31 insertions(+), 11 deletions(-)

diff -puN fs/sysfs/bin.c~sysfs-fix-deadlock fs/sysfs/bin.c
--- a/fs/sysfs/bin.c~sysfs-fix-deadlock
+++ a/fs/sysfs/bin.c
@@ -61,6 +61,7 @@ read(struct file *file, char __user *use
 	int size = dentry->d_inode->i_size;
 	loff_t offs = *off;
 	int count = min_t(size_t, bytes, PAGE_SIZE);
+	char *temp;
 
 	if (size) {
 		if (offs > size)
@@ -69,23 +70,33 @@ read(struct file *file, char __user *use
 			count = size - offs;
 	}
 
+	temp = kmalloc(count, GFP_KERNEL);
+	if (!temp)
+		return -ENOMEM;
+
 	mutex_lock(&bb->mutex);
 
 	count = fill_read(dentry, bb->buffer, offs, count);
-	if (count < 0)
-		goto out_unlock;
+	if (count < 0) {
+		mutex_unlock(&bb->mutex);
+		goto out_free;
+	}
 
-	if (copy_to_user(userbuf, bb->buffer, count)) {
+	memcpy(temp, bb->buffer, count);
+
+	mutex_unlock(&bb->mutex);
+
+	if (copy_to_user(userbuf, temp, count)) {
 		count = -EFAULT;
-		goto out_unlock;
+		goto out_free;
 	}
 
 	pr_debug("offs = %lld, *off = %lld, count = %d\n", offs, *off, count);
 
 	*off = offs + count;
 
- out_unlock:
-	mutex_unlock(&bb->mutex);
+ out_free:
+	kfree(temp);
 	return count;
 }
 
@@ -118,6 +129,7 @@ static ssize_t write(struct file *file, 
 	int size = dentry->d_inode->i_size;
 	loff_t offs = *off;
 	int count = min_t(size_t, bytes, PAGE_SIZE);
+	char *temp;
 
 	if (size) {
 		if (offs > size)
@@ -126,19 +138,27 @@ static ssize_t write(struct file *file, 
 			count = size - offs;
 	}
 
-	mutex_lock(&bb->mutex);
+	temp = kmalloc(count, GFP_KERNEL);
+	if (!temp)
+		return -ENOMEM;
 
-	if (copy_from_user(bb->buffer, userbuf, count)) {
+	if (copy_from_user(temp, userbuf, count)) {
 		count = -EFAULT;
-		goto out_unlock;
+		goto out_free;
 	}
 
+	mutex_lock(&bb->mutex);
+
+	memcpy(bb->buffer, temp, count);
+
 	count = flush_write(dentry, bb->buffer, offs, count);
+	mutex_unlock(&bb->mutex);
+
 	if (count > 0)
 		*off = offs + count;
 
- out_unlock:
-	mutex_unlock(&bb->mutex);
+out_free:
+	kfree(temp);
 	return count;
 }
 
_

Patches currently in -mm which might be from npiggin@xxxxxxx are

linux-next.patch
sysfs-fix-deadlock.patch
inotify-fix-lock-ordering-wrt-do_page_faults-mmap_sem.patch
mm-tiny-shmem-fix-lor-mmap_sem-vs-i_mutex.patch
mm-tiny-shmem-fix-lor-mmap_sem-vs-i_mutex-checkpatch-fixes.patch
vmscan-move-isolate_lru_page-to-vmscanc.patch
mlock-mlocked-pages-are-unevictable.patch
mlock-mlocked-pages-are-unevictable-fix.patch
mmap-handle-mlocked-pages-during-map-remap-unmap.patch
vmstat-mlocked-pages-statistics.patch
mm-pagecache-insertion-fewer-atomics.patch
mm-unlockless-reclaim.patch
mm-page-lock-use-lock-bitops.patch
fs-buffer-lock-use-lock-bitops.patch
mm-page-allocator-minor-speedup.patch
mm-rewrite-vmap-layer.patch
mm-rewrite-vmap-layer-fix.patch
mm-rewrite-vmap-layer-fix-fix.patch
mm-rewrite-vmap-layer-fix-fix-fix.patch
reiser4.patch
likeliness-accounting-change-and-cleanup.patch

--
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux