8000 Heap addendum to handle changes in NON-OS SDK 3.0.x by mhightower83 · Pull Request #8746 · esp8266/Arduino · GitHub
[go: up one dir, main page]

Skip to content

Heap addendum to handle changes in NON-OS SDK 3.0.x #8746

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Dec 16, 2022
Next Next commit
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
  • Loading branch information
mhightower83 committed Dec 8, 2022
commit c2e083e44642c43d4a91e51a70497da730c1708f
47 changes: 42 additions & 5 deletions cores/esp8266/heap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,25 +356,25 @@ void system_show_malloc(void)
void* IRAM_ATTR pvPortMalloc(size_t size, const char* file, int line)
{
HeapSelectDram ephemeral;
return heap_pvPortMalloc(size, file, line);;
return heap_pvPortMalloc(size, file, line);;
}

void* IRAM_ATTR pvPortCalloc(size_t count, size_t size, const char* file, int line)
{
HeapSelectDram ephemeral;
return heap_pvPortCalloc(count, size, file, line);
return heap_pvPortCalloc(count, size, file, line);
}

void* IRAM_ATTR pvPortRealloc(void *ptr, size_t size, const char* file, int line)
{
HeapSelectDram ephemeral;
return heap_pvPortRealloc(ptr, size, file, line);
return heap_pvPortRealloc(ptr, size, file, line);
}

void* IRAM_ATTR pvPortZalloc(size_t size, const char* file, int line)
{
HeapSelectDram ephemeral;
return heap_pvPortZalloc(size, file, line);
return heap_pvPortZalloc(size, file, line);
}

void IRAM_ATTR vPortFree(void *ptr, const char* file, int line)
Expand All @@ -384,7 +384,44 @@ void IRAM_ATTR vPortFree(void *ptr, const char* file, int line)
// correct context. umm_malloc free internally determines the correct heap.
HeapSelectDram ephemeral;
#endif
return heap_vPortFree(ptr, file, line);
return heap_vPortFree(ptr, file, line);
}

////////////////////////////////////////////////////////////////////////////////
/*
New for NON-OS SDK 3.0.0 and up
Needed for WPA2 Enterprise support. This was not present in SDK pre 3.0

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.

WPA2 Enterprise connect crashing is fixed at v3.0.2 and up.
*/
void* IRAM_ATTR pvEsprMalloc(size_t size, const char* file, int line, bool iram)
{
if (iram) {
HeapSelectIram ephemeral;
return heap_pvPortMalloc(size, file, line);;
} else {
HeapSelectDram ephemeral;
return heap_pvPortMalloc(size, file, line);;
}
}

void* IRAM_ATTR pvPortCallocIram(size_t count, size_t size, const char* file, int line)
{
HeapSelectIram ephemeral;
return heap_pvPortCalloc(count, size, file, line);
}

void* IRAM_ATTR pvPortZallocIram(size_t size, const char* file, int line)
{
HeapSelectIram ephemeral;
return heap_pvPortZalloc(size, file, line);
}

};
61 changes: 55 additions & 6 deletions cores/esp8266/wpa2_eap_patch.cpp

Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,43 @@
* modules.
*
*/

#include <string.h>
#include <ets_sys.h>
#include <pgmspace.h>
#include "coredecls.h"

#if defined(NONOSDK22x_190703) || \
defined(NONOSDK22x_191122) || \
defined(NONOSDK22x_191105) || \
defined(NONOSDK22x_191124) || \
defined(NONOSDK22x_190313) || \
defined(NONOSDK221) || \
defined(NONOSDK3V0) || \
defined(NONOSDK300) || \
defined(NONOSDK301) || \
defined(NONOSDK302) || \
defined(NONOSDK303) || \
defined(NONOSDK304) || \
defined(NONOSDK305)

// eap_peer_config_deinit() - For this list of SDKs there is no significant
// changes in the function. Just the line number reference for when vPortFree
// is called. When vPortFree is called, register a12 continues to hold a pointer
// to the struct StateMachine. Our cleanup routine should continue to work.
#if defined(NONOSDK300) || defined(NONOSDK301)
// Minor changes only line number changed
#define SDK_LEAK_LINE 809
#elif defined(NONOSDK302) || defined(NONOSDK303) || defined(NONOSDK304)
// Minor changes only line number changed
#define SDK_LEAK_LINE 831
#elif defined(NONOSDK305)
// Freed up IRAM ??
// Moved from `.text.eap_peer_config_deinit` to `eap_peer_config_deinit`
#define SDK_LEAK_LINE 831
#else
#define SDK_LEAK_LINE 799
#endif

#ifdef DEBUG_WPA2_EAP_PATCH
#include "esp8266_undocumented.h"
#define DEBUG_PRINTF ets_uart_printf
Expand Down Expand Up @@ -100,7 +131,7 @@ struct StateMachine { // size 200 bytes
* same line.
*/
void patch_wpa2_eap_vPortFree_a12(void *ptr, const char* file, int line, void* a12) {
if (799 == line) {
if (SDK_LEAK_LINE == line) {
// This caller is eap_peer_config_deinit()
struct StateMachine* sm = (struct StateMachine*)a12;
if (ptr == sm->config[0]) {
Expand All @@ -126,21 +157,39 @@ void patch_wpa2_eap_vPortFree_a12(void *ptr, const char* file, int line, void* a
}
#endif
}
#if 0
// This is not needed because the call was NO-OPed in the library. This code
// snippit is just to show how a future memory free issue might be resolved.
else if (672 == line) {

#if defined(NONOSDK300) || defined(NONOSDK301)
else if (682 == line) {
// This caller is wpa2_sm_rx_eapol()
// 1st of a double free
// let the 2nd free handle it.
return;
}
#elif defined(NONOSDK302) || defined(NONOSDK303) || defined(NONOSDK304) || defined(NONOSDK305)
// WPA2 Enterpise connections appear to work without crashing
// wpa2_sm_rx_eapol() has a few changes between NONOSDK301 and NONOSDK302.
// Double free appears fixed; however, still has memory leak.
// TODO: evaluate the unasm functions
#else
// This is not needed because the call was NO-OPed in the library.
// Keep code snippit for reference.
// else if (672 == line) {
// // This caller is wpa2_sm_rx_eapol()
// // 1st of a double free
// // let the 2nd free handle it.
// return;
// }
#endif
vPortFree(ptr, file, line);
}

};

#else
#error "Internal error: A new SDK has been added. This module must be updated."
#error " Need to test WPA2 Enterpise connectivity."
#endif

/*
* This will minimize code space for non-wifi enterprise sketches which do not
* need the patch and disable_extra4k_at_link_time().
Expand Down
Binary file modified tools/sdk/lib/NONOSDK300/libwpa2.a
Binary file not shown.
Binary file modified tools/sdk/lib/NONOSDK301/libwpa2.a
Binary file not shown.
Binary file modified tools/sdk/lib/NONOSDK302/libwpa2.a
Binary file not shown.
Binary file modified tools/sdk/lib/NONOSDK303/libwpa2.a
Binary file not shown.
Binary file modified tools/sdk/lib/NONOSDK304/libwpa2.a
Binary file not shown.
Binary file modified tools/sdk/lib/NONOSDK305/libwpa2.a
Binary file not shown.
10 changes: 9 additions & 1 deletion tools/sdk/lib/README.md
F438
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
## Adding new SDKs

- Create a new directory for the new SDK
- Copy .a files from SDK `lib` directory to the new directory
- Run `./eval_fix_sdks.sh --analyze`.
- Use above results to update `fix_sdk_libs.sh` to handle new SDK
- 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.

## Updating SDK libraries

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


## Updating libstdc++

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

13 changes: 12 additions & 1 deletion tools/sdk/lib/eval_fix_sdks.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
#!/bin/bash
# set -e

single_sdk="${2}"
if [[ -n "$single_sdk" ]]; then
if [[ "NONOSDK" != "${single_sdk:0:7}" ]]; then
single_sdk=""
fi
fi

add_path_ifexist() {
if [[ -d $1 ]]; then
export PATH=$( realpath $1 ):$PATH
Expand All @@ -24,6 +31,10 @@ EOF
}

list_sdks() {
if [[ -n "$single_sdk" ]]; then
echo -e "$single_sdk"
return
fi
cat <<EOF
NONOSDK22x_190313
NONOSDK22x_190703
Expand Down Expand Up @@ -68,7 +79,7 @@ analyze() {
done
echo ""

find . -name eap.o -exec md5sum {} \; | sort
find . -name eap.o -exec md5sum {} \; | sort -k2
echo ""

unset prev_sdk
Expand Down
20 changes: 18 additions & 2 deletions tools/sdk/lib/fix_sdk_libs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,28 @@ elif [[ ${VERSION} == "NONOSDK22x"* ]]; then
addSymbol_system_func1 "0x54"
patchFile "eap.o" "3059" "2" "wAA=" "8CA=" # WPA2-Enterprise patch which replaces a double-free with nop, see #8082
patchFile "eap.o" "26356" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
elif [[ ${VERSION} == "NONOSDK3V0"* ]]; then
elif [[ ${VERSION} == "NONOSDK3V0" ]]; then
addSymbol_system_func1 "0x60"
patchFile "eap.o" "3059" "2" "wAA=" "8CA=" # WPA2-Enterprise patch which replaces a double-free with nop, see #8082
patchFile "eap.o" "26356" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
elif [[ ${VERSION} == "NONOSDK3"* ]]; then
elif [[ ${VERSION} == "NONOSDK300" ]]; then
addSymbol_system_func1 "0x54"
patchFile "eap.o" "19204" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
elif [[ ${VERSION} == "NONOSDK301" ]]; then
addSymbol_system_func1 "0x54"
patchFile "eap.o" "26364" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
elif [[ ${VERSION} == "NONOSDK302" ]]; then
addSymbol_system_func1 "0x54"
patchFile "eap.o" "26536" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
elif [[ ${VERSION} == "NONOSDK303" ]]; then
addSymbol_system_func1 "0x54"
patchFile "eap.o" "26536" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
elif [[ ${VERSION} == "NONOSDK304" ]]; then
addSymbol_system_func1 "0x54"
patchFile "eap.o" "19376" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
elif [[ ${VERSION} == "NONOSDK305" ]]; then
addSymbol_system_func1 "0x54"
patchFile "eap.o" "67670" "9" "dlBvcnRGcmVl" "ejJFYXBGcmVl" # special vPortFree to recover leaked memory
else
echo "WARN: Unknown address for system_func1() called by system_restart_local()"
fi
Expand Down
0