-
Notifications
You must be signed in to change notification settings - Fork 70
Description
Checklist
- Checked the issue tracker for similar issues to ensure this is not a duplicate
- Read the documentation to confirm the issue is not addressed there and your configuration is set correctly
- Tested with the latest version to ensure the issue hasn't been fixed
How often does this bug occurs?
always
Expected behavior
- The
port_objpointer should be deleted only once during cleanup. - Any further references to
port_objaftermb_port_ser_delete()must be avoided. - The Modbus controller shutdown process should not result in use-after-free errors, even with
HEAP_POISONING_COMPREHENSIVEenabled.
Actual behavior (suspected bug)
When mbm_rtu_transp_delete() is called, the mb_port_ser_delete() function frees port_obj.
Despite that, the same port_obj is still used later in mb_port_timer_delete() and mb_port_event_delete().
With HEAP_POISONING_COMPREHENSIVE enabled, this results in accessing memory filled with 0xFEFEFEFE, leading to:
- use-after-free issues
- potential crashes or undefined behavior
Error logs or terminal output
I (1899) MASTER_TEST: Destroy master...
Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.
Core 0 register dump:
PC : 0x400dcc51 PS : 0x00060130 A0 : 0x800dcdd1 A1 : 0x3ffb5300
--- 0x400dcc51: mb_port_timer_delete at <project_root>/managed_components/espressif__esp-modbus/modbus/mb_ports/common/port_timer.c:100
A2 : 0x3ffb8dd0 A3 : 0x00060d23 A4 : 0x00060d20 A5 : 0x00060d23
A6 : 0x3ffb5200 A7 : 0x0000cdcd A8 : 0xfefefefe A9 : 0x3ffb52e0
A10 : 0x3ffb8dd0 A11 : 0x3ffb655c A12 : 0xb33fffff A13 : 0x00000000
A14 : 0x3ffb2a10 A15 : 0x3ffb8e6c SAR : 0x00000018 EXCCAUSE: 0x0000001c
EXCVADDR: 0xfefefefe LBEG : 0x4000c46c LEND : 0x4000c477 LCOUNT : 0x00000000
--- 0x4000c46c: memset in ROM
--- 0x4000c477: memset in ROM
Backtrace: 0x400dcc4e:0x3ffb5300 0x400dcdce:0x3ffb5320 0x400db065:0x3ffb5340 0x400daf8d:0x3ffb5360 0x400d94c9:0x3ffb5390 0x400d943c:0x3ffb53c0 0x400d9472:0x3ffb5420 0x400ee988:0x3ffb5440 0x40087635:0x3ffb5470
--- 0x400dcc4e: mb_port_timer_delete at <project_root>/managed_components/espressif__esp-modbus/modbus/mb_ports/common/port_timer.c:98
--- 0x400dcdce: mbm_rtu_transp_delete at <project_root>/managed_components/espressif__esp-modbus/modbus/mb_transports/rtu/rtu_master.c:108
--- 0x400db065: mbm_delete at <project_root>/managed_components/espressif__esp-modbus/modbus/mb_objects/mb_master.c:279
--- 0x400daf8d: mbc_serial_master_delete at <project_root>/managed_components/espressif__esp-modbus/modbus/mb_controller/serial/mbc_serial_master.c:125
--- 0x400d94c9: mbc_master_delete at <project_root>/managed_components/espressif__esp-modbus/modbus/mb_controller/common/esp_modbus_master.c:25
--- 0x400d943c: master_operation_func at <project_root>/managed_components/espressif__esp-modbus/examples/serial/mb_serial_master/main/serial_master.c:456
--- 0x400d9472: app_main at <project_root>/managed_components/espressif__esp-modbus/examples/serial/mb_serial_master/main/serial_master.c:518
--- 0x400ee988: main_task at <IDF_PATH>/components/freertos/app_startup.c:208
--- 0x40087635: vPortTaskWrapper at <IDF_PATH>/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:139Steps to reproduce the behavior
- Enable
CONFIG_HEAP_POISONING_COMPREHENSIVE=yinsdkconfig. - Build and flash the Modbus master example located at
examples/protocols/modbus/serial/mb_serial_master. - When
mbc_master_delete(master_handle)is called, the program crashes. - Observe the heap poisoning violation or crash in the logs.
Project release version
modbus version 2.0.2, idf version v5.5-dev-2119
System architecture
Intel/AMD 64-bit (modern PC, older Mac)
Operating system
Linux
Operating system version
openSUSE Leap 15.6
Shell
ZSH
Additional context
When mbm_rtu_transp_delete(mb_trans_base_t *inst) is called, the mb_port_ser_delete(transp->base.port_obj) function frees port_obj. However, after this memory is freed, the same port_obj is still accessed later in mb_port_timer_delete() and mb_port_event_delete(), causing a use-after-free error. This issue becomes critical especially when HEAP_POISONING_COMPREHENSIVE is enabled, as freed objects are overwritten with patterns like 0xfefefefe instead of zeros, making the problem more apparent.
Calling mb_port_ser_delete(transp->base.port_obj) after mb_port_timer_delete(transp->base.port_obj) and mb_port_event_delete(transp->base.port_obj) solves my problem. However, I have noticed that this function is called in the reverse order (i.e., ser_delete is called first) multiple times throughout the codebase, indicating that the deletion sequence requires a major revision to prevent use-after-free errors reliably.