diff mbox

[3.8.y.z,extended,stable] Patch "lockd: protect nlm_blocked access in nlmsvc_retry_blocked" has been added to staging queue

Message ID 1374100186-5342-1-git-send-email-kamal@canonical.com
State New
Headers show

Commit Message

Kamal Mostafa July 17, 2013, 10:29 p.m. UTC
This is a note to let you know that I have just added a patch titled

    lockd: protect nlm_blocked access in nlmsvc_retry_blocked

to the linux-3.8.y-queue branch of the 3.8.y.z extended stable tree 
which can be found at:

 http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.8.y-queue

This patch is scheduled to be released in version 3.8.13.5.

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.8.y.z tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable

Thanks.
-Kamal

------

From 1c3b7abfda9ec1267d8d35a0449c9549e96f016d Mon Sep 17 00:00:00 2001
From: David Jeffery <djeffery@redhat.com>
Date: Wed, 10 Jul 2013 13:19:50 -0400
Subject: lockd: protect nlm_blocked access in nlmsvc_retry_blocked

commit 1c327d962fc420aea046c16215a552710bde8231 upstream.

In nlmsvc_retry_blocked, the check that the list is non-empty and acquiring
the pointer of the first entry is unprotected by any lock.  This allows a rare
race condition when there is only one entry on the list.  A function such as
nlmsvc_grant_callback() can be called, which will temporarily remove the entry
from the list.  Between the list_empty() and list_entry(),the list may become
empty, causing an invalid pointer to be used as an nlm_block, leading to a
possible crash.

This patch adds the nlm_block_lock around these calls to prevent concurrent
use of the nlm_blocked list.

This was a regression introduced by
f904be9cc77f361d37d71468b13ff3d1a1823dea  "lockd: Mostly remove BKL from
the server".

Cc: Bryan Schumaker <bjschuma@netapp.com>
Signed-off-by: David Jeffery <djeffery@redhat.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
---
 fs/lockd/svclock.c | 4 ++++
 1 file changed, 4 insertions(+)

--
1.8.1.2
diff mbox

Patch

diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 8d80c99..57a3922 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -939,6 +939,7 @@  nlmsvc_retry_blocked(void)
 	unsigned long	timeout = MAX_SCHEDULE_TIMEOUT;
 	struct nlm_block *block;

+	spin_lock(&nlm_blocked_lock);
 	while (!list_empty(&nlm_blocked) && !kthread_should_stop()) {
 		block = list_entry(nlm_blocked.next, struct nlm_block, b_list);

@@ -948,6 +949,7 @@  nlmsvc_retry_blocked(void)
 			timeout = block->b_when - jiffies;
 			break;
 		}
+		spin_unlock(&nlm_blocked_lock);

 		dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n",
 			block, block->b_when);
@@ -957,7 +959,9 @@  nlmsvc_retry_blocked(void)
 			retry_deferred_block(block);
 		} else
 			nlmsvc_grant_blocked(block);
+		spin_lock(&nlm_blocked_lock);
 	}
+	spin_unlock(&nlm_blocked_lock);

 	return timeout;
 }