Versions
-
OS: Ubuntu 20.04
-
libmodbus: 3.1.12
libmodbus Specific
-
Server: Modbus TCP server (127.0.0.1:1503), receives request with modbus_receive() and replies by modbus_reply_exception(ctx, query, MODBUS_EXCEPTION_ILLEGAL_FUNCTION).
-
Client: Modbus TCP client sends raw illegal function 0x83 via modbus_send_raw_request_tid.
Description
I was testing exception response construction for invalid function values in modbus_reply_exception.
Current implementation uses arithmetic addition:
sft.function = function + 0x80; (in src/modbus.c)
Per the Modbus protocol, exception function codes are formed by setting the highest bit (bit 8) of the request to 1 (bitwise OR | 0x80). However, the code uses arithmetic addition (+ 0x80) at modbus.c. For request function 0x83, the computed value becomes 0x103 and is truncated to 0x03 in an 8-bit response byte.
This makes an exception response function code look like a normal function code (0x03), while the next byte is still exception code 0x01, causing protocol semantic confusion.
Code and Logs
/* Root cause snippet: src/modbus.c */
sft.slave = slave;
sft.function = function + 0x80;
sft.t_id = ctx->backend->get_response_tid(req);
rsp_length = ctx->backend->build_response_basis(&sft, rsp);
/* PoC server snippet */
modbus_reply_exception(ctx, query, MODBUS_EXCEPTION_ILLEGAL_FUNCTION);
/* PoC client snippet */
uint8_t raw_req[2] = {1, 0x83};
modbus_send_raw_request_tid(ctx, raw_req, 2, 1);
$ ./server
Starting Modbus TCP server for exception function wrap-around PoC...
Client connection accepted from 127.0.0.1.
Waiting for an indication...
<00><01><00><00><00><02><01><83>
Received one request, sending exception with modbus_reply_exception.
[00][01][00][00][00][03][01][03][01]
Exception reply sent.
$ ./client
Connecting to 127.0.0.1:1503
[00][01][00][00][00][02][01][83]
Received 9 bytes.
Raw response: 00 01 00 00 00 03 01 03 01
Response function byte: 0x03
Response next byte: 0x01
Versions
OS: Ubuntu 20.04
libmodbus: 3.1.12
libmodbus Specific
Server: Modbus TCP server (
127.0.0.1:1503), receives request withmodbus_receive()and replies bymodbus_reply_exception(ctx, query, MODBUS_EXCEPTION_ILLEGAL_FUNCTION).Client: Modbus TCP client sends raw illegal function
0x83viamodbus_send_raw_request_tid.Description
I was testing exception response construction for invalid function values in
modbus_reply_exception.Current implementation uses arithmetic addition:
sft.function = function + 0x80;(insrc/modbus.c)Per the Modbus protocol, exception function codes are formed by setting the highest bit (bit 8) of the request to 1 (bitwise OR | 0x80). However, the code uses arithmetic addition (
+ 0x80) atmodbus.c. For request function0x83, the computed value becomes0x103and is truncated to0x03in an 8-bit response byte.This makes an exception response function code look like a normal function code (
0x03), while the next byte is still exception code0x01, causing protocol semantic confusion.Code and Logs