CVE-2026-44640
Description
NanoMQ MQTT Broker (NanoMQ) is an all-around Edge Messaging Platform. Prior to 0.24.14, aio->prov_data is stored as nni_quic_conn* during dialing, but read as ex_quic_conn* during dialer close. This type confusion causes invalid object interpretation and leads to close-path hang/crash behavior. This vulnerability is fixed in 0.24.14.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
NanoMQ prior to 0.24.14 has a type confusion in QUIC dialer close that can cause hang or crash.
Vulnerability
In NanoMQ versions prior to 0.24.14, the QUIC dialer close path suffers from a type confusion bug. During dialing, aio->prov_data is stored as a nni_quic_conn* pointer, but during dialer close it is read as ex_quic_conn*. This mismatch leads to invalid object interpretation. The vulnerable code is in nng/src/supplemental/quic/msquic_dial.c [2]. Affected versions: all before 0.24.14.
Exploitation
An attacker can trigger this vulnerability by initiating a QUIC dialer connection to a target and then immediately closing the dialer. The provided PoC demonstrates this: allocate a dialer, start a dial, then close the dialer. No authentication or special privileges are required; the attacker only needs network access to the broker's QUIC endpoint. The race window is minimal as the close happens immediately after dial start.
Impact
Successful exploitation results in a hang or crash of the NanoMQ broker process. This constitutes a denial-of-service (DoS) condition. The type confusion can cause memory corruption, leading to undefined behavior. No remote code execution or data disclosure is indicated in the advisory.
Mitigation
The vulnerability is fixed in NanoMQ version 0.24.14, released on 2026-05-29 [1]. Users should upgrade to this version or later. No workarounds are provided. The advisory does not list this CVE in CISA KEV.
AI Insight generated on May 29, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
2Patches
2bf989bd39cd3* FIX [rest_api] Free `data_info` before returning parameter errors and valid `proto_ver`
2 files changed · +51 −12
fuzz/fuzz_rest_api.c+38 −0 modified@@ -113,12 +113,43 @@ fuzz_rest_api_detailed_cleanup(void) } } +static void +run_clients_query_regression_cases(void) +{ + static const char *cases[] = { + "/api/v4/clients?proto_ver=0", + "/api/v4/clients?proto_ver=6", + "/api/v4/clients?clean_start=maybe", + "/api/v4/clients?foo=bar", + "/api/v4/clients?proto_ver=3", + "/api/v4/clients?proto_ver=4", + "/api/v4/clients?proto_ver=5", + }; + + g_conf.http_server.auth_type = NONE_AUTH; + set_http_server_conf(&g_conf.http_server); + + nng_socket sock = { 0 }; + g_conf.http_server.broker_sock = &sock; + + for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) { + http_msg req = { 0 }; + put_http_msg( + &req, "application/json", "GET", cases[i], NULL, "", 0); + + http_msg resp = process_request(&req, &g_conf.http_server, &sock); + destory_http_msg(&resp); + destory_http_msg(&req); + } +} + int LLVMFuzzerInitialize(int *argc, char ***argv) { (void) argc; (void) argv; ensure_inited(); + run_clients_query_regression_cases(); atexit(fuzz_rest_api_detailed_cleanup); return 0; } @@ -168,6 +199,13 @@ static const char *uri_templates[] = { "/logs/full", "/platform_infos", "/clients", + "/clients?proto_ver=0", + "/clients?proto_ver=6", + "/clients?clean_start=maybe", + "/clients?foo=bar", + "/clients?proto_ver=3", + "/clients?proto_ver=4", + "/clients?proto_ver=5", "/clients/%s", "/clients/username/%s", "/subscriptions",
nanomq/rest_api.c+13 −12 modified@@ -1505,9 +1505,7 @@ get_clients(http_msg *msg, kv **params, size_t param_num, "disconnected") == 0) { info.conn_state = "disconnected"; } else { - return error_response(msg, - NNG_HTTP_STATUS_BAD_REQUEST, - REQ_PARAM_ERROR); + goto bad_request; } } else if (strcmp(params[i]->key, "clean_start") == 0) { if (nng_strcasecmp(params[i]->value, "true") == 0) { @@ -1518,9 +1516,7 @@ get_clients(http_msg *msg, kv **params, size_t param_num, info.clean_start = false; info.has_clean_start = true; } else { - return error_response(msg, - NNG_HTTP_STATUS_BAD_REQUEST, - REQ_PARAM_ERROR); + goto bad_request; } } else if (strcmp(params[i]->key, "proto_name") == 0) { info.proto_name = params[i]->value; @@ -1529,20 +1525,25 @@ get_clients(http_msg *msg, kv **params, size_t param_num, int ver = 0; if (sscanf(params[i]->value, "%d%c", &ver, &extra) != 1 || - ver < 0 || ver > UINT8_MAX) { - return error_response(msg, - NNG_HTTP_STATUS_BAD_REQUEST, - REQ_PARAM_ERROR); + ver < 0 || ver > UINT8_MAX || + (ver != MQTT_PROTOCOL_VERSION_v31 && + ver != MQTT_PROTOCOL_VERSION_v311 && + ver != MQTT_PROTOCOL_VERSION_v5)) { + goto bad_request; } info.proto_ver = (uint8_t) ver; info.has_proto_ver = true; } else { - return error_response( - msg, NNG_HTTP_STATUS_BAD_REQUEST, REQ_PARAM_ERROR); + goto bad_request; } } nng_id_map_foreach2(pipe_id_map, get_client_cb, &info); + goto out; + +bad_request: + cJSON_Delete(data_info); + return error_response(msg, NNG_HTTP_STATUS_BAD_REQUEST, REQ_PARAM_ERROR); out:
16bdb38921e7* FIX [devops] fix windows yaml workflow
1 file changed · +10 −4
.github/workflows/windows.yml+10 −4 modified@@ -44,12 +44,18 @@ jobs: - name: Configure run: | - $extra_flags = "" - if ("${{ matrix.arch }}" -eq "arm64") { - $extra_flags = "-A ARM64" + if (Test-Path build/CMakeCache.txt) { + Remove-Item build/CMakeCache.txt -Force + } + if (Test-Path build/CMakeFiles) { + Remove-Item -Recurse -Force build/CMakeFiles } - cmake -B build -DNNG_ENABLE_SQLITE=ON -DENABLE_RULE_ENGINE=ON -DENABLE_JWT=ON -DBUILD_BENCH=ON -DCMAKE_INSTALL_PREFIX=install $extra_flags + if ("${{ matrix.arch }}" -eq "arm64") { + cmake -B build -DNNG_ENABLE_SQLITE=ON -DENABLE_RULE_ENGINE=ON -DENABLE_JWT=ON -DBUILD_BENCH=ON -DCMAKE_INSTALL_PREFIX=install -A ARM64 + } else { + cmake -B build -DNNG_ENABLE_SQLITE=ON -DENABLE_RULE_ENGINE=ON -DENABLE_JWT=ON -DBUILD_BENCH=ON -DCMAKE_INSTALL_PREFIX=install + } - name: Build run: cmake --build build --config Release --target install
Vulnerability mechanics
Root cause
"Type confusion in the QUIC dialer close path: `aio->prov_data` is stored as `nni_quic_conn*` but read as `ex_quic_conn*`."
Attack vector
An attacker who can trigger a QUIC dialer close while a dial AIO is pending will cause the close path to misinterpret the stored pointer. The PoC shows that calling `nng_stream_dialer_close` immediately after `nng_stream_dialer_dial` (without waiting for the dial to complete) leads to a hang or crash. The precondition is local access to the NanoMQ process and the ability to initiate a QUIC dialer connection [ref_id=1].
Affected code
The vulnerability resides in `nng/src/supplemental/quic/msquic_dial.c`. The write site at approximately line 525 stores an `nni_quic_conn*` pointer via `nni_aio_set_prov_data(aio, c)`, but the read site at approximately lines 582-587 retrieves it as an `ex_quic_conn*` pointer via `nni_aio_get_prov_data(aio)`, causing a type confusion.
What the fix does
The advisory does not include a patch diff, but the fix in version 0.24.14 ensures that the pointer stored in `aio->prov_data` is read with the correct type (`nni_quic_conn*`) on the close path, or that the close path no longer dereferences the provider data as `ex_quic_conn*`. This eliminates the invalid object interpretation that caused the hang/crash [ref_id=1].
Preconditions
- inputThe attacker must be able to trigger a QUIC dialer close while a dial AIO is still pending (i.e., before the dial completes).
- authLocal access to the NanoMQ process is required to invoke the dialer operations.
Reproduction
The advisory provides a complete PoC program that allocates a dialer, starts a dial with a 1-second timeout, immediately closes the dialer, and then frees resources. When compiled with ASAN and the QUIC library, the process hangs after printing `[PoC] close dialer now` and is terminated by a timeout watchdog [ref_id=1].
Generated on May 29, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
2News mentions
0No linked articles in our index yet.