diff --git a/scripts/dnp3-gen/dnp3-gen.py b/scripts/dnp3-gen/dnp3-gen.py index cc2aa8fc..a1c23f15 100755 --- a/scripts/dnp3-gen/dnp3-gen.py +++ b/scripts/dnp3-gen/dnp3-gen.py @@ -527,6 +527,10 @@ static int DNP3DecodeObjectG{{object.group}}V{{object.variation}}(const uint8_t object->{{field.len_field}} = prefix - (offset - *len); {% endif %} if (object->{{field.len_field}} > 0) { + if (*len < object->{{field.len_field}}) { + /* Not enough data. */ + goto error; + } memcpy(object->{{field.name}}, *buf, object->{{field.len_field}}); *buf += object->{{field.len_field}}; *len -= object->{{field.len_field}}; @@ -538,20 +542,20 @@ static int DNP3DecodeObjectG{{object.group}}V{{object.variation}}(const uint8_t if (!DNP3ReadUint8(buf, len, &octet)) { goto error; } -{% set shift = 0 %} +{% set ns = namespace(shift=0) %} {% for field in field.fields %} {% if field.width == 1 %} - object->{{field.name}} = (octet >> {{shift}}) & 0x1; + object->{{field.name}} = (octet >> {{ns.shift}}) & 0x1; {% elif field.width == 2 %} - object->{{field.name}} = (octet >> {{shift}}) & 0x3; + object->{{field.name}} = (octet >> {{ns.shift}}) & 0x3; {% elif field.width == 4 %} - object->{{field.name}} = (octet >> {{shift}}) & 0xf; + object->{{field.name}} = (octet >> {{ns.shift}}) & 0xf; {% elif field.width == 7 %} - object->{{field.name}} = (octet >> {{shift}}) & 0x7f; + object->{{field.name}} = (octet >> {{ns.shift}}) & 0x7f; {% else %} {{ raise("Unhandled width of %d." % (field.width)) }} {% endif %} -{% set shift = shift + field.width %} +{% set ns.shift = ns.shift + field.width %} {% endfor %} } {% else %} diff --git a/src/app-layer-dnp3-objects.c b/src/app-layer-dnp3-objects.c index 6c1a1d29..bfd0973d 100644 --- a/src/app-layer-dnp3-objects.c +++ b/src/app-layer-dnp3-objects.c @@ -6566,6 +6566,10 @@ static int DNP3DecodeObjectG70V1(const uint8_t **buf, uint32_t *len, goto error; } if (object->filename_size > 0) { + if (*len < object->filename_size) { + /* Not enough data. */ + goto error; + } memcpy(object->filename, *buf, object->filename_size); *buf += object->filename_size; *len -= object->filename_size; @@ -6575,6 +6579,10 @@ static int DNP3DecodeObjectG70V1(const uint8_t **buf, uint32_t *len, goto error; } if (object->data_size > 0) { + if (*len < object->data_size) { + /* Not enough data. */ + goto error; + } memcpy(object->data, *buf, object->data_size); *buf += object->data_size; *len -= object->data_size; @@ -6633,12 +6641,20 @@ static int DNP3DecodeObjectG70V2(const uint8_t **buf, uint32_t *len, goto error; } if (object->username_size > 0) { + if (*len < object->username_size) { + /* Not enough data. */ + goto error; + } memcpy(object->username, *buf, object->username_size); *buf += object->username_size; *len -= object->username_size; } object->username[object->username_size] = '\0'; if (object->password_size > 0) { + if (*len < object->password_size) { + /* Not enough data. */ + goto error; + } memcpy(object->password, *buf, object->password_size); *buf += object->password_size; *len -= object->password_size; @@ -6709,6 +6725,10 @@ static int DNP3DecodeObjectG70V3(const uint8_t **buf, uint32_t *len, goto error; } if (object->filename_size > 0) { + if (*len < object->filename_size) { + /* Not enough data. */ + goto error; + } memcpy(object->filename, *buf, object->filename_size); *buf += object->filename_size; *len -= object->filename_size; @@ -6775,6 +6795,10 @@ static int DNP3DecodeObjectG70V4(const uint8_t **buf, uint32_t *len, } object->optional_text_len = prefix - (offset - *len); if (object->optional_text_len > 0) { + if (*len < object->optional_text_len) { + /* Not enough data. */ + goto error; + } memcpy(object->optional_text, *buf, object->optional_text_len); *buf += object->optional_text_len; *len -= object->optional_text_len; @@ -6832,6 +6856,10 @@ static int DNP3DecodeObjectG70V5(const uint8_t **buf, uint32_t *len, } object->file_data_len = prefix - (offset - *len); if (object->file_data_len > 0) { + if (*len < object->file_data_len) { + /* Not enough data. */ + goto error; + } memcpy(object->file_data, *buf, object->file_data_len); *buf += object->file_data_len; *len -= object->file_data_len; @@ -6892,6 +6920,10 @@ static int DNP3DecodeObjectG70V6(const uint8_t **buf, uint32_t *len, } object->optional_text_len = prefix - (offset - *len); if (object->optional_text_len > 0) { + if (*len < object->optional_text_len) { + /* Not enough data. */ + goto error; + } memcpy(object->optional_text, *buf, object->optional_text_len); *buf += object->optional_text_len; *len -= object->optional_text_len; @@ -6956,6 +6988,10 @@ static int DNP3DecodeObjectG70V7(const uint8_t **buf, uint32_t *len, goto error; } if (object->filename_size > 0) { + if (*len < object->filename_size) { + /* Not enough data. */ + goto error; + } memcpy(object->filename, *buf, object->filename_size); *buf += object->filename_size; *len -= object->filename_size; @@ -7007,6 +7043,10 @@ static int DNP3DecodeObjectG70V8(const uint8_t **buf, uint32_t *len, object->file_specification_len = prefix - (offset - *len); if (object->file_specification_len > 0) { + if (*len < object->file_specification_len) { + /* Not enough data. */ + goto error; + } memcpy(object->file_specification, *buf, object->file_specification_len); *buf += object->file_specification_len; *len -= object->file_specification_len; @@ -7697,6 +7737,10 @@ static int DNP3DecodeObjectG120V7(const uint8_t **buf, uint32_t *len, } object->error_text_len = prefix - (offset - *len); if (object->error_text_len > 0) { + if (*len < object->error_text_len) { + /* Not enough data. */ + goto error; + } memcpy(object->error_text, *buf, object->error_text_len); *buf += object->error_text_len; *len -= object->error_text_len; @@ -7886,6 +7930,10 @@ static int DNP3DecodeObjectG120V10(const uint8_t **buf, uint32_t *len, goto error; } if (object->username_len > 0) { + if (*len < object->username_len) { + /* Not enough data. */ + goto error; + } memcpy(object->username, *buf, object->username_len); *buf += object->username_len; *len -= object->username_len; @@ -7968,6 +8016,10 @@ static int DNP3DecodeObjectG120V11(const uint8_t **buf, uint32_t *len, goto error; } if (object->username_len > 0) { + if (*len < object->username_len) { + /* Not enough data. */ + goto error; + } memcpy(object->username, *buf, object->username_len); *buf += object->username_len; *len -= object->username_len;