espressif / ESP8266_RTOS_SDK

Latest ESP8266 SDK based on FreeRTOS, esp-idf style.
http://bbs.espressif.com
Apache License 2.0
3.34k stars 1.57k forks source link

`esp_timer_start_periodic` trips stack smashing protection (GIT8266O-731) #1153

Open szekelyisz opened 2 years ago

szekelyisz commented 2 years ago

Environment

Problem Description

Starting a periodic timer triggers stack smashing protection. The overflow actually happens in prvProcessTimerOrBlockTask.

Expected Behavior

Run without error.

Actual Behavior

See debug log below.

Steps to reproduce

  1. Enable COMPILER_STACK_CHECK_MODE_STRONG
  2. Compile code below
  3. Flash and monitor

Code to reproduce this issue

void print(void* arg) {
    ESP_LOGI("main", "tick");
}

void app_main(void)
{
    esp_timer_create_args_t args = {
            print,
            NULL,
            ESP_TIMER_TASK,
            "test"
    };
    esp_timer_handle_t timer;
    esp_timer_create(&args, &timer);
    ESP_LOGI("main", "before");
    esp_timer_start_periodic(timer, 1000000);
    ESP_LOGI("main", "after");
}

Debug Logs

I (107) main: start
I (108) main: before

Stack smashing protect failure!

abort() was called at PC 0x4021151e on core 0
0x4021151e: __stack_chk_fail at /home/szabi/esp/ESP8266_RTOS_SDK/components/esp_common/src/stack_check.c:37                                                     

Guru Meditation Error: Core  0 panic'ed (StoreProhibited). Exception was unhandled.
Core 0 register dump:
PC      : 0x40213ace  PS      : 0x00000030  A0      : 0x40213acc  A1      : 0x3ffeb070  
0x40213ace: abort at /home/szabi/esp/ESP8266_RTOS_SDK/components/newlib/src/syscall.c:69 (discriminator 1)

0x40213acc: abort at /home/szabi/esp/ESP8266_RTOS_SDK/components/newlib/src/syscall.c:69 (discriminator 1)

A2      : 0x00000000  A3      : 0xd38209ed  A4      : 0xd38209ed  A5      : 0x00000001  
A6      : 0x00000000  A7      : 0x00000000  A8      : 0x00000000  A9      : 0x00000000  
A10     : 0x00000000  A11     : 0x00000000  A12     : 0x00000001  A13     : 0x00000000  
A14     : 0x00000000  A15     : 0x00000000  SAR     : 0x0000001e  EXCCAUSE: 0x0000001d  

Backtrace: 0x40213ace:0x3ffeb070 0x40211521:0x3ffeb080 0x40213124:0x3ffeb090 0x4021322d:0x3ffeb0b0 
0x40213ace: abort at /home/szabi/esp/ESP8266_RTOS_SDK/components/newlib/src/syscall.c:69 (discriminator 1)

0x40211521: __stack_chk_fail at ??:?

0x40213124: prvProcessTimerOrBlockTask at /home/szabi/esp/ESP8266_RTOS_SDK/components/freertos/freertos/timers.c:595

0x4021322d: prvTimerTask at /home/szabi/esp/ESP8266_RTOS_SDK/components/freertos/freertos/timers.c:533 (discriminator 1)
szekelyisz commented 2 years ago

This is a duplicate of #1138.

szekelyisz commented 2 years ago

The problem is that __stack_chk_guard is initialized as prvProcessTimerOrBlockTask executes.

The initial value for __stack_chk_guard is NULL. This value is stored on the stack as a guard when prvProcessTimerOrBlockTask runs for the first time. During this call the main thread is woken up which executes __esp_stack_guard_setup that replaces the guard with a random value. After control returns to prvProcessTimerOrBlockTask, at the end of the function the re-initialized value is compared with the initial NULL value, and thus the check returns an error.

bowensong commented 2 years ago

The problem is that __stack_chk_guard is initialized as prvProcessTimerOrBlockTask executes.

The initial value for __stack_chk_guard is NULL. This value is stored on the stack as a guard when prvProcessTimerOrBlockTask runs for the first time. During this call the main thread is woken up which executes __esp_stack_guard_setup that replaces the guard with a random value. After control returns to prvProcessTimerOrBlockTask, at the end of the function the re-initialized value is compared with the initial NULL value, and thus the check returns an error.

You have described the root cause of the issue, but I'm afraid can't figure out a solution based on the description.

Could you please elaborate on how can I correctly initialise the __stack_chk_guard variable in order to avoid running into this issue?

szekelyisz commented 2 years ago

Could you please elaborate on how can I correctly initialise the __stack_chk_guard variable in order to avoid running into this issue?

I'll try moving the __esp_stack_guard_setup call into the bootloader. I'll submit a PR if it works.