From 26ae6f7490278b1528a9efff9970f6b8188cab80 Mon Sep 17 00:00:00 2001 From: rusefillc Date: Sat, 30 Jul 2022 12:23:53 -0400 Subject: [PATCH] [SECURITY] Cheap password protection against tune modification fix #4243 --- firmware/console/binary/tunerstudio.cpp | 17 ++++++++++++++++- firmware/controllers/algo/engine.h | 3 +++ firmware/controllers/algo/engine2.cpp | 21 +++++++++++++++++++++ firmware/controllers/settings.cpp | 1 + firmware/rusefi.cpp | 2 +- 5 files changed, 42 insertions(+), 2 deletions(-) diff --git a/firmware/console/binary/tunerstudio.cpp b/firmware/console/binary/tunerstudio.cpp index bfd44f5f50..bf92fce150 100644 --- a/firmware/console/binary/tunerstudio.cpp +++ b/firmware/console/binary/tunerstudio.cpp @@ -174,6 +174,10 @@ extern bool rebootForPresetPending; void TunerStudio::handleWriteChunkCommand(TsChannelBase* tsChannel, ts_response_format_e mode, uint16_t offset, uint16_t count, void *content) { tsState.writeChunkCommandCounter++; + if (isLockedFromUser()) { + sendErrorCode(tsChannel, TS_RESPONSE_UNRECOGNIZED_COMMAND); + return; + } efiPrintf("WRITE CHUNK mode=%d o=%d s=%d", mode, offset, count); @@ -215,6 +219,10 @@ void TunerStudio::handleWriteValueCommand(TsChannelBase* tsChannel, ts_response_ UNUSED(mode); tsState.writeValueCommandCounter++; + if (isLockedFromUser()) { + sendErrorCode(tsChannel, TS_RESPONSE_UNRECOGNIZED_COMMAND); + return; + } tunerStudioDebug(tsChannel, "got W (Write)"); // we can get a lot of these @@ -250,7 +258,14 @@ void TunerStudio::handlePageReadCommand(TsChannelBase* tsChannel, ts_response_fo return; } - const uint8_t* addr = getWorkingPageAddr() + offset; + uint8_t* addr; + if (isLockedFromUser()) { + // to have rusEFI console happy just send all zeros within a valid packet + addr = (uint8_t*)&tsChannel->scratchBuffer + SCRATCH_BUFFER_PREFIX_SIZE; + memset(addr, 0, count); + } else { + addr = getWorkingPageAddr() + offset; + } tsChannel->sendResponse(mode, addr, count); #if EFI_TUNER_STUDIO_VERBOSE // efiPrintf("Sending %d done", count); diff --git a/firmware/controllers/algo/engine.h b/firmware/controllers/algo/engine.h index abe7cba6b0..9ee3e08f53 100644 --- a/firmware/controllers/algo/engine.h +++ b/firmware/controllers/algo/engine.h @@ -468,6 +468,9 @@ void prepareOutputSignals(); void validateConfiguration(); void doScheduleStopEngine(); +void scheduleReboot(); +bool isLockedFromUser(); +void unlockEcu(int password); #define HW_CHECK_RPM 200 diff --git a/firmware/controllers/algo/engine2.cpp b/firmware/controllers/algo/engine2.cpp index 8097577194..de23fd5104 100644 --- a/firmware/controllers/algo/engine2.cpp +++ b/firmware/controllers/algo/engine2.cpp @@ -17,6 +17,7 @@ #include "closed_loop_fuel.h" #include "launch_control.h" #include "injector_model.h" +#include "tunerstudio.h" #if EFI_PROD_CODE #include "svnversion.h" @@ -222,3 +223,23 @@ trigger_config_s VvtTriggerConfiguration::getType() const { bool VvtTriggerConfiguration::isVerboseTriggerSynchDetails() const { return engineConfiguration->verboseVVTDecoding; } + +bool isLockedFromUser() { + int lock = engineConfiguration->tuneHidingKey; + bool isLocked = lock > 0; + if (isLocked) { + firmwareError(OBD_PCM_Processor_Fault, "password protected"); + } + return isLocked; +} + +void unlockEcu(int password) { + if (password != engineConfiguration->tuneHidingKey) { + efiPrintf("Nope rebooting..."); + scheduleReboot(); + } else { + efiPrintf("Unlocked! Burning..."); + engineConfiguration->tuneHidingKey = 0; + requestBurn(); + } +} diff --git a/firmware/controllers/settings.cpp b/firmware/controllers/settings.cpp index 6bc8b794b2..c20e145b77 100644 --- a/firmware/controllers/settings.cpp +++ b/firmware/controllers/settings.cpp @@ -1190,6 +1190,7 @@ void initSettings(void) { addConsoleActionSS("set_egt_cs_pin", (VoidCharPtrCharPtr) setEgtCSPin); addConsoleActionI("set_egt_spi", setEgtSpi); + addConsoleActionI(CMD_ECU_UNLOCK, unlockEcu); addConsoleActionSS("set_trigger_simulator_mode", setTriggerSimulatorMode); addConsoleActionS("set_fuel_pump_pin", setFuelPumpPin); diff --git a/firmware/rusefi.cpp b/firmware/rusefi.cpp index 34e3222a17..ece3016bd7 100644 --- a/firmware/rusefi.cpp +++ b/firmware/rusefi.cpp @@ -156,7 +156,7 @@ void rebootNow() { * Some configuration changes require full firmware reset. * Once day we will write graceful shutdown, but that would be one day. */ -static void scheduleReboot() { +void scheduleReboot() { efiPrintf("Rebooting in 3 seconds..."); chibios_rt::CriticalSectionLocker csl; chVTSetI(&resetTimer, TIME_MS2I(3000), (vtfunc_t) rebootNow, NULL);