1 From c78a87d0a1fc885dfdbe21fd5e07787691dfb068 Mon Sep 17 00:00:00 2001
2 From: David Teigland <teigland@redhat.com>
3 Date: Thu, 18 Jun 2009 13:20:24 -0500
4 Subject: [PATCH] dlm: fix plock use-after-free
6 Fix a regression from the original addition of nfs lock support
7 586759f03e2e9031ac5589912a51a909ed53c30a. When a synchronous
8 (non-nfs) plock completes, the waiting thread will wake up and
9 free the op struct. This races with the user thread in
10 dev_write() which goes on to read the op's callback field to
11 check if the lock is async and needs a callback. This check
12 can happen on the freed op. The fix is to note the callback
13 value before the op can be freed.
15 Signed-off-by: David Teigland <teigland@redhat.com>
16 Signed-off-by: Coly Li <coly.li@suse.de>
18 fs/dlm/plock.c | 17 ++++++++++-------
19 1 files changed, 10 insertions(+), 7 deletions(-)
21 diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c
22 index 894a32d..16f682e 100644
25 @@ -353,7 +353,7 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
27 struct dlm_plock_info info;
30 + int found = 0, do_callback = 0;
32 if (count != sizeof(info))
34 @@ -366,21 +366,24 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
37 list_for_each_entry(op, &recv_list, list) {
38 - if (op->info.fsid == info.fsid && op->info.number == info.number &&
39 + if (op->info.fsid == info.fsid &&
40 + op->info.number == info.number &&
41 op->info.owner == info.owner) {
42 + struct plock_xop *xop = (struct plock_xop *)op;
43 list_del_init(&op->list);
46 memcpy(&op->info, &info, sizeof(info));
55 spin_unlock(&ops_lock);
58 - struct plock_xop *xop;
59 - xop = (struct plock_xop *)op;
62 dlm_plock_callback(op);