stephane / libmodbus

A Modbus library for Linux, Mac OS, FreeBSD and Windows
http://libmodbus.org
GNU Lesser General Public License v2.1
3.4k stars 1.73k forks source link

Buffer overflow after several repeated connections between master and slave using the tcp protocol. #759

Open GodLiu1 opened 1 month ago

GodLiu1 commented 1 month ago

libmodbus version

3.1.10

OS and/or distribution

Ubuntu20.04

Environment

arm64

Description

Jetson Xavier NX

Actual behavior if applicable

The client connection from 127.0.0.1 is accepted Waiting for an indication...

<03><00><00><00><06><03><00><00><00><07> [03][F7][00][00][00][11][FF][03][0E][00][00][00][02][00][03][00][04][00][05][00][14][00][01] cnt=1015 The client connection from 127.0.0.1 is accepted Waiting for an indication... *** buffer overflow detected ***: terminated Aborted (core dumped) ## Expected behavior or suggestion Using tcp communication, after the master and slave have repeatedly reconnected more than 1015 times, a memory overflow interrupt occurs on the slave side, interrupted at rc = modbus_receive(ctx, query); function ## Steps to reproduce the behavior (commands or source code) slave code: ctx = modbus_new_tcp("127.0.0.1", 1502); if (ctx == NULL) { fprintf(stderr, "Failed to create the libmodbus context\n"); return -1; } query = (uint8_t *)malloc(MODBUS_TCP_MAX_ADU_LENGTH); if (query == NULL) { fprintf(stderr, "Failed to allocate memory for query\n"); modbus_free(ctx); return -1; } header_length = modbus_get_header_length(ctx); modbus_set_debug(ctx, TRUE); mb_mapping = modbus_mapping_new_start_address(0, 64, 0, 64, 0, 64, 0, 64); if (mb_mapping == NULL) { fprintf(stderr, "Failed to allocate the mapping: %s\n", modbus_strerror(errno)); modbus_free(ctx); free(query); return -1; } mb_mapping->tab_registers[0] = 0; mb_mapping->tab_registers[1] = 2; mb_mapping->tab_registers[2] = 3; mb_mapping->tab_registers[3] = 4; mb_mapping->tab_registers[4] = 5; mb_mapping->tab_registers[5] = 20; mb_mapping->tab_registers[6] = 1; s = modbus_tcp_listen(ctx, 1); if (s == -1) { fprintf(stderr, "Failed to listen: %s\n", modbus_strerror(errno)); modbus_free(ctx); modbus_mapping_free(mb_mapping); free(query); return -1; } int cnt=1; while (true) { modbus_tcp_accept(ctx, &s); rc = modbus_receive(ctx, query); if (rc == -1) { fprintf(stderr, "Receive failed: %s\n", modbus_strerror(errno)); break; } rc = modbus_reply(ctx, query, rc, mb_mapping); if (rc == -1) { fprintf(stderr, "Reply failed: %s\n", modbus_strerror(errno)); break; } std::cout<<"cnt="<tab_registers[i] = query[i]; } // 打印 Modbus 寄存器表中的值 std::cout << "Modbus register values: "; for (int i = 0; i < rc; i++) { std::cout << mb_mapping->tab_registers[i] << " "; } std::cout << std::endl; modbus_close(ctx); // 关闭连接 usleep(50000); // 等待200毫秒后再进行下一次读取 } // 清理资源 modbus_free(ctx); modbus_mapping_free(mb_mapping); return 0;
GodLiu1 commented 1 month ago

The problem is easy to reproduce, that is, repeatedly disconnecting and reconnecting will result in a memory overflow 1015 times on time, it should be that the modbus_receive() function internally shifted the pointer, I have looked at the source code, the problem should be found in line 350 of modbus.c in int _modbus_receive_msg(modbus_t ctx, uint8_t msg, msg_type_t msg_type), but unfortunately I haven't found the exact problem so far!