-
Notifications
You must be signed in to change notification settings - Fork 721
Fix read overflow #1812
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: dev
Are you sure you want to change the base?
Fix read overflow #1812
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## dev #1812 +/- ##
==========================================
- Coverage 83.48% 83.48% -0.01%
==========================================
Files 311 311
Lines 54885 54890 +5
Branches 12218 12057 -161
==========================================
+ Hits 45822 45825 +3
+ Misses 7847 7846 -1
- Partials 1216 1219 +3
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Packet++/src/RawPacket.cpp
Outdated
if ((size_t)m_RawDataLen + dataToInsertLen < (size_t)m_RawDataLen) | ||
{ | ||
PCPP_LOG_ERROR("RawPacket::insertData: dataToInsertLen causes overflow"); | ||
return; | ||
} |
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.
Can we throw a std::length_error
instead of just returning with a error message? The error message will not indicate the error condition to the caller.
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.
Will throwing an exception prevent the application from crashing? 🤔
This method was called in BgpLayer
so we should probably think how to prevent it from being called with malformed data
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.
You want a crash if overflow happens. Or at least you want an exception thrown to indicate the failure of the operation, and if the caller doesn't handle it up the call stack, then to crash. It isn't really possible to recover from the situation as the system has reached the limit of how much data can be stored inside a packet.
Silently continuing with just an error message in the log is worse as the program will assume the operation went fine and produce corrupted data down the line. This is exactly the type of improbable situation the exception mechanism was made to handle.
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.
I totally agree, however I don't think throwing an exception will resolve the OSS-Fuzz issue. We should probably throw an exception and fix the issue that caused it in BgpLayer
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.
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.
Generally, I find exceptions are fine as long as they aren't used to dictate common control flow. The current mainstream compilers use an architecture that has a "zero cost" try-catch blocks if the exception isn't thrown. The tradeoff is a significant overhead if an exception is thrown, so you only want them thrown for rare events.
The current usage seems ok to me? How often are overflows expected to happen?
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.
In most cases, I wouldn't expect an exception to be thrown, however:
- In applications that use PcapPlusPlus with an arbitrary payload (either to test malformed packet handling or because they generate a random payload), an exception can be thrown and we would like to avoid the cost of it
- Most (or all?) of our critical path code doesn't catch exceptions and try to handle edge cases so they don't end up with exceptions. I think we should do the same here for consistency
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.
Hi, I have been working on other things and have been checking out this PR again. I agree with sela's points and will prepare a patch after a confirmation from your side -
- NO exception will be thrown in RawPacket, only it is logged and an error is returned. This is to ensure new clients of the code do not lead to a crash and code stylistically aligns with the rest.
- Separately, will add a check for the error in the BGPLayer as it is the only client in the project that uses it.
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.
I think we can still throw an error in insertData()
but I would avoid try..catch
in BgpLayer
and instead check the sizes before calling extendLayer()
. @Marti2203 let me know what you think
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.
Sounds good. I will also cover the nitpick and send it tonight :)
Packet++/src/RawPacket.cpp
Outdated
if ((size_t)m_RawDataLen + dataToInsertLen < (size_t)m_RawDataLen) | ||
{ | ||
PCPP_LOG_ERROR("RawPacket::insertData: dataToInsertLen causes overflow"); | ||
return; | ||
} |
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.
I think we can still throw an error in insertData()
but I would avoid try..catch
in BgpLayer
and instead check the sizes before calling extendLayer()
. @Marti2203 let me know what you think
Pushed an update. Feedback is appreciated! |
@Marti2203 CI fails, can you please take a look? |
Hi @seladb Apologies for the super late response, will take care of it today |
Thanks for the rerun, will check the results! |
@seladb I have added Packet.h to fix the forward declaration issue. Would be happy to discuss a different solution but I think that it should not be a problem |
if (m_Data != nullptr && m_Packet != nullptr) | ||
{ | ||
auto raw_len = static_cast<size_t>(m_Packet->getRawPacket()->getRawDataLen()); | ||
if (raw_len + bytesToExtend < raw_len) |
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 can this be true? 🤔
bytesToExtend
is of type size_t
, which can't be a negative number
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.
As previously discussed, this can overflow when unsigned going back to a lower 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.
You're right! Can you add a comment above this line to remind future us why we did it? 🙂
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.
Sure! 😄 It is an annoying edge-case
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.
Can you add the packet data that caused this issue to our regression tests, the same way it's done in this PR?
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.
Sure, will do!
Fixes the following issue detected by OSS-Fuzz:
This fix was generated by CodeRover-S, an LLM agent for fixing security vulnerabilities. More details can be found at: