Skip to content

Buffer overflow / stack smashing in WiFiGenericClass::mode() #11218

Closed
@MattiasTF

Description

@MattiasTF

Board

ESP32, custom board

Device Description

n/a

Hardware Configuration

n/a

Version

latest master (checkout manually)

IDE Name

VSCode

Operating System

Linux

Flash frequency

80 MHz

PSRAM enabled

yes

Upload speed

1000000

Description

Since merging #11052, any application crashes with a stack smashing protect failure when exiting WiFiGenericClass::mode(), if gcc’s stack protector is set to "strong".

WiFiGenericClass::mode() attempts to disable LR mode if it’s not supposed to be enabled. To find out if LR is enabled, it calls esp_wifi_get_protocol(wifi_interface_t ifx, uint8_t *protocol_bitmap) and passes a pointer to a single uint8_t on the stack. However, esp_wifi_get_protocol writes two protocol bitmap bytes, thereby overwriting whatever comes after that one byte on the stack.

The crash can be fixed by making current_protocol an array of size 2.

The documentation doesn’t specify how many bytes are written to the pointer, so I’m not sure if this an arduino-esp32 bug or an IDF bug. esp_wifi_get_protocol is apparently provided by the closed source WiFi blob, which I cannot debug.

Sketch

static void get_protocols(wifi_interface_t wif)
{
    uint8_t buf[16];
    memset(buf, 0xaa, sizeof(buf));

    esp_wifi_get_protocol(wif, buf + sizeof(buf)/2);

    for (size_t i = 0; i < sizeof(buf); i++) {
        printf(" %02x", buf[i]);
    }
    printf("\n");
}

Debug Message

Stack smashing protect failure!

0x40083221: panic_abort at /home/user/idf-5-4-lib-builder/esp-idf/components/esp_system/panic.c:454
0x4008b591: esp_system_abort at /home/user/idf-5-4-lib-builder/esp-idf/components/esp_system/port/esp_system_chip.c:92
0x4008256a: __stack_chk_fail at /home/user/idf-5-4-lib-builder/esp-idf/components/esp_system/stack_check.c:28
0x4017ca6c: WiFiGenericClass::mode(wifi_mode_t) at /home/user/.platformio/packages/framework-arduinoespressif32/libraries/WiFi/src/WiFiGeneric.cpp:650
0x40152a36: Wifi::setup() at /home/user/esp32-firmware/software/src/modules/wifi/wifi.cpp:676
0x400e9215: setup() at /home/user/esp32-firmware/software/.pio/libdeps/esp32test/ArduinoJson/src/ArduinoJson/Json/JsonDeserializer.hpp:520
0x40184973: loopTask(void*) at /home/user/.platformio/packages/framework-arduinoespressif32/cores/esp32/main.cpp:59
0x4008b942: vPortTaskWrapper at /home/user/idf-5-4-lib-builder/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:139

Other Steps to Reproduce

To reproduce the crash, use -fstack-protector-strong when compiling a project that uses WiFi.

To observe the bytes written by esp_wifi_get_protocol, paste the sketch into WiFiGeneric.cpp and call it with WIFI_IF_AP or WIFI_IF_STA after the corresponding interface has been enabled in WiFiGeneric::mode(). It should retrieve the enabled protocols into the middle of a prepared buffer and print the buffer.

Expected output:
aa aa aa aa aa aa aa aa 07 aa aa aa aa aa aa aa
One byte should be written to the middle of the buffer.

Actual output:
aa aa aa aa aa aa aa aa 07 00 aa aa aa aa aa aa
Two bytes have been written to the middle of the buffer.

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions