From: Timo Sirainen Date: Thu, 11 Sep 2025 12:20:26 +0000 (+0300) Subject: auth: auth_fields_import_*() - Handle empty key without crashing X-Git-Tag: 2.4.2~416 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e198d3c452c6a6a368ee9d410797f3447cd598e6;p=thirdparty%2Fdovecot%2Fcore.git auth: auth_fields_import_*() - Handle empty key without crashing --- diff --git a/src/auth/auth-fields.c b/src/auth/auth-fields.c index 8b92836588..36d9cba3ef 100644 --- a/src/auth/auth-fields.c +++ b/src/auth/auth-fields.c @@ -115,12 +115,13 @@ void auth_fields_reset(struct auth_fields *fields) } } -static void auth_fields_import_prefixed_args(struct auth_fields *fields, - const char *prefix, - const char *const *args, - enum auth_field_flags flags) +static int auth_fields_import_prefixed_args(struct auth_fields *fields, + const char *prefix, + const char *const *args, + enum auth_field_flags flags) { const char *key, *value; + int ret = 0; for (; *args != NULL; args++) { value = strchr(*args, '='); @@ -131,26 +132,33 @@ static void auth_fields_import_prefixed_args(struct auth_fields *fields, if (*prefix != '\0') key = t_strconcat(prefix, key, NULL); } + if (key[0] == '\0') + ret = -1; auth_fields_add(fields, key, value, flags); } + return ret; } -void auth_fields_import_prefixed(struct auth_fields *fields, const char *prefix, - const char *str, enum auth_field_flags flags) +int auth_fields_import_prefixed(struct auth_fields *fields, const char *prefix, + const char *str, enum auth_field_flags flags) { + int ret; T_BEGIN { const char *const *arg = t_strsplit_tabescaped(str); - auth_fields_import_prefixed_args(fields, prefix, arg, flags); + ret = auth_fields_import_prefixed_args(fields, prefix, arg, flags); } T_END; + return ret; } -void auth_fields_import_args(struct auth_fields *fields, - const char *const *args, - enum auth_field_flags flags) +int auth_fields_import_args(struct auth_fields *fields, + const char *const *args, + enum auth_field_flags flags) { + int ret; T_BEGIN { - auth_fields_import_prefixed_args(fields, "", args, flags); + ret = auth_fields_import_prefixed_args(fields, "", args, flags); } T_END; + return ret; } const ARRAY_TYPE(auth_field) *auth_fields_export(struct auth_fields *fields) diff --git a/src/auth/auth-fields.h b/src/auth/auth-fields.h index 855f0ac475..e7f0e6e63c 100644 --- a/src/auth/auth-fields.h +++ b/src/auth/auth-fields.h @@ -26,11 +26,11 @@ void auth_fields_remove(struct auth_fields *fields, const char *key); const char *auth_fields_find(struct auth_fields *fields, const char *key); bool auth_fields_exists(struct auth_fields *fields, const char *key); -void auth_fields_import_args(struct auth_fields *fields, - const char *const *args, - enum auth_field_flags flags); -void auth_fields_import_prefixed(struct auth_fields *fields, const char *prefix, - const char *str, enum auth_field_flags flags); +int auth_fields_import_args(struct auth_fields *fields, + const char *const *args, + enum auth_field_flags flags); +int auth_fields_import_prefixed(struct auth_fields *fields, const char *prefix, + const char *str, enum auth_field_flags flags); const ARRAY_TYPE(auth_field) *auth_fields_export(struct auth_fields *fields); /* Append fields where (flag & flags_mask) == flags_result. */ void auth_fields_append(struct auth_fields *fields, string_t *dest, diff --git a/src/auth/auth-request-fields.c b/src/auth/auth-request-fields.c index 51e82aabcb..8a5fe8a1a6 100644 --- a/src/auth/auth-request-fields.c +++ b/src/auth/auth-request-fields.c @@ -208,8 +208,11 @@ bool auth_request_import_info(struct auth_request *request, fields->client_id = p_strdup(request->pool, value); event_add_str(event, "client_id", value); } else if (strcmp(key, "forward_fields") == 0) { - auth_fields_import_prefixed(fields->extra_fields, - "forward_", value, 0); + if (auth_fields_import_prefixed(fields->extra_fields, + "forward_", value, 0) < 0) { + e_error(request->event, + "Invalid forward_fields: %s", value); + } /* make sure the forward_ fields aren't deleted by auth_fields_rollback() if the first passdb lookup fails. */ auth_fields_snapshot(fields->extra_fields); diff --git a/src/auth/userdb-blocking.c b/src/auth/userdb-blocking.c index 5ce9523e1b..771efd8b2b 100644 --- a/src/auth/userdb-blocking.c +++ b/src/auth/userdb-blocking.c @@ -50,7 +50,11 @@ static bool user_callback(struct auth_worker_connection *conn ATTR_UNUSED, } if (args != NULL && args[0] != NULL && *args[0] != '\0') { - auth_fields_import_args(request->fields.userdb_reply, args, 0); + if (auth_fields_import_args(request->fields.userdb_reply, + args, 0) < 0) { + e_error(authdb_event(request), + "BUG: auth-worker sent invalid args"); + } if (auth_fields_exists(request->fields.userdb_reply, "tempfail")) request->userdb_lookup_tempfailed = TRUE; }