From 24c20d188e24c815e28351cddb838c01e7dfb241 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 6 Jan 2022 15:20:04 +0100 Subject: [PATCH] esp_rom: remove functions which depend on sizeof(struct stat) ...and all their callers. With the upcoming switch from sizeof(time_t)==4 to sizeof(time_t)==8, sizeof(struct stat) is also increasing. A few newlib functions present in ROM allocate 'struct stat' on the stack and call _fstat_r on this structure. The implementation of fstat is provided in ESP-IDF. This implementation will often do memset(st, 0, sizeof(*st)), where st is 'struct stat*', before setting some fields of this structure. If IDF is built with sizeof(st) different from sizeof(st) which ROM was built with, this will lead to an out-of-bounds write and a stack corruption. This commit removes problematic ROM functions from the linker script. Here are the functions which allocate 'struct stat': * _isatty_r (in ROM) * __swhatbuf_r, called by __smakebuf_r, called by __swsetup_r and __srefill_r (in ROM) * _fseeko_r (not in ROM) * glob2 (not in ROM) * _gettemp (not in ROM) As a result, these functions are used from libc.a, and use correct size of 'stat' structure. Closes https://github.com/espressif/esp-idf/issues/7980 --- components/esp_rom/CMakeLists.txt | 60 ++++++++++++++----- .../esp32/ld/esp32.rom.newlib-funcs.ld | 5 -- .../esp_rom/esp32/ld/esp32.rom.newlib-time.ld | 9 +++ .../esp32c3/ld/esp32c3.rom.newlib-time.ld | 15 +++++ .../esp_rom/esp32c3/ld/esp32c3.rom.newlib.ld | 4 -- .../esp32h2/ld/rev1/esp32h2.rom.newlib.ld | 6 +- .../esp32h2/ld/rev2/esp32h2.rom.newlib.ld | 6 +- .../esp32s2/ld/esp32s2.rom.newlib-funcs.ld | 5 -- .../esp32s2/ld/esp32s2.rom.newlib-time.ld | 16 +++++ .../esp32s3/ld/esp32s3.rom.newlib-time.ld | 15 +++++ .../esp_rom/esp32s3/ld/esp32s3.rom.newlib.ld | 4 -- .../esp_rom/esp8684/ld/esp8684.rom.newlib.ld | 6 +- 12 files changed, 103 insertions(+), 48 deletions(-) create mode 100644 components/esp_rom/esp32c3/ld/esp32c3.rom.newlib-time.ld create mode 100644 components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-time.ld create mode 100644 components/esp_rom/esp32s3/ld/esp32s3.rom.newlib-time.ld diff --git a/components/esp_rom/CMakeLists.txt b/components/esp_rom/CMakeLists.txt index 2af8d81cac..acdf0fca1f 100644 --- a/components/esp_rom/CMakeLists.txt +++ b/components/esp_rom/CMakeLists.txt @@ -97,13 +97,14 @@ else() # Regular app build # then all time functions from the ROM memory will not be linked. # Instead, those functions can be used from the toolchain by ESP-IDF. rom_linker_script("newlib-time") - endif() - # Include in newlib nano from ROM only if SPIRAM cache workaround is disabled - if(CONFIG_NEWLIB_NANO_FORMAT) - rom_linker_script("newlib-nano") - endif() + # Include in newlib nano from ROM only if SPIRAM cache workaround is disabled + # and sizeof(time_t) == 4 + if(CONFIG_NEWLIB_NANO_FORMAT) + rom_linker_script("newlib-nano") + endif() + endif() endif() if(NOT CONFIG_SPI_FLASH_ROM_DRIVER_PATCH) @@ -119,10 +120,19 @@ else() # Regular app build rom_linker_script("newlib-data") rom_linker_script("spiflash") - if(CONFIG_NEWLIB_NANO_FORMAT) - rom_linker_script("newlib-nano") + if(NOT CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS) + # If SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS option is defined + # then all time functions from the ROM memory will not be linked. + # Instead, those functions can be used from the toolchain by ESP-IDF. + + if(CONFIG_NEWLIB_NANO_FORMAT) + rom_linker_script("newlib-nano") + endif() + + rom_linker_script("newlib-time") endif() + # descirptors used by ROM code target_sources(${COMPONENT_LIB} PRIVATE "esp32s2/usb_descriptors.c") @@ -130,16 +140,32 @@ else() # Regular app build rom_linker_script("newlib") rom_linker_script("version") - if(CONFIG_NEWLIB_NANO_FORMAT) - rom_linker_script("newlib-nano") + if(NOT CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS) + # If SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS option is defined + # then all time functions from the ROM memory will not be linked. + # Instead, those functions can be used from the toolchain by ESP-IDF. + + if(CONFIG_NEWLIB_NANO_FORMAT) + rom_linker_script("newlib-nano") + endif() + + rom_linker_script("newlib-time") endif() elseif(target STREQUAL "esp32c3") rom_linker_script("newlib") rom_linker_script("version") - if(CONFIG_NEWLIB_NANO_FORMAT) - rom_linker_script("newlib-nano") + if(NOT CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS) + # If SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS option is defined + # then all time functions from the ROM memory will not be linked. + # Instead, those functions can be used from the toolchain by ESP-IDF. + + if(CONFIG_NEWLIB_NANO_FORMAT) + rom_linker_script("newlib-nano") + endif() + + rom_linker_script("newlib-time") endif() if(CONFIG_ESP32C3_REV_MIN_3) @@ -150,8 +176,10 @@ else() # Regular app build rom_linker_script("newlib") rom_linker_script("version") - if(CONFIG_NEWLIB_NANO_FORMAT) - rom_linker_script("newlib-nano") + if(NOT CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS) + if(CONFIG_NEWLIB_NANO_FORMAT) + rom_linker_script("newlib-nano") + endif() endif() elseif(target STREQUAL "esp8684") @@ -159,8 +187,10 @@ else() # Regular app build rom_linker_script("version") rom_linker_script("mbedtls") - if(CONFIG_NEWLIB_NANO_FORMAT) - rom_linker_script("newlib-nano") + if(NOT CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS) + if(CONFIG_NEWLIB_NANO_FORMAT) + rom_linker_script("newlib-nano") + endif() endif() endif() diff --git a/components/esp_rom/esp32/ld/esp32.rom.newlib-funcs.ld b/components/esp_rom/esp32/ld/esp32.rom.newlib-funcs.ld index d38e445274..79d5c5be0d 100644 --- a/components/esp_rom/esp32/ld/esp32.rom.newlib-funcs.ld +++ b/components/esp_rom/esp32/ld/esp32.rom.newlib-funcs.ld @@ -43,7 +43,6 @@ _getenv_r = 0x40001fbc; isalnum = 0x40000f04; isalpha = 0x40000f18; isascii = 0x4000c20c; -_isatty_r = 0x40000ea0; isblank = 0x40000f2c; iscntrl = 0x40000f50; isdigit = 0x40000f64; @@ -77,14 +76,11 @@ __sfmoreglue = 0x40001dc8; __sfp = 0x40001e90; __sfp_lock_acquire = 0x40001e08; __sfp_lock_release = 0x40001e14; -__sfvwrite_r = 0x4005893c; __sinit = 0x40001e38; __sinit_lock_acquire = 0x40001e20; __sinit_lock_release = 0x40001e2c; -__smakebuf_r = 0x40059108; srand = 0x40001004; __sread = 0x40001118; -__srefill_r = 0x400593d4; __sseek = 0x40001184; strcasecmp = 0x400011cc; strcasestr = 0x40001210; @@ -122,7 +118,6 @@ __submore = 0x40058f3c; __swbuf = 0x40058cb4; __swbuf_r = 0x40058bec; __swrite = 0x40001150; -__swsetup_r = 0x40058cc8; toascii = 0x4000c720; tolower = 0x40001868; toupper = 0x40001884; diff --git a/components/esp_rom/esp32/ld/esp32.rom.newlib-time.ld b/components/esp_rom/esp32/ld/esp32.rom.newlib-time.ld index f6b222eb10..50ec64882d 100644 --- a/components/esp_rom/esp32/ld/esp32.rom.newlib-time.ld +++ b/components/esp_rom/esp32/ld/esp32.rom.newlib-time.ld @@ -27,3 +27,12 @@ _timezone = 0x3ffae0a0; _tzname = 0x3ffae030; _daylight = 0x3ffae0a4; __month_lengths = 0x3ff9609c; + +/* These functions don't use time_t, but use other structures which include time_t. + * For example, 'struct stat' contains time_t. + */ +_isatty_r = 0x40000ea0; +__sfvwrite_r = 0x4005893c; +__smakebuf_r = 0x40059108; +__srefill_r = 0x400593d4; +__swsetup_r = 0x40058cc8; diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.newlib-time.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.newlib-time.ld new file mode 100644 index 0000000000..27734ced89 --- /dev/null +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.newlib-time.ld @@ -0,0 +1,15 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* These are the newlib functions and the .bss/.data symbols which are related to 'time_t' + or other structures which include 'time_t' (like 'struct stat'). + These ROM functions were compiled with sizeof(time_t) == 4. + When compiling with sizeof(time_t) == 8, these functions should be excluded from the build. + */ + +_isatty_r = 0x40000380; +PROVIDE( __smakebuf_r = 0x4000046c ); +PROVIDE( __swhatbuf_r = 0x40000470 ); +PROVIDE( __swsetup_r = 0x4000047c ); diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.newlib.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.newlib.ld index c086e8151c..257a919f3e 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.newlib.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.newlib.ld @@ -25,7 +25,6 @@ strncmp = 0x40000370; strlen = 0x40000374; strstr = 0x40000378; bzero = 0x4000037c; -_isatty_r = 0x40000380; sbrk = 0x40000384; isalnum = 0x40000388; isalpha = 0x4000038c; @@ -84,11 +83,8 @@ PROVIDE( fflush = 0x4000045c ); PROVIDE( _fflush_r = 0x40000460 ); PROVIDE( _fwalk = 0x40000464 ); PROVIDE( _fwalk_reent = 0x40000468 ); -PROVIDE( __smakebuf_r = 0x4000046c ); -PROVIDE( __swhatbuf_r = 0x40000470 ); PROVIDE( __swbuf_r = 0x40000474 ); __swbuf = 0x40000478; -PROVIDE( __swsetup_r = 0x4000047c ); /* Data (.data, .bss, .rodata) */ syscall_table_ptr = 0x3fcdffe0; _global_impure_ptr = 0x3fcdffdc; diff --git a/components/esp_rom/esp32h2/ld/rev1/esp32h2.rom.newlib.ld b/components/esp_rom/esp32h2/ld/rev1/esp32h2.rom.newlib.ld index 61b4b4715b..fc9ee8c9de 100644 --- a/components/esp_rom/esp32h2/ld/rev1/esp32h2.rom.newlib.ld +++ b/components/esp_rom/esp32h2/ld/rev1/esp32h2.rom.newlib.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -31,7 +31,6 @@ strncmp = 0x40000378; strlen = 0x4000037c; strstr = 0x40000380; bzero = 0x40000384; -_isatty_r = 0x40000388; sbrk = 0x4000038c; isalnum = 0x40000390; isalpha = 0x40000394; @@ -90,11 +89,8 @@ PROVIDE( fflush = 0x40000464 ); PROVIDE( _fflush_r = 0x40000468 ); PROVIDE( _fwalk = 0x4000046c ); PROVIDE( _fwalk_reent = 0x40000470 ); -PROVIDE( __smakebuf_r = 0x40000474 ); -PROVIDE( __swhatbuf_r = 0x40000478 ); PROVIDE( __swbuf_r = 0x4000047c ); __swbuf = 0x40000480; -PROVIDE( __swsetup_r = 0x40000484 ); /* Data (.data, .bss, .rodata) */ syscall_table_ptr = 0x3fcdffdc; _global_impure_ptr = 0x3fcdffd8; diff --git a/components/esp_rom/esp32h2/ld/rev2/esp32h2.rom.newlib.ld b/components/esp_rom/esp32h2/ld/rev2/esp32h2.rom.newlib.ld index 199e43d118..746ed1b771 100644 --- a/components/esp_rom/esp32h2/ld/rev2/esp32h2.rom.newlib.ld +++ b/components/esp_rom/esp32h2/ld/rev2/esp32h2.rom.newlib.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -31,7 +31,6 @@ strncmp = 0x400004a4; strlen = 0x400004a8; strstr = 0x400004ac; bzero = 0x400004b0; -_isatty_r = 0x400004b4; sbrk = 0x400004b8; isalnum = 0x400004bc; isalpha = 0x400004c0; @@ -90,11 +89,8 @@ fflush = 0x40000590; _fflush_r = 0x40000594; _fwalk = 0x40000598; _fwalk_reent = 0x4000059c; -__smakebuf_r = 0x400005a0; -__swhatbuf_r = 0x400005a4; __swbuf_r = 0x400005a8; __swbuf = 0x400005ac; -__swsetup_r = 0x400005b0; _strtod_l = 0x400005b4; _strtod_r = 0x400005b8; strtod_l = 0x400005bc; diff --git a/components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-funcs.ld b/components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-funcs.ld index fc976bbbaf..899997df46 100644 --- a/components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-funcs.ld +++ b/components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-funcs.ld @@ -29,7 +29,6 @@ _fwalk_reent = 0x4001bd24; isalnum = 0x400078d8; isalpha = 0x400078e8; isascii = 0x4001aaec; -_isatty_r = 0x400078a0; isblank = 0x400078f8; iscntrl = 0x40007918; isdigit = 0x40007930; @@ -66,11 +65,9 @@ __sfmoreglue = 0x4001a4c8; __sfp = 0x4001a590; __sfp_lock_acquire = 0x4001a508; __sfp_lock_release = 0x4001a514; -__sfvwrite_r = 0x40001310; __sinit = 0x4001a538; __sinit_lock_acquire = 0x4001a520; __sinit_lock_release = 0x4001a52c; -__smakebuf_r = 0x40001954; srand = 0x40007a24; __sread = 0x4001a660; __sseek = 0x4001a6cc; @@ -104,9 +101,7 @@ strtok_r = 0x4001af7c; strupr = 0x40008084; __swbuf = 0x4000167c; __swbuf_r = 0x400015bc; -__swhatbuf_r = 0x400018f8; __swrite = 0x4001a698; -__swsetup_r = 0x40001690; toascii = 0x4001af90; tolower = 0x40008158; toupper = 0x40008174; diff --git a/components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-time.ld b/components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-time.ld new file mode 100644 index 0000000000..1e705c698b --- /dev/null +++ b/components/esp_rom/esp32s2/ld/esp32s2.rom.newlib-time.ld @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* These are the newlib functions and the .bss/.data symbols which are related to 'time_t' + or other structures which include 'time_t' (like 'struct stat'). + These ROM functions were compiled with sizeof(time_t) == 4. + When compiling with sizeof(time_t) == 8, these functions should be excluded from the build. + */ + +__swsetup_r = 0x40001690; +__smakebuf_r = 0x40001954; +__swhatbuf_r = 0x400018f8; +__sfvwrite_r = 0x40001310; +_isatty_r = 0x400078a0; diff --git a/components/esp_rom/esp32s3/ld/esp32s3.rom.newlib-time.ld b/components/esp_rom/esp32s3/ld/esp32s3.rom.newlib-time.ld new file mode 100644 index 0000000000..986ce3a18d --- /dev/null +++ b/components/esp_rom/esp32s3/ld/esp32s3.rom.newlib-time.ld @@ -0,0 +1,15 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* These are the newlib functions and the .bss/.data symbols which are related to 'time_t' + or other structures which include 'time_t' (like 'struct stat'). + These ROM functions were compiled with sizeof(time_t) == 4. + When compiling with sizeof(time_t) == 8, these functions should be excluded from the build. + */ + +_isatty_r = 0x4000126c; +PROVIDE( __smakebuf_r = 0x40001530 ); +PROVIDE( __swsetup_r = 0x40001560 ); +PROVIDE( __swhatbuf_r = 0x4000153c ); diff --git a/components/esp_rom/esp32s3/ld/esp32s3.rom.newlib.ld b/components/esp_rom/esp32s3/ld/esp32s3.rom.newlib.ld index bd33a20187..2b64c0e940 100644 --- a/components/esp_rom/esp32s3/ld/esp32s3.rom.newlib.ld +++ b/components/esp_rom/esp32s3/ld/esp32s3.rom.newlib.ld @@ -25,7 +25,6 @@ strncmp = 0x4000123c; strlen = 0x40001248; strstr = 0x40001254; bzero = 0x40001260; -_isatty_r = 0x4000126c; sbrk = 0x40001278; isalnum = 0x40001284; isalpha = 0x40001290; @@ -84,11 +83,8 @@ PROVIDE( fflush = 0x40001500 ); PROVIDE( _fflush_r = 0x4000150c ); PROVIDE( _fwalk = 0x40001518 ); PROVIDE( _fwalk_reent = 0x40001524 ); -PROVIDE( __smakebuf_r = 0x40001530 ); -PROVIDE( __swhatbuf_r = 0x4000153c ); PROVIDE( __swbuf_r = 0x40001548 ); __swbuf = 0x40001554; -PROVIDE( __swsetup_r = 0x40001560 ); /* Data (.data, .bss, .rodata) */ syscall_table_ptr = 0x3fceffd4; _global_impure_ptr = 0x3fceffd0; diff --git a/components/esp_rom/esp8684/ld/esp8684.rom.newlib.ld b/components/esp_rom/esp8684/ld/esp8684.rom.newlib.ld index 0d10b6b187..92250ddeb4 100644 --- a/components/esp_rom/esp8684/ld/esp8684.rom.newlib.ld +++ b/components/esp_rom/esp8684/ld/esp8684.rom.newlib.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -30,7 +30,6 @@ strncmp = 0x400004a0; strlen = 0x400004a4; strstr = 0x400004a8; bzero = 0x400004ac; -_isatty_r = 0x400004b0; sbrk = 0x400004b4; isalnum = 0x400004b8; isalpha = 0x400004bc; @@ -89,11 +88,8 @@ fflush = 0x4000058c; _fflush_r = 0x40000590; _fwalk = 0x40000594; _fwalk_reent = 0x40000598; -__smakebuf_r = 0x4000059c; -__swhatbuf_r = 0x400005a0; __swbuf_r = 0x400005a4; __swbuf = 0x400005a8; -__swsetup_r = 0x400005ac; _strtod_l = 0x400005b0; _strtod_r = 0x400005b4; strtod_l = 0x400005b8;