diff options
author | Stefan Metzmacher <metze@samba.org> | 2015-06-02 12:39:17 +0200 |
---|---|---|
committer | Amitay Isaacs <amitay@samba.org> | 2015-06-12 12:40:54 +0200 |
commit | a2690bc3f4e28a2ed50ccb47cb404fc8570fde6d (patch) | |
tree | 548174fcc71373f63758a0489f9779249bf89f9c /ctdb/server/ctdb_lock.c | |
parent | 89849c4d31c0bb0c47864e11abc89efe7d812d87 (diff) | |
download | samba-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>
Diffstat (limited to 'ctdb/server/ctdb_lock.c')
-rw-r--r-- | ctdb/server/ctdb_lock.c | 11 |
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); |