Skip to content

Commit c2e083e

Browse files
committed
Heap addendum to handle changes in NON-OS SDK 3.0.x
The NON-OS SDK 3.0.x has breaking changes to pvPortMalloc. They added one more argument for selecting a heap. To avoid breaking the build, I renamed their broken version pvEsprMalloc. To be used, the LIBS need to be edited. They also added pvPortZallocIram and pvPortCallocIram, which are not a problem. Issues with WPA2 Enterprise in new SDKs: * v3.0.0 and v3.0.1 - have the same memory leak and duplicate free bugs from before * v3.0.2 through v3.0.5 - have the same memory leak; however, _no_ duplicate free crash. * memory leak can be seen by cycling through setup, connect, disconnect, and clear setup - repeatedly. Updated `wpa2_eap_patch.cpp` and binary patch scripts to handle v3.0.0 through v3.0.5. Patched SDKs v3.0.0 through v3.0.5
1 parent da48a52 commit c2e083e

File tree

11 files changed

+136
-15
lines changed

11 files changed

+136
-15
lines changed

Diff for: cores/esp8266/heap.cpp

+42-5
Original file line numberDiff line numberDiff line change
@@ -356,25 +356,25 @@ void system_show_malloc(void)
356356
void* IRAM_ATTR pvPortMalloc(size_t size, const char* file, int line)
357357
{
358358
HeapSelectDram ephemeral;
359-
return heap_pvPortMalloc(size, file, line);;
359+
return heap_pvPortMalloc(size, file, line);;
360360
}
361361

362362
void* IRAM_ATTR pvPortCalloc(size_t count, size_t size, const char* file, int line)
363363
{
364364
HeapSelectDram ephemeral;
365-
return heap_pvPortCalloc(count, size, file, line);
365+
return heap_pvPortCalloc(count, size, file, line);
366366
}
367367

368368
void* IRAM_ATTR pvPortRealloc(void *ptr, size_t size, const char* file, int line)
369369
{
370370
HeapSelectDram ephemeral;
371-
return heap_pvPortRealloc(ptr, size, file, line);
371+
return heap_pvPortRealloc(ptr, size, file, line);
372372
}
373373

374374
void* IRAM_ATTR pvPortZalloc(size_t size, const char* file, int line)
375375
{
376376
HeapSelectDram ephemeral;
377-
return heap_pvPortZalloc(size, file, line);
377+
return heap_pvPortZalloc(size, file, line);
378378
}
379379

380380
void IRAM_ATTR vPortFree(void *ptr, const char* file, int line)
@@ -384,7 +384,44 @@ void IRAM_ATTR vPortFree(void *ptr, const char* file, int line)
384384
// correct context. umm_malloc free internally determines the correct heap.
385385
HeapSelectDram ephemeral;
386386
#endif
387-
return heap_vPortFree(ptr, file, line);
387+
return heap_vPortFree(ptr, file, line);
388+
}
389+
390+
////////////////////////////////////////////////////////////////////////////////
391+
/*
392+
New for NON-OS SDK 3.0.0 and up
393+
Needed for WPA2 Enterprise support. This was not present in SDK pre 3.0
394+
395+
The NON-OS SDK 3.0.x has breaking changes to pvPortMalloc. They added one more
396+
argument for selecting a heap. To avoid breaking the build, I renamed their
397+
broken version pvEsprMalloc. To be used, the LIBS need to be edited.
398+
399+
They also added pvPortZallocIram and pvPortCallocIram, which are not a
400+
problem.
401+
402+
WPA2 Enterprise connect crashing is fixed at v3.0.2 and up.
403+
*/
404+
void* IRAM_ATTR pvEsprMalloc(size_t size, const char* file, int line, bool iram)
405+
{
406+
if (iram) {
407+
HeapSelectIram ephemeral;
408+
return heap_pvPortMalloc(size, file, line);;
409+
} else {
410+
HeapSelectDram ephemeral;
411+
return heap_pvPortMalloc(size, file, line);;
412+
}
413+
}
414+
415+
void* IRAM_ATTR pvPortCallocIram(size_t count, size_t size, const char* file, int line)
416+
{
417+
HeapSelectIram ephemeral;
418+
return heap_pvPortCalloc(count, size, file, line);
419+
}
420+
421+
void* IRAM_ATTR pvPortZallocIram(size_t size, const char* file, int line)
422+
{
423+
HeapSelectIram ephemeral;
424+
return heap_pvPortZalloc(size, file, line);
388425
}
389426

390427
};

Diff for: cores/esp8266/wpa2_eap_patch.cpp

+55-6
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,43 @@
55
* modules.
66
*
77
*/
8-
98
#include <string.h>
109
#include <ets_sys.h>
1110
#include <pgmspace.h>
1211
#include "coredecls.h"
1312

13+
#if defined(NONOSDK22x_190703) || \
14+
defined(NONOSDK22x_191122) || \
15+
defined(NONOSDK22x_191105) || \
16+
defined(NONOSDK22x_191124) || \
17+
defined(NONOSDK22x_190313) || \
18+
defined(NONOSDK221) || \
19+
defined(NONOSDK3V0) || \
20+
defined(NONOSDK300) || \
21+
defined(NONOSDK301) || \
22+
defined(NONOSDK302) || \
23+
defined(NONOSDK303) || \
24+
defined(NONOSDK304) || \
25+
defined(NONOSDK305)
26+
27+
// eap_peer_config_deinit() - For this list of SDKs there is no significant
28+
// changes in the function. Just the line number reference for when vPortFree
29+
// is called. When vPortFree is called, register a12 continues to hold a pointer
30+
// to the struct StateMachine. Our cleanup routine should continue to work.
31+
#if defined(NONOSDK300) || defined(NONOSDK301)
32+
// Minor changes only line number changed
33+
#define SDK_LEAK_LINE 809
34+
#elif defined(NONOSDK302) || defined(NONOSDK303) || defined(NONOSDK304)
35+
// Minor changes only line number changed
36+
#define SDK_LEAK_LINE 831
37+
#elif defined(NONOSDK305)
38+
// Freed up IRAM ??
39+
// Moved from `.text.eap_peer_config_deinit` to `eap_peer_config_deinit`
40+
#define SDK_LEAK_LINE 831
41+
#else
42+
#define SDK_LEAK_LINE 799
43+
#endif
44+
1445
#ifdef DEBUG_WPA2_EAP_PATCH
1546
#include "esp8266_undocumented.h"
1647
#define DEBUG_PRINTF ets_uart_printf
@@ -100,7 +131,7 @@ struct StateMachine { // size 200 bytes
100131
* same line.
101132
*/
102133
void patch_wpa2_eap_vPortFree_a12(void *ptr, const char* file, int line, void* a12) {
103-
if (799 == line) {
134+
if (SDK_LEAK_LINE == line) {
104135
// This caller is eap_peer_config_deinit()
105136
struct StateMachine* sm = (struct StateMachine*)a12;
106137
if (ptr == sm->config[0]) {
@@ -126,21 +157,39 @@ void patch_wpa2_eap_vPortFree_a12(void *ptr, const char* file, int line, void* a
126157
}
127158
#endif
128159
}
129-
#if 0
130-
// This is not needed because the call was NO-OPed in the library. This code
131-
// snippit is just to show how a future memory free issue might be resolved.
132-
else if (672 == line) {
160+
161+
#if defined(NONOSDK300) || defined(NONOSDK301)
162+
else if (682 == line) {
133163
// This caller is wpa2_sm_rx_eapol()
134164
// 1st of a double free
135165
// let the 2nd free handle it.
136166
return;
137167
}
168+
#elif defined(NONOSDK302) || defined(NONOSDK303) || defined(NONOSDK304) || defined(NONOSDK305)
169+
// WPA2 Enterpise connections appear to work without crashing
170+
// wpa2_sm_rx_eapol() has a few changes between NONOSDK301 and NONOSDK302.
171+
// Double free appears fixed; however, still has memory leak.
172+
// TODO: evaluate the unasm functions
173+
#else
174+
// This is not needed because the call was NO-OPed in the library.
175+
// Keep code snippit for reference.
176+
// else if (672 == line) {
177+
// // This caller is wpa2_sm_rx_eapol()
178+
// // 1st of a double free
179+
// // let the 2nd free handle it.
180+
// return;
181+
// }
138182
#endif
139183
vPortFree(ptr, file, line);
140184
}
141185

142186
};
143187

188+
#else
189+
#error "Internal error: A new SDK has been added. This module must be updated."
190+
#error " Need to test WPA2 Enterpise connectivity."
191+
#endif
192+
144193
/*
145194
* This will minimize code space for non-wifi enterprise sketches which do not
146195
* need the patch and disable_extra4k_at_link_time().

Diff for: tools/sdk/lib/NONOSDK300/libwpa2.a

0 Bytes
Binary file not shown.

Diff for: tools/sdk/lib/NONOSDK301/libwpa2.a

0 Bytes
Binary file not shown.

Diff for: tools/sdk/lib/NONOSDK302/libwpa2.a

0 Bytes
Binary file not shown.

Diff for: tools/sdk/lib/NONOSDK303/libwpa2.a

0 Bytes
Binary file not shown.

Diff for: tools/sdk/lib/NONOSDK304/libwpa2.a

0 Bytes
Binary file not shown.

Diff for: tools/sdk/lib/NONOSDK305/libwpa2.a

0 Bytes
Binary file not shown.

Diff for: tools/sdk/lib/README.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
1+
## Adding new SDKs
2+
3+
- Create a new directory for the new SDK
4+
- Copy .a files from SDK `lib` directory to the new directory
5+
- Run `./eval_fix_sdks.sh --analyze`.
6+
- Use above results to update `fix_sdk_libs.sh` to handle new SDK
7+
- Once `fix_sdk_libs.sh` has been updated. You can run `./eval_fix_sdks.sh --patch` to do a batch run of `fix_sdk_libs.sh` against each SDK.
8+
19
## Updating SDK libraries
210

311
- Copy .a files from SDK `lib` directory to this directory
412
- Run `fix_sdk_libs.sh`
513

14+
615
## Updating libstdc++
716

817
After building gcc using crosstool-NG, get compiled libstdc++ and remove some objects:
@@ -17,4 +26,3 @@ xtensa-lx106-elf-ar d libstdc++.a del_opv.o
1726
xtensa-lx106-elf-ar d libstdc++.a new_op.o
1827
xtensa-lx106-elf-ar d libstdc++.a new_opv.o
1928
```
20-

Diff for: tools/sdk/lib/eval_fix_sdks.sh

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
#!/bin/bash
22
# set -e
33

4+
single_sdk="${2}"
5+
if [[ -n "$single_sdk" ]]; then
6+
if [[ "NONOSDK" != "${single_sdk:0:7}" ]]; then
7+
single_sdk=""
8+
fi
9+
fi
10+
411
add_path_ifexist() {
512
if [[ -d $1 ]]; then
613
export PATH=$( realpath $1 ):$PATH
@@ -24,6 +31,10 @@ EOF
2431
}
2532

2633
list_sdks() {
34+
if [[ -n "$single_sdk" ]]; then
35+
echo -e "$single_sdk"
36+
return
37+
fi
2738
cat <<EOF
2839
NONOSDK22x_190313
2940
NONOSDK22x_190703
@@ -68,7 +79,7 @@ analyze() {
6879
done
6980
echo ""
7081

71-
find . -name eap.o -exec md5sum {} \; | sort
82+
find . -name eap.o -exec md5sum {} \; | sort -k2
7283
echo ""
7384

7485
unset prev_sdk

Diff for: tools/sdk/lib/fix_sdk_libs.sh

+18-2
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,28 @@ elif [[ ${VERSION} == "NONOSDK22x"* ]]; then
8181
addSymbol_system_func1 "0x54"
8282
patchFile "eap.o" "3059" "2" "wAA=" "8CA=" # WPA2-Enterprise patch which replaces a double-free with nop, see #8082
8383
patchFile "eap.o" "26356" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
84-
elif [[ ${VERSION} == "NONOSDK3V0"* ]]; then
84+
elif [[ ${VERSION} == "NONOSDK3V0" ]]; then
8585
addSymbol_system_func1 "0x60"
8686
patchFile "eap.o" "3059" "2" "wAA=" "8CA=" # WPA2-Enterprise patch which replaces a double-free with nop, see #8082
8787
patchFile "eap.o" "26356" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
88-
elif [[ ${VERSION} == "NONOSDK3"* ]]; then
88+
elif [[ ${VERSION} == "NONOSDK300" ]]; then
8989
addSymbol_system_func1 "0x54"
90+
patchFile "eap.o" "19204" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
91+
elif [[ ${VERSION} == "NONOSDK301" ]]; then
92+
addSymbol_system_func1 "0x54"
93+
patchFile "eap.o" "26364" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
94+
elif [[ ${VERSION} == "NONOSDK302" ]]; then
95+
addSymbol_system_func1 "0x54"
96+
patchFile "eap.o" "26536" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
97+
elif [[ ${VERSION} == "NONOSDK303" ]]; then
98+
addSymbol_system_func1 "0x54"
99+
patchFile "eap.o" "26536" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
100+
elif [[ ${VERSION} == "NONOSDK304" ]]; then
101+
addSymbol_system_func1 "0x54"
102+
patchFile "eap.o" "19376" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
103+
elif [[ ${VERSION} == "NONOSDK305" ]]; then
104+
addSymbol_system_func1 "0x54"
105+
patchFile "eap.o" "67670" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
90106
else
91107
echo "WARN: Unknown address for system_func1() called by system_restart_local()"
92108
fi

0 commit comments

Comments
 (0)