summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2015-06-02 12:39:17 +0200
committerAmitay Isaacs <amitay@samba.org>2015-06-12 12:40:54 +0200
commita2690bc3f4e28a2ed50ccb47cb404fc8570fde6d (patch)
tree548174fcc71373f63758a0489f9779249bf89f9c
parent89849c4d31c0bb0c47864e11abc89efe7d812d87 (diff)
downloadsamba-a2690bc3f4e28a2ed50ccb47cb404fc8570fde6d.tar.gz
ctdb-locking: make process_callbacks() more robust
We should not dereference lock_ctx after invoking the callback in the auto_mark == false case. The callback could have destroyed it. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11293 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Amitay Isaacs <amitay@gmail.com>
-rw-r--r--ctdb/server/ctdb_lock.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/ctdb/server/ctdb_lock.c b/ctdb/server/ctdb_lock.c
index 8b3206d4b65..6a79e209232 100644
--- a/ctdb/server/ctdb_lock.c
+++ b/ctdb/server/ctdb_lock.c
@@ -334,8 +334,9 @@ static int ctdb_lock_request_destructor(struct lock_request *lock_request)
static void process_callbacks(struct lock_context *lock_ctx, bool locked)
{
struct lock_request *request;
+ bool auto_mark = lock_ctx->auto_mark;
- if (lock_ctx->auto_mark && locked) {
+ if (auto_mark && locked) {
switch (lock_ctx->type) {
case LOCK_RECORD:
tdb_chainlock_mark(lock_ctx->ctdb_db->ltdb->tdb, lock_ctx->key);
@@ -356,7 +357,7 @@ static void process_callbacks(struct lock_context *lock_ctx, bool locked)
}
request = lock_ctx->request;
- if (lock_ctx->auto_mark) {
+ if (auto_mark) {
/* Since request may be freed in the callback, unset the lock
* context, so request destructor will not free lock context.
*/
@@ -368,7 +369,11 @@ static void process_callbacks(struct lock_context *lock_ctx, bool locked)
request->callback(request->private_data, locked);
- if (lock_ctx->auto_mark && locked) {
+ if (!auto_mark) {
+ return;
+ }
+
+ if (locked) {
switch (lock_ctx->type) {
case LOCK_RECORD:
tdb_chainlock_unmark(lock_ctx->ctdb_db->ltdb->tdb, lock_ctx->key);