New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dnp3: added sanity checks to avoid crashes in a case of malformed data #5063
Conversation
@@ -840,6 +840,9 @@ static void DNP3HandleUserDataRequest(DNP3State *dnp3, const uint8_t *input, | |||
|
|||
lh = (DNP3LinkHeader *)input; | |||
|
|||
if (input_len <= sizeof(DNP3LinkHeader)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is already tested at line 1060
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it's not tested there since input_len is tested at 1060 but frame_len is passed to DNP3HandleUserDataRequest.
Well, probably frame_len is tested inside DNP3CalculateLinkLength so the test at 843 is not necessary.
Please see my reply to your second note with a complete explanation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed but line 1067 adds test if (input_len < frame_len) {
after if (input_len < sizeof(DNP3LinkHeader)) {
So, this line 843 test looks redundant to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
line 1067 forces waiting for the data if frame_len is bigger than input_len.
However, line 843 tests quite different condition, i.e. if frame_len is small (smaller than header length).
Well, I agree that 843 is redundant. But it's only because of DNP3CalculateLinkLength never returns value lesser than header length (or zero).
There is no other validation and 1067 would not do the trick if DNP3CalculateLinkLength could return any value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I understand better what you mean.
DNP3CalculateLinkLength
is indeed the good function checking that we have enough space in the frame (to use the name used in the source), even if we have more frames in the buffer.
One can use DEBUG_VALIDATE_BUG_ON
to add these safety checks, even if it is redundant today
Well, after some analysis i found only one place where an additional check is mandatory. |
Thanks for the reproducer. So, I would patch like this, to make
What do you think ? |
@ilya-bakhtin I compiled this fix with the probing parser direction fix and other things in #5093 |
I agree the root reason for the issue was inspecting a request on a response handling path. |
Closing in favor of #5093 |
Make sure these boxes are signed before submitting your Pull Request -- thank you.
Link to redmine ticket:
Describe changes:
DNP3 parser code contains some unsafe pointer arithmetic. It basically works in a case of correct data; however if the input is malformed then it crashes.
The fix adds some sanity checks to avoid the processing of malformed/incomplete data.
PRScript output (if applicable):
#suricata-verify-pr:
#suricata-verify-repo:
#suricata-verify-branch:
#suricata-update-pr:
#suricata-update-repo:
#suricata-update-branch:
#libhtp-pr:
#libhtp-repo:
#libhtp-branch: