mirror of
https://github.com/zeek/zeek.git
synced 2025-10-13 20:18:20 +00:00
Adjust modbus register array parsing.
For modbus message types that include variable amount of register values (uint16[]), setting a &length attribute without an explicit array size could trigger a parsing assertion since it allows for the "element" data pointer to travel past the "end of data" (e.g. when &length is odd). This is changed to now give both an array size and &length to earlier terminate the parsing of elements before the assert is checked and so a single out-of-bound check can be done for the entire array (leaving off &length causes an out-of-bound check for each element). Added another parameter to modbus events that carry register arrays to the script-layer which indicates the associated byte count from the message (allowing for invalid values to be detected): modbus_read_holding_registers_response modbus_read_input_registers_response modbus_write_multiple_registers_request modbus_read_write_multiple_registers_request modbus_read_write_multiple_registers_response modbus_read_fifo_queue_response
This commit is contained in:
parent
defed7b6f3
commit
c911d03c30
9 changed files with 79 additions and 22 deletions
|
@ -192,7 +192,7 @@ type ReadHoldingRegistersRequest(header: ModbusTCP_TransportHeader) = record {
|
|||
# RESPONSE FC=3
|
||||
type ReadHoldingRegistersResponse(header: ModbusTCP_TransportHeader) = record {
|
||||
byte_count: uint8;
|
||||
registers: uint16[] &length=byte_count;
|
||||
registers: uint16[byte_count/2] &length=byte_count;
|
||||
} &let {
|
||||
deliver: bool = $context.flow.deliver_ReadHoldingRegistersResponse(header, this);
|
||||
} &byteorder=bigendian;
|
||||
|
@ -208,7 +208,7 @@ type ReadInputRegistersRequest(header: ModbusTCP_TransportHeader) = record {
|
|||
# RESPONSE FC=4
|
||||
type ReadInputRegistersResponse(header: ModbusTCP_TransportHeader) = record {
|
||||
byte_count: uint8;
|
||||
registers: uint16[] &length=byte_count;
|
||||
registers: uint16[byte_count/2] &length=byte_count;
|
||||
} &let {
|
||||
deliver: bool = $context.flow.deliver_ReadInputRegistersResponse(header, this);
|
||||
} &byteorder=bigendian;
|
||||
|
@ -303,7 +303,7 @@ type ReadFileRecordRequest(header: ModbusTCP_TransportHeader) = record {
|
|||
type FileRecordResponse = record {
|
||||
file_len: uint8 &check(file_len >= 0x07 && file_len <= 0xF5);
|
||||
ref_type: uint8 &check(ref_type == 6);
|
||||
record_data: uint16[] &length=file_len;
|
||||
record_data: uint16[file_len/2] &length=file_len;
|
||||
} &byteorder=bigendian;
|
||||
|
||||
# RESPONSE FC=20
|
||||
|
@ -372,7 +372,7 @@ type ReadWriteMultipleRegistersRequest(header: ModbusTCP_TransportHeader) = reco
|
|||
# RESPONSE FC=23
|
||||
type ReadWriteMultipleRegistersResponse(header: ModbusTCP_TransportHeader) = record {
|
||||
byte_count: uint8;
|
||||
registers: uint16[] &length=byte_count;
|
||||
registers: uint16[byte_count/2] &length=byte_count;
|
||||
} &let {
|
||||
deliver: bool = $context.flow.deliver_ReadWriteMultipleRegistersResponse(header, this);
|
||||
} &byteorder=bigendian;
|
||||
|
@ -388,7 +388,7 @@ type ReadFIFOQueueRequest(header: ModbusTCP_TransportHeader) = record {
|
|||
type ReadFIFOQueueResponse(header: ModbusTCP_TransportHeader) = record {
|
||||
byte_count: uint16 &check(byte_count <= 62);
|
||||
fifo_count: uint16 &check(fifo_count <= 31);
|
||||
register_data: uint16[fifo_count] &length=byte_count/2;
|
||||
register_data: uint16[fifo_count] &length=fifo_count*2;
|
||||
} &let {
|
||||
deliver: bool = $context.flow.deliver_ReadFIFOQueueResponse(header, this);
|
||||
} &byteorder=bigendian;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue