-
Notifications
You must be signed in to change notification settings - Fork 886
Fixes for undefined behavior in the snmp decoder #1345
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
base: master
Are you sure you want to change the base?
Conversation
Before
After
Is this OK? |
With the pcap: |
print-snmp.c
Outdated
signbit = 0x80000000; | ||
} | ||
/* We can only store the low 32 bits of the given value. If we've | ||
* shifted the sign bit away, we will restore it below. */ |
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.
Some additional commentary about the method used to store only the low 32 bits (i.e., masking the upper 8 bits away before shifting left by 8 bits), and an indication that this avoids undefined behavior, might be useful
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.
How about
/* In order to avoid undefined behavior, we mask off the low
* 24 bits of the data before shifting up by 8 bits. Either
* way, we lose the top 8 bits, but shifting through the sign
* bit results in undefined data. If we've shifted the sign
* bit away, we will restore it below. */
7f180e4
to
28afdbc
Compare
Rebased.
And no SNMP code path. |
With a new test file without "IPv6 problem":
After
Is this OK? |
New capture file |
It's using the snmp printer because it's UDP port 162 (trap). The ASN.1 value is an out of bounds negative number. The old behavior shifted the sign bit away; the new behavior retains the sign bit but the number is still not the one represented in the packet. I think it's OK. |
Instead of shifting bits off the top of the 32-bit value, we mask off the top 8 bits before shifting them away, and restore the sign bit at the end. This still results in a result that is not what was intended, as this code can not handle values greater than 2^31-1 or smaller than -2^31, but this new mechanism results in a "more correct" garbage out, with no undefined behavior.
When decoding an OID, and shifting left by 7, mask off the top 7 bits first. This still results in GIGO, but avoids undefined behavior on the way there. OIDs with values this large are not supported by this code.
28afdbc
to
2eb5203
Compare
These changes fix undefined behavior in the snmp decoder when the underlying representation is of a value larger than 32-bits. The decoder fundamentally doesn't support these values, and the original behavior is GIGO. We retain the same GIGO behavior, but avoiding undefined behavior.
Fixes #1054