Skip to content

Commit afd7962

Browse files
authored
Merge pull request wolfSSL#478 from embhorn/fenrir-fixes
Fenrir fixes
2 parents eb14efd + 0e1da90 commit afd7962

7 files changed

Lines changed: 209 additions & 87 deletions

File tree

.github/workflows/sec-websocket-test.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,16 @@ jobs:
4343

4444
- name: Download libwebsockets
4545
run: |
46-
git clone https://github.com/warmcat/libwebsockets
46+
git clone https://github.com/warmcat/libwebsockets --branch v4.3.3 --single-branch
4747
4848
- name: Build libwebsockets with wolfSSL
4949
run: |
5050
cd libwebsockets
5151
mkdir build
5252
cd build
53-
cmake .. -DLWS_WITH_WOLFSSL=1 -DLWS_WOLFSSL_INCLUDE_DIRS=/usr/local/include/wolfssl -DLWS_WOLFSSL_LIBRARIES=/usr/local/lib/libwolfssl.so -DLWS_WITH_EXTERNAL_POLL=1 ..
53+
# Note: -Wno-error=sign-conversion works around a sign mismatch in
54+
# libwebsockets v4.3.3 openssl-server.c:311 (lws_filepos_t -> long)
55+
cmake .. -DLWS_WITH_WOLFSSL=1 -DLWS_WOLFSSL_INCLUDE_DIRS=/usr/local/include/wolfssl -DLWS_WOLFSSL_LIBRARIES=/usr/local/lib/libwolfssl.so -DLWS_WITH_EXTERNAL_POLL=1 -DLWS_WITHOUT_TESTAPPS=ON -DCMAKE_C_FLAGS="-Wno-error=sign-conversion"
5456
make
5557
sudo make install
5658

src/mqtt_broker.c

Lines changed: 162 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,10 @@ static int BrokerStrCompare(const char* a, const char* b)
159159
for (i = 0; i < max_len; i++) {
160160
/* Branchless index clamp: when i >= len, reads position 0.
161161
* Length mismatch is caught by the final XOR below. */
162-
int ia = i & ((i - len_a) >> (sizeof(int) * 8 - 1));
163-
int ib = i & ((i - len_b) >> (sizeof(int) * 8 - 1));
162+
unsigned int maskA = 0u - (unsigned int)(i < len_a);
163+
unsigned int maskB = 0u - (unsigned int)(i < len_b);
164+
int ia = (int)((unsigned int)i & maskA);
165+
int ib = (int)((unsigned int)i & maskB);
164166
result |= (a[ia] ^ b[ib]);
165167
}
166168
result |= (len_a ^ len_b);
@@ -1509,11 +1511,13 @@ static int BrokerSubs_Add(MqttBroker* broker, BrokerClient* bc,
15091511
rc = MQTT_CODE_ERROR_MEMORY;
15101512
}
15111513
if (rc == MQTT_CODE_SUCCESS) {
1512-
XMEMSET(sub, 0, sizeof(*sub));
1513-
sub->in_use = 1;
15141514
if (filter_len >= BROKER_MAX_FILTER_LEN) {
1515-
filter_len = BROKER_MAX_FILTER_LEN - 1;
1515+
rc = MQTT_CODE_ERROR_OUT_OF_BUFFER;
15161516
}
1517+
}
1518+
if (rc == MQTT_CODE_SUCCESS) {
1519+
XMEMSET(sub, 0, sizeof(*sub));
1520+
sub->in_use = 1;
15171521
XMEMCPY(sub->filter, filter, filter_len);
15181522
sub->filter[filter_len] = '\0';
15191523
}
@@ -1830,20 +1834,22 @@ static int BrokerRetained_Store(MqttBroker* broker, const char* topic,
18301834
}
18311835
if (rc == MQTT_CODE_SUCCESS) {
18321836
int tlen = (int)XSTRLEN(topic);
1833-
XMEMSET(msg, 0, sizeof(*msg));
1834-
msg->in_use = 1;
18351837
if (tlen >= BROKER_MAX_TOPIC_LEN) {
1836-
tlen = BROKER_MAX_TOPIC_LEN - 1;
1838+
rc = MQTT_CODE_ERROR_OUT_OF_BUFFER;
1839+
}
1840+
else if (payload_len > BROKER_MAX_PAYLOAD_LEN) {
1841+
rc = MQTT_CODE_ERROR_OUT_OF_BUFFER;
18371842
}
1838-
XMEMCPY(msg->topic, topic, (size_t)tlen);
1839-
msg->topic[tlen] = '\0';
1840-
if (payload_len > 0 && payload != NULL) {
1841-
if (payload_len > BROKER_MAX_PAYLOAD_LEN) {
1842-
payload_len = BROKER_MAX_PAYLOAD_LEN;
1843+
if (rc == MQTT_CODE_SUCCESS) {
1844+
XMEMSET(msg, 0, sizeof(*msg));
1845+
msg->in_use = 1;
1846+
XMEMCPY(msg->topic, topic, (size_t)tlen);
1847+
msg->topic[tlen] = '\0';
1848+
if (payload_len > 0 && payload != NULL) {
1849+
XMEMCPY(msg->payload, payload, payload_len);
18431850
}
1844-
XMEMCPY(msg->payload, payload, payload_len);
1851+
msg->payload_len = payload_len;
18451852
}
1846-
msg->payload_len = payload_len;
18471853
}
18481854
}
18491855
#else
@@ -2012,18 +2018,21 @@ static void BrokerClient_ClearWill(BrokerClient* bc)
20122018
bc->will_qos = MQTT_QOS_0;
20132019
bc->will_retain = 0;
20142020
bc->will_delay_sec = 0;
2015-
bc->will_payload_len = 0;
20162021
#ifdef WOLFMQTT_STATIC_MEMORY
2022+
bc->will_payload_len = 0;
20172023
bc->will_topic[0] = '\0';
20182024
#else
20192025
if (bc->will_topic) {
2026+
BROKER_FORCE_ZERO(bc->will_topic, XSTRLEN(bc->will_topic) + 1);
20202027
WOLFMQTT_FREE(bc->will_topic);
20212028
bc->will_topic = NULL;
20222029
}
20232030
if (bc->will_payload) {
2031+
BROKER_FORCE_ZERO(bc->will_payload, bc->will_payload_len);
20242032
WOLFMQTT_FREE(bc->will_payload);
20252033
bc->will_payload = NULL;
20262034
}
2035+
bc->will_payload_len = 0;
20272036
#endif
20282037
}
20292038

@@ -2051,31 +2060,29 @@ static int BrokerPendingWill_Add(MqttBroker* broker, BrokerClient* bc)
20512060
rc = MQTT_CODE_ERROR_MEMORY;
20522061
}
20532062
if (rc == MQTT_CODE_SUCCESS) {
2054-
XMEMSET(pw, 0, sizeof(*pw));
2055-
pw->in_use = 1;
2056-
{
2057-
int len = (int)XSTRLEN(bc->client_id);
2058-
if (len >= BROKER_MAX_CLIENT_ID_LEN) {
2059-
len = BROKER_MAX_CLIENT_ID_LEN - 1;
2060-
}
2061-
XMEMCPY(pw->client_id, bc->client_id, len);
2062-
pw->client_id[len] = '\0';
2063+
int id_len = (int)XSTRLEN(bc->client_id);
2064+
int t_len = (int)XSTRLEN(bc->will_topic);
2065+
if (id_len >= BROKER_MAX_CLIENT_ID_LEN) {
2066+
rc = MQTT_CODE_ERROR_OUT_OF_BUFFER;
20632067
}
2064-
{
2065-
int len = (int)XSTRLEN(bc->will_topic);
2066-
if (len >= BROKER_MAX_TOPIC_LEN) {
2067-
len = BROKER_MAX_TOPIC_LEN - 1;
2068-
}
2069-
XMEMCPY(pw->topic, bc->will_topic, len);
2070-
pw->topic[len] = '\0';
2068+
else if (t_len >= BROKER_MAX_TOPIC_LEN) {
2069+
rc = MQTT_CODE_ERROR_OUT_OF_BUFFER;
20712070
}
2072-
if (bc->will_payload_len > 0) {
2073-
word16 len = bc->will_payload_len;
2074-
if (len > BROKER_MAX_WILL_PAYLOAD_LEN) {
2075-
len = BROKER_MAX_WILL_PAYLOAD_LEN;
2071+
else if (bc->will_payload_len > BROKER_MAX_WILL_PAYLOAD_LEN) {
2072+
rc = MQTT_CODE_ERROR_OUT_OF_BUFFER;
2073+
}
2074+
if (rc == MQTT_CODE_SUCCESS) {
2075+
XMEMSET(pw, 0, sizeof(*pw));
2076+
pw->in_use = 1;
2077+
XMEMCPY(pw->client_id, bc->client_id, id_len);
2078+
pw->client_id[id_len] = '\0';
2079+
XMEMCPY(pw->topic, bc->will_topic, t_len);
2080+
pw->topic[t_len] = '\0';
2081+
if (bc->will_payload_len > 0) {
2082+
XMEMCPY(pw->payload, bc->will_payload,
2083+
bc->will_payload_len);
2084+
pw->payload_len = bc->will_payload_len;
20762085
}
2077-
XMEMCPY(pw->payload, bc->will_payload, len);
2078-
pw->payload_len = len;
20792086
}
20802087
}
20812088
}
@@ -2121,12 +2128,14 @@ static int BrokerPendingWill_Add(MqttBroker* broker, BrokerClient* bc)
21212128
}
21222129
else if (pw != NULL) {
21232130
if (pw->topic) {
2131+
BROKER_FORCE_ZERO(pw->topic, XSTRLEN(pw->topic) + 1);
21242132
WOLFMQTT_FREE(pw->topic);
21252133
}
21262134
if (pw->client_id) {
21272135
WOLFMQTT_FREE(pw->client_id);
21282136
}
21292137
if (pw->payload) {
2138+
BROKER_FORCE_ZERO(pw->payload, pw->payload_len);
21302139
WOLFMQTT_FREE(pw->payload);
21312140
}
21322141
WOLFMQTT_FREE(pw);
@@ -2179,8 +2188,14 @@ static void BrokerPendingWill_Cancel(MqttBroker* broker,
21792188
broker->pending_wills = next;
21802189
}
21812190
WOLFMQTT_FREE(pw->client_id);
2182-
if (pw->topic) WOLFMQTT_FREE(pw->topic);
2183-
if (pw->payload) WOLFMQTT_FREE(pw->payload);
2191+
if (pw->topic) {
2192+
BROKER_FORCE_ZERO(pw->topic, XSTRLEN(pw->topic) + 1);
2193+
WOLFMQTT_FREE(pw->topic);
2194+
}
2195+
if (pw->payload) {
2196+
BROKER_FORCE_ZERO(pw->payload, pw->payload_len);
2197+
WOLFMQTT_FREE(pw->payload);
2198+
}
21842199
WOLFMQTT_FREE(pw);
21852200
return;
21862201
}
@@ -2204,8 +2219,14 @@ static void BrokerPendingWill_FreeAll(MqttBroker* broker)
22042219
while (pw) {
22052220
BrokerPendingWill* next = pw->next;
22062221
if (pw->client_id) WOLFMQTT_FREE(pw->client_id);
2207-
if (pw->topic) WOLFMQTT_FREE(pw->topic);
2208-
if (pw->payload) WOLFMQTT_FREE(pw->payload);
2222+
if (pw->topic) {
2223+
BROKER_FORCE_ZERO(pw->topic, XSTRLEN(pw->topic) + 1);
2224+
WOLFMQTT_FREE(pw->topic);
2225+
}
2226+
if (pw->payload) {
2227+
BROKER_FORCE_ZERO(pw->payload, pw->payload_len);
2228+
WOLFMQTT_FREE(pw->payload);
2229+
}
22092230
WOLFMQTT_FREE(pw);
22102231
pw = next;
22112232
}
@@ -2266,8 +2287,14 @@ static int BrokerPendingWill_Process(MqttBroker* broker)
22662287
broker->pending_wills = next;
22672288
}
22682289
if (pw->client_id) WOLFMQTT_FREE(pw->client_id);
2269-
if (pw->topic) WOLFMQTT_FREE(pw->topic);
2270-
if (pw->payload) WOLFMQTT_FREE(pw->payload);
2290+
if (pw->topic) {
2291+
BROKER_FORCE_ZERO(pw->topic, XSTRLEN(pw->topic) + 1);
2292+
WOLFMQTT_FREE(pw->topic);
2293+
}
2294+
if (pw->payload) {
2295+
BROKER_FORCE_ZERO(pw->payload, pw->payload_len);
2296+
WOLFMQTT_FREE(pw->payload);
2297+
}
22712298
WOLFMQTT_FREE(pw);
22722299
activity = 1;
22732300
}
@@ -2429,8 +2456,12 @@ static void BrokerClient_PublishWillImmediate(MqttBroker* broker,
24292456
BrokerRetained_Delete(broker, topic);
24302457
}
24312458
else {
2432-
(void)BrokerRetained_Store(broker, topic, payload,
2459+
int ret_rc = BrokerRetained_Store(broker, topic, payload,
24332460
payload_len, 0);
2461+
if (ret_rc != MQTT_CODE_SUCCESS) {
2462+
WBLOG_ERR(broker, "Retained store failed: %s",
2463+
MqttClient_ReturnCodeToString(ret_rc));
2464+
}
24342465
}
24352466
}
24362467

@@ -2674,6 +2705,25 @@ static int BrokerHandle_Connect(BrokerClient* bc, int rx_len,
26742705
word16 id_len = 0;
26752706
if (MqttDecode_Num((byte*)mc.client_id - MQTT_DATA_LEN_SIZE,
26762707
&id_len, MQTT_DATA_LEN_SIZE) == MQTT_DATA_LEN_SIZE) {
2708+
#ifdef WOLFMQTT_STATIC_MEMORY
2709+
if (id_len >= BROKER_MAX_CLIENT_ID_LEN) {
2710+
WBLOG_ERR(broker,
2711+
"broker: client_id too long (%u >= %d) sock=%d",
2712+
(unsigned)id_len, BROKER_MAX_CLIENT_ID_LEN,
2713+
(int)bc->sock);
2714+
#ifdef WOLFMQTT_V5
2715+
if (mc.protocol_level >= MQTT_CONNECT_PROTOCOL_LEVEL_5) {
2716+
ack.return_code = MQTT_REASON_CLIENT_ID_NOT_VALID;
2717+
}
2718+
else
2719+
#endif
2720+
{
2721+
ack.return_code =
2722+
MQTT_CONNECT_ACK_CODE_REFUSED_ID;
2723+
}
2724+
goto send_connack;
2725+
}
2726+
#endif
26772727
BROKER_STORE_STR(bc->client_id, mc.client_id, id_len,
26782728
BROKER_MAX_CLIENT_ID_LEN);
26792729
}
@@ -2735,6 +2785,17 @@ static int BrokerHandle_Connect(BrokerClient* bc, int rx_len,
27352785
if (mc.enable_lwt && mc.lwt_msg != NULL) {
27362786
if (mc.lwt_msg->topic_name != NULL &&
27372787
mc.lwt_msg->topic_name_len > 0) {
2788+
#ifdef WOLFMQTT_STATIC_MEMORY
2789+
if (mc.lwt_msg->topic_name_len >= BROKER_MAX_TOPIC_LEN) {
2790+
WBLOG_ERR(broker,
2791+
"broker: LWT topic too long (%u >= %d) sock=%d",
2792+
(unsigned)mc.lwt_msg->topic_name_len,
2793+
BROKER_MAX_TOPIC_LEN, (int)bc->sock);
2794+
ack.return_code =
2795+
MQTT_CONNECT_ACK_CODE_REFUSED_UNAVAIL;
2796+
goto send_connack;
2797+
}
2798+
#endif
27382799
BROKER_STORE_STR(bc->will_topic, mc.lwt_msg->topic_name,
27392800
mc.lwt_msg->topic_name_len, BROKER_MAX_TOPIC_LEN);
27402801
}
@@ -2796,6 +2857,25 @@ static int BrokerHandle_Connect(BrokerClient* bc, int rx_len,
27962857
word16 ulen = 0;
27972858
if (MqttDecode_Num((byte*)mc.username - MQTT_DATA_LEN_SIZE,
27982859
&ulen, MQTT_DATA_LEN_SIZE) == MQTT_DATA_LEN_SIZE) {
2860+
#ifdef WOLFMQTT_STATIC_MEMORY
2861+
if (ulen >= BROKER_MAX_USERNAME_LEN) {
2862+
WBLOG_ERR(broker,
2863+
"broker: username too long (%u >= %d) sock=%d",
2864+
(unsigned)ulen, BROKER_MAX_USERNAME_LEN,
2865+
(int)bc->sock);
2866+
#ifdef WOLFMQTT_V5
2867+
if (mc.protocol_level >= MQTT_CONNECT_PROTOCOL_LEVEL_5) {
2868+
ack.return_code = MQTT_REASON_BAD_USER_OR_PASS;
2869+
}
2870+
else
2871+
#endif
2872+
{
2873+
ack.return_code =
2874+
MQTT_CONNECT_ACK_CODE_REFUSED_BAD_USER_PWD;
2875+
}
2876+
goto send_connack;
2877+
}
2878+
#endif
27992879
BROKER_STORE_STR_SENSITIVE(bc->username, mc.username, ulen,
28002880
BROKER_MAX_USERNAME_LEN);
28012881
}
@@ -2804,6 +2884,25 @@ static int BrokerHandle_Connect(BrokerClient* bc, int rx_len,
28042884
word16 plen = 0;
28052885
if (MqttDecode_Num((byte*)mc.password - MQTT_DATA_LEN_SIZE,
28062886
&plen, MQTT_DATA_LEN_SIZE) == MQTT_DATA_LEN_SIZE) {
2887+
#ifdef WOLFMQTT_STATIC_MEMORY
2888+
if (plen >= BROKER_MAX_PASSWORD_LEN) {
2889+
WBLOG_ERR(broker,
2890+
"broker: password too long (%u >= %d) sock=%d",
2891+
(unsigned)plen, BROKER_MAX_PASSWORD_LEN,
2892+
(int)bc->sock);
2893+
#ifdef WOLFMQTT_V5
2894+
if (mc.protocol_level >= MQTT_CONNECT_PROTOCOL_LEVEL_5) {
2895+
ack.return_code = MQTT_REASON_BAD_USER_OR_PASS;
2896+
}
2897+
else
2898+
#endif
2899+
{
2900+
ack.return_code =
2901+
MQTT_CONNECT_ACK_CODE_REFUSED_BAD_USER_PWD;
2902+
}
2903+
goto send_connack;
2904+
}
2905+
#endif
28072906
BROKER_STORE_STR_SENSITIVE(bc->password, mc.password, plen,
28082907
BROKER_MAX_PASSWORD_LEN);
28092908
}
@@ -2868,6 +2967,9 @@ static int BrokerHandle_Connect(BrokerClient* bc, int rx_len,
28682967
char auto_id[32];
28692968
int id_len = XSNPRINTF(auto_id, (int)sizeof(auto_id),
28702969
"auto-%04x", broker->next_packet_id++);
2970+
if (broker->next_packet_id == 0) {
2971+
broker->next_packet_id = 1;
2972+
}
28712973
if (id_len > 0) {
28722974
BROKER_STORE_STR(bc->client_id, auto_id, (word16)id_len,
28732975
BROKER_MAX_CLIENT_ID_LEN);
@@ -2909,7 +3011,7 @@ static int BrokerHandle_Connect(BrokerClient* bc, int rx_len,
29093011
}
29103012
#endif
29113013

2912-
#ifdef WOLFMQTT_BROKER_WILL
3014+
#if defined(WOLFMQTT_BROKER_WILL) || defined(WOLFMQTT_STATIC_MEMORY)
29133015
send_connack:
29143016
#endif
29153017
rc = MqttEncode_ConnectAck(bc->tx_buf, BROKER_CLIENT_TX_SZ(bc), &ack);
@@ -2976,11 +3078,13 @@ static int BrokerHandle_Subscribe(BrokerClient* bc, int rx_len,
29763078

29773079
if (f && MqttDecode_Num((byte*)f - MQTT_DATA_LEN_SIZE,
29783080
&flen, MQTT_DATA_LEN_SIZE) == MQTT_DATA_LEN_SIZE) {
2979-
(void)BrokerSubs_Add(broker, bc, f, flen, topic_qos);
2980-
3081+
int sub_rc = BrokerSubs_Add(broker, bc, f, flen, topic_qos);
3082+
if (sub_rc != MQTT_CODE_SUCCESS) {
3083+
granted_qos = (MqttQoS)MQTT_SUBSCRIBE_ACK_CODE_FAILURE;
3084+
}
29813085
#ifdef WOLFMQTT_BROKER_RETAINED
2982-
/* Deliver retained messages matching this filter */
2983-
{
3086+
else {
3087+
/* Deliver retained messages matching this filter */
29843088
char filter_z[BROKER_MAX_FILTER_LEN];
29853089
word16 copy_len = flen;
29863090
if (copy_len >= BROKER_MAX_FILTER_LEN) {
@@ -3153,8 +3257,14 @@ static int BrokerHandle_Publish(BrokerClient* bc, int rx_len,
31533257
}
31543258
}
31553259
#endif
3156-
(void)BrokerRetained_Store(broker, topic, payload,
3157-
pub.total_len, expiry);
3260+
{
3261+
int ret_rc = BrokerRetained_Store(broker, topic, payload,
3262+
pub.total_len, expiry);
3263+
if (ret_rc != MQTT_CODE_SUCCESS) {
3264+
WBLOG_ERR(broker, "Retained store failed: %s",
3265+
MqttClient_ReturnCodeToString(ret_rc));
3266+
}
3267+
}
31583268
}
31593269
}
31603270
#endif /* WOLFMQTT_BROKER_RETAINED */

src/mqtt_client.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2913,9 +2913,11 @@ int MqttClient_NetDisconnect(MqttClient *client)
29132913
#ifdef WOLFMQTT_DEBUG_CLIENT
29142914
PRINTF("Net Disconnect: Removing pending responses");
29152915
#endif
2916+
MqttPendResp *nextResp;
29162917
for (tmpResp = client->firstPendResp;
29172918
tmpResp != NULL;
2918-
tmpResp = tmpResp->next) {
2919+
tmpResp = nextResp) {
2920+
nextResp = tmpResp->next;
29192921
#ifdef WOLFMQTT_DEBUG_CLIENT
29202922
PRINTF("\tPendResp: %p (obj %p), Type %s (%d), ID %d, InProc %d, Done %d",
29212923
tmpResp, tmpResp->packet_obj,

0 commit comments

Comments
 (0)