Skip to content

Commit 40fba0a

Browse files
authored
Merge branch 'master' into pr-eraseconfig-reset
2 parents f8a8251 + 521ae60 commit 40fba0a

File tree

11 files changed

+91
-29
lines changed

11 files changed

+91
-29
lines changed

cores/esp8266/core_esp8266_postmortem.cpp

+12-2
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ static void cut_here() {
110110
ets_putc('\n');
111111
}
112112

113+
static inline bool is_pc_valid(uint32_t pc) {
114+
return pc >= XCHAL_INSTRAM0_VADDR && pc < (XCHAL_INSTROM0_VADDR + XCHAL_INSTROM0_SIZE);
115+
}
116+
113117
/*
114118
Add some assembly to grab the stack pointer and pass it as an argument before
115119
it grows for the target function. Should stabilize the stack offsets, used to
@@ -125,7 +129,7 @@ asm(
125129
"\n"
126130
"__wrap_system_restart_local:\n\t"
127131
"mov a2, a1\n\t"
128-
"j postmortem_report\n\t"
132+
"j.l postmortem_report, a3\n\t"
129133
".size __wrap_system_restart_local, .-__wrap_system_restart_local\n\t"
130134
);
131135

@@ -181,7 +185,13 @@ static void postmortem_report(uint32_t sp_dump) {
181185
exccause, epc1, rst_info.epc2, rst_info.epc3, rst_info.excvaddr, rst_info.depc);
182186
}
183187
else if (rst_info.reason == REASON_SOFT_WDT_RST) {
184-
ets_printf_P(PSTR("\nSoft WDT reset\n"));
188+
ets_printf_P(PSTR("\nSoft WDT reset"));
189+
const char infinite_loop[] = { 0x06, 0xff, 0xff }; // loop: j loop
190+
if (is_pc_valid(rst_info.epc1) && 0 == memcmp_P(infinite_loop, (PGM_VOID_P)rst_info.epc1, 3u)) {
191+
// The SDK is riddled with these. They are usually preceded by an ets_printf.
192+
ets_printf_P(PSTR(" - deliberate infinite loop detected"));
193+
}
194+
ets_putc('\n');
185195
ets_printf_P(PSTR("\nException (%d):\nepc1=0x%08x epc2=0x%08x epc3=0x%08x excvaddr=0x%08x depc=0x%08x\n"),
186196
rst_info.exccause, /* Address executing at time of Soft WDT level-1 interrupt */ rst_info.epc1, 0, 0, 0, 0);
187197
}

cores/esp8266/umm_malloc/Notes.h

+11
Original file line numberDiff line numberDiff line change
@@ -341,5 +341,16 @@ Enhancement ideas:
341341
* For multiple Heaps builds, add a dedicated function that always reports
342342
DRAM results.
343343

344+
345+
April 22, 2023
346+
347+
The umm_poison logic runs outside the UMM_CRITICAL_* umbrella. When interrupt
348+
routines do alloc calls, it is possible to interrupt an in-progress allocation
349+
just before the poison is set, with a new alloc request resulting in a false
350+
"poison check fail" against the in-progress allocation. The SDK does mallocs
351+
from ISRs. SmartConfig can illustrate this issue.
352+
353+
Move get_poisoned() within UMM_CRITICAL_* in umm_malloc() and umm_realloc().
354+
344355
*/
345356
#endif

cores/esp8266/umm_malloc/umm_local.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,11 @@ void *umm_poison_realloc_fl(void *ptr, size_t size, const char *file, int line)
142142

143143
add_poison_size(&size);
144144
ret = umm_realloc(ptr, size);
145-
146-
ret = get_poisoned(ret, size);
145+
/*
146+
"get_poisoned" is now called from umm_realloc while still in a critical
147+
section. Before umm_realloc returned, the pointer offset was adjusted to
148+
the start of the requested buffer.
149+
*/
147150

148151
return ret;
149152
}

cores/esp8266/umm_malloc/umm_malloc.cpp

+19-7
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,8 @@ void *umm_malloc(size_t size) {
909909

910910
ptr = umm_malloc_core(_context, size);
911911

912+
ptr = POISON_CHECK_SET_POISON(ptr, size);
913+
912914
UMM_CRITICAL_EXIT(id_malloc);
913915

914916
return ptr;
@@ -1068,7 +1070,7 @@ void *umm_realloc(void *ptr, size_t size) {
10681070
// Case 2 - block + next block fits EXACTLY
10691071
} else if ((blockSize + nextBlockSize) == blocks) {
10701072
DBGLOG_DEBUG("exact realloc using next block - %i\n", blocks);
1071-
umm_assimilate_up(c);
1073+
umm_assimilate_up(_context, c);
10721074
STATS__FREE_BLOCKS_UPDATE(-nextBlockSize);
10731075
blockSize += nextBlockSize;
10741076

@@ -1087,8 +1089,9 @@ void *umm_realloc(void *ptr, size_t size) {
10871089
STATS__FREE_BLOCKS_UPDATE(-prevBlockSize);
10881090
STATS__FREE_BLOCKS_ISR_MIN();
10891091
blockSize += prevBlockSize;
1092+
POISON_CHECK_SET_POISON((void *)&UMM_DATA(c), size); // Fix allocation so ISR poison check is good
10901093
UMM_CRITICAL_SUSPEND(id_realloc);
1091-
memmove((void *)&UMM_DATA(c), ptr, curSize);
1094+
UMM_POISON_MEMMOVE((void *)&UMM_DATA(c), ptr, curSize);
10921095
ptr = (void *)&UMM_DATA(c);
10931096
UMM_CRITICAL_RESUME(id_realloc);
10941097
// Case 5 - prev block + block + next block fits
@@ -1108,8 +1111,9 @@ void *umm_realloc(void *ptr, size_t size) {
11081111
#else
11091112
blockSize += (prevBlockSize + nextBlockSize);
11101113
#endif
1114+
POISON_CHECK_SET_POISON((void *)&UMM_DATA(c), size);
11111115
UMM_CRITICAL_SUSPEND(id_realloc);
1112-
memmove((void *)&UMM_DATA(c), ptr, curSize);
1116+
UMM_POISON_MEMMOVE((void *)&UMM_DATA(c), ptr, curSize);
11131117
ptr = (void *)&UMM_DATA(c);
11141118
UMM_CRITICAL_RESUME(id_realloc);
11151119

@@ -1119,8 +1123,9 @@ void *umm_realloc(void *ptr, size_t size) {
11191123
void *oldptr = ptr;
11201124
if ((ptr = umm_malloc_core(_context, size))) {
11211125
DBGLOG_DEBUG("realloc %i to a bigger block %i, copy, and free the old\n", blockSize, blocks);
1126+
POISON_CHECK_SET_POISON((void *)&UMM_DATA(c), size);
11221127
UMM_CRITICAL_SUSPEND(id_realloc);
1123-
memcpy(ptr, oldptr, curSize);
1128+
UMM_POISON_MEMCPY(ptr, oldptr, curSize);
11241129
UMM_CRITICAL_RESUME(id_realloc);
11251130
umm_free_core(_context, oldptr);
11261131
} else {
@@ -1181,8 +1186,9 @@ void *umm_realloc(void *ptr, size_t size) {
11811186
blockSize = blocks;
11821187
#endif
11831188
}
1189+
POISON_CHECK_SET_POISON((void *)&UMM_DATA(c), size);
11841190
UMM_CRITICAL_SUSPEND(id_realloc);
1185-
memmove((void *)&UMM_DATA(c), ptr, curSize);
1191+
UMM_POISON_MEMMOVE((void *)&UMM_DATA(c), ptr, curSize);
11861192
ptr = (void *)&UMM_DATA(c);
11871193
UMM_CRITICAL_RESUME(id_realloc);
11881194
} else if (blockSize >= blocks) { // 2
@@ -1198,8 +1204,9 @@ void *umm_realloc(void *ptr, size_t size) {
11981204
void *oldptr = ptr;
11991205
if ((ptr = umm_malloc_core(_context, size))) {
12001206
DBGLOG_DEBUG("realloc %d to a bigger block %d, copy, and free the old\n", blockSize, blocks);
1207+
POISON_CHECK_SET_POISON((void *)&UMM_DATA(c), size);
12011208
UMM_CRITICAL_SUSPEND(id_realloc);
1202-
memcpy(ptr, oldptr, curSize);
1209+
UMM_POISON_MEMCPY(ptr, oldptr, curSize);
12031210
UMM_CRITICAL_RESUME(id_realloc);
12041211
umm_free_core(_context, oldptr);
12051212
} else {
@@ -1223,8 +1230,9 @@ void *umm_realloc(void *ptr, size_t size) {
12231230
void *oldptr = ptr;
12241231
if ((ptr = umm_malloc_core(_context, size))) {
12251232
DBGLOG_DEBUG("realloc %d to a bigger block %d, copy, and free the old\n", blockSize, blocks);
1233+
POISON_CHECK_SET_POISON((void *)&UMM_DATA(c), size);
12261234
UMM_CRITICAL_SUSPEND(id_realloc);
1227-
memcpy(ptr, oldptr, curSize);
1235+
UMM_POISON_MEMCPY(ptr, oldptr, curSize);
12281236
UMM_CRITICAL_RESUME(id_realloc);
12291237
umm_free_core(_context, oldptr);
12301238
} else {
@@ -1250,6 +1258,8 @@ void *umm_realloc(void *ptr, size_t size) {
12501258

12511259
STATS__FREE_BLOCKS_MIN();
12521260

1261+
ptr = POISON_CHECK_SET_POISON(ptr, size);
1262+
12531263
/* Release the critical section... */
12541264
UMM_CRITICAL_EXIT(id_realloc);
12551265

@@ -1258,6 +1268,7 @@ void *umm_realloc(void *ptr, size_t size) {
12581268

12591269
/* ------------------------------------------------------------------------ */
12601270

1271+
#if !defined(UMM_POISON_CHECK) && !defined(UMM_POISON_CHECK_LITE)
12611272
void *umm_calloc(size_t num, size_t item_size) {
12621273
void *ret;
12631274

@@ -1273,6 +1284,7 @@ void *umm_calloc(size_t num, size_t item_size) {
12731284

12741285
return ret;
12751286
}
1287+
#endif
12761288

12771289
/* ------------------------------------------------------------------------ */
12781290

cores/esp8266/umm_malloc/umm_malloc_cfg.h

+8
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,9 @@ extern bool umm_poison_check(void);
618618
// Local Additions to better report location in code of the caller.
619619
void *umm_poison_realloc_fl(void *ptr, size_t size, const char *file, int line);
620620
void umm_poison_free_fl(void *ptr, const char *file, int line);
621+
#define POISON_CHECK_SET_POISON(p, s) get_poisoned(p, s)
622+
#define UMM_POISON_SKETCH_PTR(p) ((void*)((uintptr_t)p + sizeof(UMM_POISONED_BLOCK_LEN_TYPE) + UMM_POISON_SIZE_BEFORE))
623+
#define UMM_POISON_SKETCH_PTRSZ(s) (s - sizeof(UMM_POISONED_BLOCK_LEN_TYPE) - UMM_POISON_SIZE_BEFORE - UMM_POISON_SIZE_AFTER)
621624
#if defined(UMM_POISON_CHECK_LITE)
622625
/*
623626
* We can safely do individual poison checks at free and realloc and stay
@@ -637,8 +640,13 @@ void umm_poison_free_fl(void *ptr, const char *file, int line);
637640
#else
638641
#define POISON_CHECK() 1
639642
#define POISON_CHECK_NEIGHBORS(c) do {} while (false)
643+
#define POISON_CHECK_SET_POISON(p, s) (p)
644+
#define UMM_POISON_SKETCH_PTR(p) (p)
645+
#define UMM_POISON_SKETCH_PTRSZ(s) (s)
640646
#endif
641647

648+
#define UMM_POISON_MEMMOVE(t, p, s) memmove(UMM_POISON_SKETCH_PTR(t), UMM_POISON_SKETCH_PTR(p), UMM_POISON_SKETCH_PTRSZ(s))
649+
#define UMM_POISON_MEMCPY(t, p, s) memcpy(UMM_POISON_SKETCH_PTR(t), UMM_POISON_SKETCH_PTR(p), UMM_POISON_SKETCH_PTRSZ(s))
642650

643651
#if defined(UMM_POISON_CHECK) || defined(UMM_POISON_CHECK_LITE)
644652
/*

cores/esp8266/umm_malloc/umm_poison.c

+12-7
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,11 @@ void *umm_poison_malloc(size_t size) {
163163
add_poison_size(&size);
164164

165165
ret = umm_malloc(size);
166-
167-
ret = get_poisoned(ret, size);
166+
/*
167+
"get_poisoned" is now called from umm_malloc while still in a critical
168+
section. Before umm_malloc returned, the pointer offset was adjusted to
169+
the start of the requested buffer.
170+
*/
168171

169172
return ret;
170173
}
@@ -177,17 +180,16 @@ void *umm_poison_calloc(size_t num, size_t item_size) {
177180
// Use saturated multiply.
178181
// Rely on umm_malloc to supply the fail response as needed.
179182
size_t size = umm_umul_sat(num, item_size);
183+
size_t request_sz = size;
180184

181185
add_poison_size(&size);
182186

183187
ret = umm_malloc(size);
184188

185189
if (NULL != ret) {
186-
memset(ret, 0x00, size);
190+
memset(ret, 0x00, request_sz);
187191
}
188192

189-
ret = get_poisoned(ret, size);
190-
191193
return ret;
192194
}
193195

@@ -200,8 +202,11 @@ void *umm_poison_realloc(void *ptr, size_t size) {
200202

201203
add_poison_size(&size);
202204
ret = umm_realloc(ptr, size);
203-
204-
ret = get_poisoned(ret, size);
205+
/*
206+
"get_poisoned" is now called from umm_realloc while still in a critical
207+
section. Before umm_realloc returned, the pointer offset was adjusted to
208+
the start of the requested buffer.
209+
*/
205210

206211
return ret;
207212
}

libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h

+2-3
Original file line numberDiff line numberDiff line change
@@ -281,14 +281,13 @@ void ESP8266WebServerTemplate<ServerType>::serveStatic(const char* uri, FS& fs,
281281
template <typename ServerType>
282282
void ESP8266WebServerTemplate<ServerType>::handleClient() {
283283
if (_currentStatus == HC_NONE) {
284-
ClientType client = _server.accept();
285-
if (!client) {
284+
_currentClient = _server.accept();
285+
if (!_currentClient) {
286286
return;
287287
}
288288

289289
DBGWS("New client\n");
290290

291-
_currentClient = client;
292291
_currentStatus = HC_WAIT_READ;
293292
_statusChange = millis();
294293
}

libraries/ESP8266WiFi/examples/BearSSL_CertStore/certs-from-mozilla.py

-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
if item.startswith("'-----BEGIN CERTIFICATE-----"):
4848
pems.append(item)
4949
del names[0] # Remove headers
50-
del pems[0] # Remove headers
5150

5251
# Try and make ./data, skip if present
5352
try:

libraries/ESP8266WiFi/src/WiFiClient.h

+6-6
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,12 @@ class WiFiClient : public Client, public SList<WiFiClient> {
107107
static void stopAll();
108108
static void stopAllExcept(WiFiClient * c);
109109

110-
void keepAlive (uint16_t idle_sec = TCP_DEFAULT_KEEPALIVE_IDLE_SEC, uint16_t intv_sec = TCP_DEFAULT_KEEPALIVE_INTERVAL_SEC, uint8_t count = TCP_DEFAULT_KEEPALIVE_COUNT);
111-
bool isKeepAliveEnabled () const;
112-
uint16_t getKeepAliveIdle () const;
113-
uint16_t getKeepAliveInterval () const;
114-
uint8_t getKeepAliveCount () const;
115-
void disableKeepAlive () { keepAlive(0, 0, 0); }
110+
virtual void keepAlive (uint16_t idle_sec = TCP_DEFAULT_KEEPALIVE_IDLE_SEC, uint16_t intv_sec = TCP_DEFAULT_KEEPALIVE_INTERVAL_SEC, uint8_t count = TCP_DEFAULT_KEEPALIVE_COUNT);
111+
virtual bool isKeepAliveEnabled () const;
112+
virtual uint16_t getKeepAliveIdle () const;
113+
virtual uint16_t getKeepAliveInterval () const;
114+
virtual uint8_t getKeepAliveCount () const;
115+
virtual void disableKeepAlive () { keepAlive(0, 0, 0); }
116116

117117
// default NoDelay=False (Nagle=True=!NoDelay)
118118
// Nagle is for shortly delaying outgoing data, to send less/bigger packets

libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h

+15
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,21 @@ class WiFiClientSecure : public WiFiClient {
357357

358358
// consume bytes after use (see peekBuffer)
359359
virtual void peekConsume (size_t consume) override { return _ctx->peekConsume(consume); }
360+
361+
void keepAlive(uint16_t idle_sec = TCP_DEFAULT_KEEPALIVE_IDLE_SEC, uint16_t intv_sec = TCP_DEFAULT_KEEPALIVE_INTERVAL_SEC, uint8_t count = TCP_DEFAULT_KEEPALIVE_COUNT) override
362+
{
363+
_ctx->keepAlive(idle_sec, intv_sec, count);
364+
}
365+
366+
bool isKeepAliveEnabled() const override { return _ctx->isKeepAliveEnabled(); };
367+
368+
uint16_t getKeepAliveIdle() const override { return _ctx->getKeepAliveIdle(); };
369+
370+
uint16_t getKeepAliveInterval() const override { return _ctx->getKeepAliveInterval(); };
371+
372+
uint8_t getKeepAliveCount() const override { return _ctx->getKeepAliveCount(); };
373+
374+
void disableKeepAlive() override { _ctx->disableKeepAlive(); };
360375

361376
private:
362377
std::shared_ptr<WiFiClientSecureCtx> _ctx;

0 commit comments

Comments
 (0)