From 63f1e4010603fc14884ea1acfdc6e4512c72c728 Mon Sep 17 00:00:00 2001 From: Christopher Pascoe Date: Mon, 21 Dec 2015 16:41:38 -0800 Subject: [PATCH] Fix RAM corruption caused by our hook of register_chipv6_phy(init_data*). "init_data", when non-NULL, is on the heap, and the register_chipv6_phy call sometimes modifies data in (at least) the offset range [128:249], suggesting that it is a buffer larger than 128 bytes in size (the size of our "phy_init_data" buffer). When we use our static buffer (prior to this change), the call could would overwrite the .rodata section and lead to undefined behaviour. To address this, just patch the heap-allocated buffer with our data. Move phy_init_data to flash as it's now readonly and never modified. --- cores/esp8266/core_esp8266_phy.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/cores/esp8266/core_esp8266_phy.c b/cores/esp8266/core_esp8266_phy.c index df8da3ec49..6086c920ca 100644 --- a/cores/esp8266/core_esp8266_phy.c +++ b/cores/esp8266/core_esp8266_phy.c @@ -24,7 +24,9 @@ #include #include -static uint8_t phy_init_data[128] = +#include "c_types.h" + +static const uint8_t ICACHE_FLASH_ATTR phy_init_data[128] = { [0] = 5, // Reserved, do not change [1] = 0, // Reserved, do not change @@ -241,9 +243,12 @@ static uint8_t phy_init_data[128] = }; extern int __real_register_chipv6_phy(uint8_t* init_data); -extern int __wrap_register_chipv6_phy(uint8_t* unused) { - phy_init_data[107] = __get_adc_mode(); - return __real_register_chipv6_phy(phy_init_data); +extern int __wrap_register_chipv6_phy(uint8_t* init_data) { + if (init_data != NULL) { + memcpy(init_data, phy_init_data, sizeof(phy_init_data)); + init_data[107] = __get_adc_mode(); + } + return __real_register_chipv6_phy(init_data); } extern int __get_rf_mode(void) __attribute__((weak));