dnp3: bound the maximum number of objects per tx

Default to 2048, but provide a user configuration value.

Ticket: #8181
pull/14592/merge
Jason Ish 1 week ago committed by Victor Julien
parent 3a32bb5743
commit 2c95f1ff44

@ -57,10 +57,11 @@ Other Changes
- tcp.window
- ``dnp3`` has reduced the maximum number of open transactions from
500 down to 32, and the maximum number of points per message from
unbounded to 16384. Configuration options, ``max-tx`` and
``max-points`` have been added for users who may need to change
these defaults.
500 down to 32, the maximum number of points per message from
unbounded to 16384, and the maximum number of objects per message
from unbounded to 2048. Configuration options, ``max-tx``,
``max-points``, and ``max-objects`` have been added for users who
may need to change these defaults.
Upgrading to 8.0.1
------------------

@ -30,3 +30,9 @@ alert dnp3 any any -> any any (msg:"SURICATA DNP3 Too many points in message"; \
app-layer-event:dnp3.too_many_points; \
threshold:type backoff, track by_flow, count 1, multiplier 10; \
classtype:protocol-command-decode; sid:2270005; rev:1;)
# Too many objects.
alert dnp3 any any -> any any (msg:"SURICATA DNP3 Too many objects"; \
app-layer-event:dnp3.too_many_objects; \
threshold:type backoff, track by_flow, count 1, multiplier 10; \
classtype:protocol-command-decode; sid:2270006; rev:1;)

@ -94,6 +94,9 @@ static uint64_t dnp3_max_tx = 32;
/* The maximum number of points allowed per message (configurable). */
static uint64_t max_points = 16384;
/* The maximum number of objects allowed per message (configurable). */
static uint64_t dnp3_max_objects = 2048;
/* Decoder event map. */
SCEnumCharMap dnp3_decoder_event_table[] = {
{ "FLOODED", DNP3_DECODER_EVENT_FLOODED },
@ -103,6 +106,7 @@ SCEnumCharMap dnp3_decoder_event_table[] = {
{ "MALFORMED", DNP3_DECODER_EVENT_MALFORMED },
{ "UNKNOWN_OBJECT", DNP3_DECODER_EVENT_UNKNOWN_OBJECT },
{ "TOO_MANY_POINTS", DNP3_DECODER_EVENT_TOO_MANY_POINTS },
{ "TOO_MANY_OBJECTS", DNP3_DECODER_EVENT_TOO_MANY_OBJECTS },
{ NULL, -1 },
};
@ -703,6 +707,7 @@ static int DNP3DecodeApplicationObjects(DNP3Transaction *tx, const uint8_t *buf,
{
int retval = 0;
uint64_t point_count = 0;
uint64_t object_count = 0;
if (buf == NULL || len == 0) {
return 1;
@ -717,6 +722,12 @@ static int DNP3DecodeApplicationObjects(DNP3Transaction *tx, const uint8_t *buf,
DNP3ObjHeader *header = (DNP3ObjHeader *)buf;
offset += sizeof(DNP3ObjHeader);
/* Check if we've exceeded the maximum number of objects. */
if (++object_count > dnp3_max_objects) {
DNP3SetEventTx(tx, DNP3_DECODER_EVENT_TOO_MANY_OBJECTS);
goto done;
}
DNP3Object *object = DNP3ObjectAlloc();
if (unlikely(object == NULL)) {
goto done;
@ -1615,6 +1626,13 @@ void RegisterDNP3Parsers(void)
max_points = (uint64_t)value;
}
}
/* Parse max-objects configuration. */
if (SCConfGetInt("app-layer.protocols.dnp3.max-objects", &value)) {
if (value > 0) {
dnp3_max_objects = (uint64_t)value;
}
}
} else {
SCLogConfig("Parser disabled for protocol %s. "
"Protocol detection still on.", proto_name);

@ -110,6 +110,7 @@ enum {
DNP3_DECODER_EVENT_MALFORMED,
DNP3_DECODER_EVENT_UNKNOWN_OBJECT,
DNP3_DECODER_EVENT_TOO_MANY_POINTS,
DNP3_DECODER_EVENT_TOO_MANY_OBJECTS,
};
/**

@ -1231,6 +1231,7 @@ app-layer:
dp: 20000
#max-tx: 32
#max-points: 16384
#max-objects: 2048
# SCADA EtherNet/IP and CIP protocol support
enip:

Loading…
Cancel
Save