diff --git a/src/MessageStore.cpp b/src/MessageStore.cpp index 8b6775eec..4030bdd28 100644 --- a/src/MessageStore.cpp +++ b/src/MessageStore.cpp @@ -215,7 +215,12 @@ const StoredMessage *MessageStore::tryAddFromPacket(const meshtastic_MeshPacket sm.channelIndex = packet.channel; const char *payload = reinterpret_cast(packet.decoded.payload.bytes); - size_t len = strnlen(payload, MAX_MESSAGE_SIZE - 1); + // payload.bytes is not NUL-terminated, so bound by the received size too: a shorter message + // stored after a longer one would otherwise pick up the previous occupant's trailing bytes. + size_t avail = packet.decoded.payload.size; + if (avail > MAX_MESSAGE_SIZE - 1) + avail = MAX_MESSAGE_SIZE - 1; + size_t len = strnlen(payload, avail); sm.textOffset = storeTextInPool(payload, len); sm.textLength = len; diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 7b1263147..cdd61d15f 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -741,6 +741,10 @@ void NodeDB::resetRadioConfig(bool is_fresh_install) LOG_INFO("Set default channel and radio preferences!"); channels.initDefaults(); + // Defaults ship the public PSK, so strip it again before onConfigChanged() publishes hashes; + // loadFromDisk's sanitation is a no-op when the channel file was absent or corrupt. + if (owner.is_licensed) + channels.ensureLicensedOperation(); } channels.onConfigChanged(); diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index 70d869bea..572b79242 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -1855,7 +1855,12 @@ bool PhoneAPI::handleToRadioPacket(meshtastic_MeshPacket &p) p.want_ack = true; } - lastPortNumToRadio[p.decoded.portnum] = millis(); + // Only the rate-limited ports above are ever read back, so recording any other portnum would let + // a client grow this map without bound by cycling through them. + if (IS_ONE_OF(p.decoded.portnum, meshtastic_PortNum_TRACEROUTE_APP, meshtastic_PortNum_POSITION_APP, + meshtastic_PortNum_WAYPOINT_APP, meshtastic_PortNum_ALERT_APP, meshtastic_PortNum_TELEMETRY_APP, + meshtastic_PortNum_TEXT_MESSAGE_APP)) + lastPortNumToRadio[p.decoded.portnum] = millis(); service->handleToRadio(p); return true; } diff --git a/src/modules/DropzoneModule.cpp b/src/modules/DropzoneModule.cpp index 2340f31f2..4658cb5b6 100644 --- a/src/modules/DropzoneModule.cpp +++ b/src/modules/DropzoneModule.cpp @@ -32,14 +32,17 @@ ProcessMessage DropzoneModule::handleReceived(const meshtastic_MeshPacket &mp) auto &p = mp.decoded; char matchCompare[54]; auto incomingMessage = reinterpret_cast(p.payload.bytes); - sprintf(matchCompare, "%s conditions", owner.short_name); - if (strncasecmp(incomingMessage, matchCompare, strlen(matchCompare)) == 0) { + // payload.bytes is not NUL-terminated, so a comparison longer than the received size would read + // whatever the previous occupant of the packet left behind. + const size_t received = p.payload.size; + snprintf(matchCompare, sizeof(matchCompare), "%s conditions", owner.short_name); + if (received >= strlen(matchCompare) && strncasecmp(incomingMessage, matchCompare, strlen(matchCompare)) == 0) { LOG_DEBUG("Received dropzone conditions request"); startSendConditions = millis(); } - sprintf(matchCompare, "%s conditions", owner.long_name); - if (strncasecmp(incomingMessage, matchCompare, strlen(matchCompare)) == 0) { + snprintf(matchCompare, sizeof(matchCompare), "%s conditions", owner.long_name); + if (received >= strlen(matchCompare) && strncasecmp(incomingMessage, matchCompare, strlen(matchCompare)) == 0) { LOG_DEBUG("Received dropzone conditions request"); startSendConditions = millis(); }