Validate Modbus frame size before writing the ADU buffer

modbus_message wrote register values into the fixed-size adu[] buffer
before any length validation; the only size check runs later in
modbus_send_rtu. A register count above MODBUS_MAX_REGISTERS overran
both the caller's values[] array and adu[], and even a multi-register
write within the register limit could exceed MODBUS_MAX_ADU_SIZE and
write past the buffer.

Reject requests exceeding MODBUS_MAX_REGISTERS, and reject multi-register
write frames larger than MODBUS_MAX_ADU_SIZE, before any adu[] write.
Single-register reads and writes are unaffected.
This commit is contained in:
Greg Cormier
2026-07-13 19:22:26 +00:00
parent 09f8ba597a
commit ee71df957a
+5
View File
@@ -278,6 +278,9 @@ FLASHMEM status_code_t modbus_message (uint8_t server, modbus_function_t functio
cmd.rx_length = 5;
} else {
if(registers > MODBUS_MAX_REGISTERS) // reject requests too large for adu[]
return Status_InvalidStatement;
cmd.tx_length = 6 + 2 * registers;
cmd.rx_length = cmd.tx_length - 1;
@@ -290,6 +293,8 @@ FLASHMEM status_code_t modbus_message (uint8_t server, modbus_function_t functio
}
} else {
cmd.tx_length += 3; cmd.rx_length = 8;
if(cmd.tx_length > MODBUS_MAX_ADU_SIZE || cmd.rx_length > MODBUS_MAX_ADU_SIZE)
return Status_InvalidStatement; // frame will not fit adu[]
cmd.adu[4] = (uint8_t)(registers >> 8);
cmd.adu[5] = (uint8_t)(registers & 0xFF);
cmd.adu[6] = (uint8_t)(registers << 1);