dnp3: bound the maximum number of objects per tx

Default to 2048, but provide a user configuration value.

Ticket: #8181
(cherry picked from commit 2c95f1ff44)
pull/14599/head
Jason Ish 4 months ago committed by Victor Julien
parent c03a8db521
commit bdbc38bca2

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

@ -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; \ app-layer-event:dnp3.too_many_points; \
threshold:type backoff, track by_flow, count 1, multiplier 10; \ threshold:type backoff, track by_flow, count 1, multiplier 10; \
classtype:protocol-command-decode; sid:2270005; rev:1;) 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). */ /* The maximum number of points allowed per message (configurable). */
static uint64_t max_points = 16384; 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. */ /* Decoder event map. */
SCEnumCharMap dnp3_decoder_event_table[] = { SCEnumCharMap dnp3_decoder_event_table[] = {
{ "FLOODED", DNP3_DECODER_EVENT_FLOODED }, { "FLOODED", DNP3_DECODER_EVENT_FLOODED },
@ -103,6 +106,7 @@ SCEnumCharMap dnp3_decoder_event_table[] = {
{ "MALFORMED", DNP3_DECODER_EVENT_MALFORMED }, { "MALFORMED", DNP3_DECODER_EVENT_MALFORMED },
{ "UNKNOWN_OBJECT", DNP3_DECODER_EVENT_UNKNOWN_OBJECT }, { "UNKNOWN_OBJECT", DNP3_DECODER_EVENT_UNKNOWN_OBJECT },
{ "TOO_MANY_POINTS", DNP3_DECODER_EVENT_TOO_MANY_POINTS }, { "TOO_MANY_POINTS", DNP3_DECODER_EVENT_TOO_MANY_POINTS },
{ "TOO_MANY_OBJECTS", DNP3_DECODER_EVENT_TOO_MANY_OBJECTS },
{ NULL, -1 }, { NULL, -1 },
}; };
@ -703,6 +707,7 @@ static int DNP3DecodeApplicationObjects(DNP3Transaction *tx, const uint8_t *buf,
{ {
int retval = 0; int retval = 0;
uint64_t point_count = 0; uint64_t point_count = 0;
uint64_t object_count = 0;
if (buf == NULL || len == 0) { if (buf == NULL || len == 0) {
return 1; return 1;
@ -717,6 +722,12 @@ static int DNP3DecodeApplicationObjects(DNP3Transaction *tx, const uint8_t *buf,
DNP3ObjHeader *header = (DNP3ObjHeader *)buf; DNP3ObjHeader *header = (DNP3ObjHeader *)buf;
offset += sizeof(DNP3ObjHeader); 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(); DNP3Object *object = DNP3ObjectAlloc();
if (unlikely(object == NULL)) { if (unlikely(object == NULL)) {
goto done; goto done;
@ -1615,6 +1626,13 @@ void RegisterDNP3Parsers(void)
max_points = (uint64_t)value; 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 { } else {
SCLogConfig("Parser disabled for protocol %s. " SCLogConfig("Parser disabled for protocol %s. "
"Protocol detection still on.", proto_name); "Protocol detection still on.", proto_name);

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

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

Loading…
Cancel
Save