locking: make process_callbacks() more robust
authorStefan Metzmacher <metze@samba.org>
Tue, 2 Jun 2015 10:39:17 +0000 (12:39 +0200)
committerAmitay Isaacs <amitay@gmail.com>
Mon, 15 Jun 2015 02:13:01 +0000 (12:13 +1000)
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>
(Imported from commit a2690bc3f4e28a2ed50ccb47cb404fc8570fde6d)

server/ctdb_lock.c

index 397c11b85d84b9d0d62da963da5b7efd6fa3ef06..3db31998fb8fd26ae03e4e6de42737723121ebda 100644 (file)
@@ -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);