From 8d719f8e923f469a5395d58559177b35d54df24d Mon Sep 17 00:00:00 2001 From: Egor Tensin Date: Mon, 12 Jun 2023 01:23:24 +0200 Subject: command: fix a race condition Modifying cmd_dispatcher fields like that make it inherently unsafe to call cmd_dispatcher_handle_conn concurrently. --- src/command.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/command.c b/src/command.c index 55d60da..bd58f05 100644 --- a/src/command.c +++ b/src/command.c @@ -103,8 +103,8 @@ void cmd_dispatcher_destroy(struct cmd_dispatcher *dispatcher) free(dispatcher); } -int cmd_dispatcher_handle(const struct cmd_dispatcher *dispatcher, const struct msg *command, - struct msg **result) +static int cmd_dispatcher_handle_internal(const struct cmd_dispatcher *dispatcher, + const struct msg *command, struct msg **result, void *arg) { const char *actual_cmd = msg_get_first_string(command); @@ -114,7 +114,7 @@ int cmd_dispatcher_handle(const struct cmd_dispatcher *dispatcher, const struct if (strcmp(cmd->name, actual_cmd)) continue; - return cmd->handler(command, result, dispatcher->ctx); + return cmd->handler(command, result, arg); } log_err("Received an unknown command\n"); @@ -122,6 +122,12 @@ int cmd_dispatcher_handle(const struct cmd_dispatcher *dispatcher, const struct return -1; } +int cmd_dispatcher_handle(const struct cmd_dispatcher *dispatcher, const struct msg *command, + struct msg **result) +{ + return cmd_dispatcher_handle_internal(dispatcher, command, result, dispatcher->ctx); +} + int cmd_dispatcher_handle_conn(int conn_fd, void *_dispatcher) { struct cmd_dispatcher *dispatcher = (struct cmd_dispatcher *)_dispatcher; @@ -141,11 +147,7 @@ int cmd_dispatcher_handle_conn(int conn_fd, void *_dispatcher) if (ret < 0) goto free_ctx; - void *old_ctx = dispatcher->ctx; - dispatcher->ctx = new_ctx; - ret = cmd_dispatcher_handle(dispatcher, request, &response); - dispatcher->ctx = old_ctx; - + ret = cmd_dispatcher_handle_internal(dispatcher, request, &response, new_ctx); if (ret < 0) goto free_response; -- cgit v1.2.3