diff --git a/cores/esp8266/Updater.cpp b/cores/esp8266/Updater.cpp index c1584cf98..c194c1d23 100644 --- a/cores/esp8266/Updater.cpp +++ b/cores/esp8266/Updater.cpp @@ -223,19 +223,29 @@ bool UpdaterClass::end(bool evenIfRemaining){ _size = progress(); } - uint32_t sigLen = 0; if (_verify) { - ESP.flashRead(_startAddress + _size - sizeof(uint32_t), &sigLen, sizeof(uint32_t)); + const uint32_t expectedSigLen = _verify->length(); + // If expectedSigLen is non-zero, we expect the last four bytes of the buffer to + // contain a matching length field, preceded by the bytes of the signature itself. + // But if expectedSigLen is zero, we expect neither a signature nor a length field; + uint32_t sigLen = 0; + + if (expectedSigLen > 0) { + ESP.flashRead(_startAddress + _size - sizeof(uint32_t), &sigLen, sizeof(uint32_t)); + } #ifdef DEBUG_UPDATER DEBUG_UPDATER.printf_P(PSTR("[Updater] sigLen: %d\n"), sigLen); #endif - if (sigLen != _verify->length()) { + if (sigLen != expectedSigLen) { _setError(UPDATE_ERROR_SIGN); _reset(); return false; } - int binSize = _size - sigLen - sizeof(uint32_t) /* The siglen word */; + int binSize = _size; + if (expectedSigLen > 0) { + _size -= (sigLen + sizeof(uint32_t) /* The siglen word */); + } _hash->begin(); #ifdef DEBUG_UPDATER DEBUG_UPDATER.printf_P(PSTR("[Updater] Adjusted binsize: %d\n"), binSize); @@ -254,20 +264,24 @@ bool UpdaterClass::end(bool evenIfRemaining){ for (int i=0; i<_hash->len(); i++) DEBUG_UPDATER.printf(" %02x", ret[i]); DEBUG_UPDATER.printf("\n"); #endif - uint8_t *sig = (uint8_t*)malloc(sigLen); - if (!sig) { - _setError(UPDATE_ERROR_SIGN); - _reset(); - return false; - } - ESP.flashRead(_startAddress + binSize, sig, sigLen); + + uint8_t *sig = nullptr; // Safe to free if we don't actually malloc + if (expectedSigLen > 0) { + sig = (uint8_t*)malloc(sigLen); + if (!sig) { + _setError(UPDATE_ERROR_SIGN); + _reset(); + return false; + } + ESP.flashRead(_startAddress + binSize, sig, sigLen); #ifdef DEBUG_UPDATER - DEBUG_UPDATER.printf_P(PSTR("[Updater] Received Signature:")); - for (size_t i=0; iverify(_hash, (void *)sig, sigLen)) { free(sig); _setError(UPDATE_ERROR_SIGN);