-
Notifications
You must be signed in to change notification settings - Fork 171
Broker, client, and MQTT v5 packet validation and reliability fixes #552
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
ccce7eb
60d20f6
57cfd36
1ef1d06
2581a2c
d46da08
b455240
5b97a8d
337f88d
2c5ce32
d9e79ce
087d9f0
c829dbc
154bfae
be003af
61870fb
dc8ab1e
356fd47
0154f26
dcbc2c0
ab130c2
0fb17bc
6bec2fb
41dabde
bd8104d
7e14290
abb3dcc
bf581a1
9447505
3004ba9
c138692
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -118,13 +118,30 @@ static int fw_message_process(MQTTCtx *mqttCtx, byte* buffer, word32 len) | |
| #ifdef ENABLE_FIRMWARE_SIG | ||
| ecc_key eccKey; | ||
| #endif | ||
| word32 check_len = sizeof(FirmwareHeader) + header->sigLen + | ||
| header->pubKeyLen + header->fwLen; | ||
| word32 remaining; | ||
|
|
||
| /* Verify entire message was received */ | ||
| if (len != check_len) { | ||
| PRINTF("Message header vs. actual size mismatch! %d != %d", | ||
| len, check_len); | ||
| /* Validate sequentially; a summed length check overflows word32 for | ||
| * attacker-chosen fwLen (CWE-190 -> heap OOB on pubKeyBuf/fwBuf). */ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove CWE reference |
||
| if (len < sizeof(FirmwareHeader)) { | ||
| PRINTF("Message smaller than firmware header! %u", (unsigned int)len); | ||
| return EXIT_FAILURE; | ||
| } | ||
| remaining = len - sizeof(FirmwareHeader); | ||
| if (header->sigLen > remaining) { | ||
| PRINTF("Firmware sigLen exceeds message! %u", | ||
| (unsigned int)header->sigLen); | ||
| return EXIT_FAILURE; | ||
| } | ||
| remaining -= header->sigLen; | ||
| if (header->pubKeyLen > remaining) { | ||
| PRINTF("Firmware pubKeyLen exceeds message! %u", | ||
| (unsigned int)header->pubKeyLen); | ||
| return EXIT_FAILURE; | ||
| } | ||
| remaining -= header->pubKeyLen; | ||
| if (header->fwLen != remaining) { | ||
| PRINTF("Message header vs. actual size mismatch! %u != %u", | ||
| (unsigned int)header->fwLen, (unsigned int)remaining); | ||
| return EXIT_FAILURE; | ||
| } | ||
|
|
||
|
|
@@ -172,10 +189,13 @@ static int mqtt_message_cb(MqttClient *client, MqttMessage *msg, | |
| { | ||
| MQTTCtx* mqttCtx = (MQTTCtx*)client->ctx; | ||
|
|
||
| /* Verify this message is for the firmware topic */ | ||
| /* Verify this message is for the firmware topic. Compare against the full | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Too wordy for the example. Revert this comment to the original. |
||
| * expected length (not the wire-supplied topic_name_len) so a zero-length | ||
| * (v5 Topic Alias) or byte-prefix topic cannot pass the gate. */ | ||
| if (msg_new && | ||
| msg->topic_name_len == (word16)XSTRLEN(mqttCtx->topic_name) && | ||
| XSTRNCMP(msg->topic_name, mqttCtx->topic_name, | ||
| msg->topic_name_len) == 0 && | ||
| XSTRLEN(mqttCtx->topic_name)) == 0 && | ||
| !mFwBuf) | ||
| { | ||
| /* Allocate buffer for entire message */ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -68,8 +68,13 @@ static int callback_mqtt(struct lws *wsi, enum lws_callback_reasons reason, | |
| else if (reason == LWS_CALLBACK_CLIENT_CONNECTION_ERROR) { | ||
| net->status = -1; | ||
| } | ||
| else if (reason == LWS_CALLBACK_CLOSED) { | ||
| else if (reason == LWS_CALLBACK_CLOSED || | ||
| reason == LWS_CALLBACK_CLIENT_CLOSED) { | ||
| net->status = 0; | ||
| /* libwebsockets frees the wsi after this callback returns; clear the | ||
| * dangling pointer so NetWebsocket_Disconnect's `if (net->wsi)` guard | ||
| * skips lws_close_reason() on freed memory (CWE-416). */ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove CWE reference |
||
| net->wsi = NULL; | ||
| } | ||
| else if (reason == LWS_CALLBACK_CLIENT_RECEIVE) { | ||
| if (in && len > 0) { | ||
|
|
@@ -185,8 +190,13 @@ int NetWebsocket_Connect(void *ctx, const char* host, word16 port, | |
| /* Set SSL options for the connection if TLS is enabled */ | ||
| if (mqttCtx && mqttCtx->use_tls) { | ||
| conn_info.ssl_connection = LCCSCF_USE_SSL; | ||
| conn_info.ssl_connection |= LCCSCF_ALLOW_SELFSIGNED; | ||
| conn_info.ssl_connection |= LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK; | ||
| /* Only relax verification when no CA was supplied (dev/self-signed). | ||
| * When the operator provides a CA via -A, perform full chain and | ||
| * hostname verification rather than silently disabling it. */ | ||
| if (mqttCtx->ca_file == NULL) { | ||
| conn_info.ssl_connection |= LCCSCF_ALLOW_SELFSIGNED; | ||
| conn_info.ssl_connection |= LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK; | ||
| } | ||
| } | ||
| #endif /* ENABLE_MQTT_TLS */ | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove CWE reference