Skip to content

Commit

Permalink
Heap addendum to handle changes in NON-OS SDK 3.0.x
Browse files Browse the repository at this point in the history
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
1 parent da48a52 commit c2e083e
Show file tree
Hide file tree
Showing 11 changed files with 136 additions and 15 deletions.
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
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 comments on commit c2e083e

Please sign in to comment.