]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-sasl: Enforce absolute limit on SASL message size for both client and server
authorStephan Bosch <stephan.bosch@open-xchange.com>
Tue, 28 Oct 2025 13:35:06 +0000 (14:35 +0100)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Fri, 31 Oct 2025 19:57:35 +0000 (19:57 +0000)
This is a second layer of defence against abuse. The real limit enforced by the
auth service can be (is) smaller. Additionally, these limits will make sure the
fuzzer does not time out.

OSS-Fuzz report: 455796070

src/lib-auth-client/auth-client-interface.h
src/lib-sasl/dsasl-client.c
src/lib-sasl/sasl-common.h
src/lib-sasl/sasl-server-request.c

index f4dce1db843947c3df798c1585413e27bbcddce0..b6425a7290c66424adf37f5bb58e55aaedb8781e 100644 (file)
 
 /* GSSAPI can use quite large packets */
 #define AUTH_CLIENT_MAX_LINE_LENGTH 16384
+/* Make sure AUTH_CLIENT_MAX_LINE_LENGTH does not exceed the absolute maximum */
+#if AUTH_CLIENT_MAX_LINE_LENGTH > SASL_MAX_MESSAGE_SIZE
+#  error "AUTH_CLIENT_MAX_LINE_LENGTH exceeds SASL_MAX_MESSAGE_SIZE"
+#endif
 
 /* auth failure codes */
 #define AUTH_CLIENT_FAIL_CODE_AUTHZFAILED       "authz_fail"
index b5932955cf003dc708a6e2d48ba808bfa99eaddf..bc111afb169f15cf0bbb6c2d6906f23632eec7d4 100644 (file)
@@ -124,6 +124,12 @@ dsasl_client_input(struct dsasl_client *client,
                *error_r = "Unexpected NUL in input data";
                return DSASL_CLIENT_RESULT_ERR_PROTOCOL;
        }
+       if (input_len > (size_t)SASL_MAX_MESSAGE_SIZE) {
+               *error_r = t_strdup_printf(
+                       "Excessive challenge size (> %d)",
+                       SASL_MAX_MESSAGE_SIZE);
+               return DSASL_CLIENT_RESULT_ERR_PROTOCOL;
+       }
        return client->mech->input(client, input, input_len, error_r);
 }
 
index d51c7ea31b58a00c4f2b22b39e752addccd6ee29..fff7373b3c31df09523ed9ea912ccd72acfda3ce 100644 (file)
@@ -1,6 +1,12 @@
 #ifndef SASL_COMMON_H
 #define SASL_COMMON_H
 
+/*
+ * Absolute limits
+ */
+
+#define SASL_MAX_MESSAGE_SIZE (64 * 1024)
+
 /*
  * Mechanism security flags
  */
index 6656fd216ff42686ee3f9bc3b499f177635c8712..7cfc4abc3d493e5073475aa83292efa4ad5752f1 100644 (file)
@@ -140,6 +140,22 @@ void sasl_server_request_destroy(struct sasl_server_req_ctx *rctx)
        sasl_server_request_unref(rctx);
 }
 
+static bool
+sasl_server_request_fail_on_size(struct sasl_server_request *req,
+                                size_t data_size)
+{
+       if (data_size > (size_t)SASL_MAX_MESSAGE_SIZE) {
+               /* We should normally never get here, because the limit enforced
+                  by the auth service is smaller.
+                */
+               e_debug(req->event, "Excessive response size (> %d)",
+                       SASL_MAX_MESSAGE_SIZE);
+               sasl_server_request_failure(req->mech);
+               return TRUE;
+       }
+       return FALSE;
+}
+
 static bool
 sasl_server_request_fail_on_nuls(struct sasl_server_request *req,
                                 const unsigned char *data, size_t data_size)
@@ -177,6 +193,8 @@ void sasl_server_request_initial(struct sasl_server_req_ctx *rctx,
        i_assert(req->state == SASL_SERVER_REQUEST_STATE_NEW);
        req->state = SASL_SERVER_REQUEST_STATE_SERVER;
 
+       if (sasl_server_request_fail_on_size(req, data_size))
+               return;
        if (sasl_server_request_fail_on_nuls(req, data, data_size))
                return;
 
@@ -212,6 +230,8 @@ void sasl_server_request_input(struct sasl_server_req_ctx *rctx,
        i_assert(!req->finished_with_data);
        req->state = SASL_SERVER_REQUEST_STATE_SERVER;
 
+       if (sasl_server_request_fail_on_size(req, data_size))
+               return;
        if (sasl_server_request_fail_on_nuls(req, data, data_size))
                return;