]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.fixes/dlm-fix-plock-use-after-free.patch
Fix oinkmaster patch.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.fixes / dlm-fix-plock-use-after-free.patch
CommitLineData
2cb7cef9
BS
1From c78a87d0a1fc885dfdbe21fd5e07787691dfb068 Mon Sep 17 00:00:00 2001
2From: David Teigland <teigland@redhat.com>
3Date: Thu, 18 Jun 2009 13:20:24 -0500
4Subject: [PATCH] dlm: fix plock use-after-free
5
6Fix a regression from the original addition of nfs lock support
7586759f03e2e9031ac5589912a51a909ed53c30a. When a synchronous
8(non-nfs) plock completes, the waiting thread will wake up and
9free the op struct. This races with the user thread in
10dev_write() which goes on to read the op's callback field to
11check if the lock is async and needs a callback. This check
12can happen on the freed op. The fix is to note the callback
13value before the op can be freed.
14
15Signed-off-by: David Teigland <teigland@redhat.com>
16Signed-off-by: Coly Li <coly.li@suse.de>
17---
18 fs/dlm/plock.c | 17 ++++++++++-------
19 1 files changed, 10 insertions(+), 7 deletions(-)
20
21diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c
22index 894a32d..16f682e 100644
23--- a/fs/dlm/plock.c
24+++ b/fs/dlm/plock.c
25@@ -353,7 +353,7 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
26 {
27 struct dlm_plock_info info;
28 struct plock_op *op;
29- int found = 0;
30+ int found = 0, do_callback = 0;
31
32 if (count != sizeof(info))
33 return -EINVAL;
34@@ -366,21 +366,24 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
35
36 spin_lock(&ops_lock);
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);
44- found = 1;
45- op->done = 1;
46 memcpy(&op->info, &info, sizeof(info));
47+ if (xop->callback)
48+ do_callback = 1;
49+ else
50+ op->done = 1;
51+ found = 1;
52 break;
53 }
54 }
55 spin_unlock(&ops_lock);
56
57 if (found) {
58- struct plock_xop *xop;
59- xop = (struct plock_xop *)op;
60- if (xop->callback)
61+ if (do_callback)
62 dlm_plock_callback(op);
63 else
64 wake_up(&recv_wq);
65--
661.6.0.2
67