]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
auth: Fix crash when user iteration request is queued
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Tue, 19 Apr 2022 08:40:52 +0000 (11:40 +0300)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Thu, 21 Apr 2022 07:45:56 +0000 (07:45 +0000)
auth_worker_call() returns NULL when the request couldn't be handled
immediately, which would result in NULL pointer dereference later on.

src/auth/userdb-blocking.c

index 0cd2d2350269f00af819d5456028d67c71543ada..9f928e740f22a19a101a6eaf3f266b3cf6b7cc86 100644 (file)
@@ -71,11 +71,13 @@ void userdb_blocking_lookup(struct auth_request *request)
                         str_c(str), user_callback, request);
 }
 
-static bool iter_callback(struct auth_worker_connection *conn ATTR_UNUSED,
+static bool iter_callback(struct auth_worker_connection *conn,
                          const char *reply, void *context)
 {
        struct blocking_userdb_iterate_context *ctx = context;
 
+       ctx->conn = conn;
+
        if (str_begins(reply, "*\t")) {
                if (ctx->destroyed)
                        return TRUE;
@@ -109,8 +111,8 @@ userdb_blocking_iter_init(struct auth_request *request,
        ctx->ctx.context = context;
 
        auth_request_ref(request);
-       ctx->conn = auth_worker_call(request->pool, "*",
-                                    str_c(str), iter_callback, ctx);
+       auth_worker_call(request->pool, "*",
+                        str_c(str), iter_callback, ctx);
        return &ctx->ctx;
 }
 
@@ -119,6 +121,8 @@ void userdb_blocking_iter_next(struct userdb_iterate_context *_ctx)
        struct blocking_userdb_iterate_context *ctx =
                (struct blocking_userdb_iterate_context *)_ctx;
 
+       i_assert(ctx->conn != NULL);
+
        ctx->next = TRUE;
        auth_worker_server_resume_input(ctx->conn);
 }
@@ -134,6 +138,7 @@ int userdb_blocking_iter_deinit(struct userdb_iterate_context **_ctx)
        /* iter_callback() may still be called */
        ctx->destroyed = TRUE;
 
-       auth_worker_server_resume_input(ctx->conn);
+       if (ctx->conn != NULL)
+               auth_worker_server_resume_input(ctx->conn);
        return ret;
 }