+++ /dev/null
-From c78a87d0a1fc885dfdbe21fd5e07787691dfb068 Mon Sep 17 00:00:00 2001
-From: David Teigland <teigland@redhat.com>
-Date: Thu, 18 Jun 2009 13:20:24 -0500
-Subject: [PATCH] dlm: fix plock use-after-free
-
-Fix a regression from the original addition of nfs lock support
-586759f03e2e9031ac5589912a51a909ed53c30a. When a synchronous
-(non-nfs) plock completes, the waiting thread will wake up and
-free the op struct. This races with the user thread in
-dev_write() which goes on to read the op's callback field to
-check if the lock is async and needs a callback. This check
-can happen on the freed op. The fix is to note the callback
-value before the op can be freed.
-
-Signed-off-by: David Teigland <teigland@redhat.com>
-Signed-off-by: Coly Li <coly.li@suse.de>
----
- fs/dlm/plock.c | 17 ++++++++++-------
- 1 files changed, 10 insertions(+), 7 deletions(-)
-
-diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c
-index 894a32d..16f682e 100644
---- a/fs/dlm/plock.c
-+++ b/fs/dlm/plock.c
-@@ -353,7 +353,7 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
- {
- struct dlm_plock_info info;
- struct plock_op *op;
-- int found = 0;
-+ int found = 0, do_callback = 0;
-
- if (count != sizeof(info))
- return -EINVAL;
-@@ -366,21 +366,24 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
-
- spin_lock(&ops_lock);
- list_for_each_entry(op, &recv_list, list) {
-- if (op->info.fsid == info.fsid && op->info.number == info.number &&
-+ if (op->info.fsid == info.fsid &&
-+ op->info.number == info.number &&
- op->info.owner == info.owner) {
-+ struct plock_xop *xop = (struct plock_xop *)op;
- list_del_init(&op->list);
-- found = 1;
-- op->done = 1;
- memcpy(&op->info, &info, sizeof(info));
-+ if (xop->callback)
-+ do_callback = 1;
-+ else
-+ op->done = 1;
-+ found = 1;
- break;
- }
- }
- spin_unlock(&ops_lock);
-
- if (found) {
-- struct plock_xop *xop;
-- xop = (struct plock_xop *)op;
-- if (xop->callback)
-+ if (do_callback)
- dlm_plock_callback(op);
- else
- wake_up(&recv_wq);
---
-1.6.0.2
-