[SYS] Bound remaining MQTT/HTTP/BLE/RF inputs into fixed buffers (#2324)
Follow-up to #2321. That PR fixed five strcpy sites in XtoSYS/createOrUpdateDevice but left adjacent attack surfaces using the same pattern (strncpy with the destination's own size, leaving the buffer non-NUL-terminated when the source is at the limit; or strcpy of WiFiManager/HTTP form values that bypass the client-side maxlength). The over-long string then flows into saveConfig() and back into a strcpy on next boot, corrupting heap/.bss on every reload. main/main.cpp - XtoSYS: length-check before copying mqtt_topic, discovery_prefix, gateway_name, gw_pass (ota_pass), and ble_aes. Reject over-length with THEENGS_LOG_WARNING, preserving existing values. main/main.cpp - loadConfigFromFlash: new loadStrField() helper applies the same guard to every SPIFFS-loaded string (mqtt_server/port/user/pass per slot, mqtt_topic, discovery_prefix, gateway_name, ota_pass, ble_aes). Defense in depth in case a pre-fix build left an over-length value in /config.json. main/main.cpp - WiFiManager save: bound mqtt_topic against the 150-byte portal buffer overflowing the 66-byte destination (HTML maxlength is client-side only; a raw POST bypasses it). main/webUI.cpp - handleCG /gw save: bound gateway-password form input before the strncpy that previously left ota_pass non-NUL-terminated. main/blufi.cpp - ESP_BLUFI_EVENT_RECV_STA_SSID/PASSWD: clamp the wire-supplied ssid_len/passwd_len before the memcpy and the trailing NUL so a crafted BluFi provisioning frame cannot overrun gl_sta_ssid[32]/gl_sta_passwd[64]. main/gatewayBT.cpp - BLEDecryptor (Victron, encr==3): remove `nonce[16] = {0}`, a one-byte stack-OOB write reachable from any BLE adv. The line was dead (the memset two lines later zeroes the whole array); deleting it eliminates the OOB write. main/gatewaySRFB.cpp - SRFBtoX: bound the _uartbuf writer so a 433 MHz frame with no STOP can no longer let _uartpos grow past sizeof(_uartbuf). main/gatewaySRFB.cpp - _rfbSend: the hex output buffer was sized RF_MESSAGE_SIZE (9) but _rawToHex writes 2*N+2 bytes per call. Resize to fit. Tested on a Theengs Bridge: built theengs-bridge-v11 env, OTA-flashed, and verified that publishing {"discovery_prefix":"Z"*200} to MQTTtoSYS/config leaves discovery_prefix unchanged (no Z*65 truncation in subsequent discovery topics), bridge keeps decoding BLE adverts, and SYStoMQTT/LWT stay healthy. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
2459e1c29b
commit
0b6780678f
5 files changed
+113
-29
No files matched your search
+11
-2
@@ -60,7 +60,9 @@ void _rfbSend(byte* message) {
|
||||
}
|
||||
|
||||
void _rfbSend(byte* message, int times) {
|
||||
char buffer[RF_MESSAGE_SIZE];
|
||||
// _rawToHex writes 3 bytes per input byte (two hex chars + CR) followed by a
|
||||
// terminating NUL, so the buffer needs 2 * RF_MESSAGE_SIZE + 2 bytes.
|
||||
char buffer[RF_MESSAGE_SIZE * 2 + 2] = {0};
|
||||
TheengsUtils::_rawToHex(message, buffer, RF_MESSAGE_SIZE);
|
||||
THEENGS_LOG_NOTICE(F("[RFBRIDGE] Sending MESSAGE" CR));
|
||||
|
||||
@@ -85,8 +87,15 @@ bool SRFBtoX() {
|
||||
if (c == RF_CODE_STOP) {
|
||||
_rfbDecode();
|
||||
receiving = false;
|
||||
} else {
|
||||
} else if (_uartpos < sizeof(_uartbuf)) {
|
||||
_uartbuf[_uartpos++] = c;
|
||||
} else {
|
||||
// Frame longer than expected — drop it rather than overrun _uartbuf.
|
||||
// A crafted 433 MHz transmission that emits START but never STOP would
|
||||
// otherwise let _uartpos grow up to 255 and trample adjacent globals.
|
||||
THEENGS_LOG_WARNING(F("[RFBRIDGE] RF frame too long, dropping" CR));
|
||||
receiving = false;
|
||||
_uartpos = 0;
|
||||
}
|
||||
} else if (c == RF_CODE_START) {
|
||||
_uartpos = 0;
|
||||
|
||||
Reference in new issue
Block a user