-
Notifications
You must be signed in to change notification settings - Fork 926
[BUG] Reject DROPREQ with reversed seqno range #3321
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
Open
mszatmary-netflix
wants to merge
2
commits into
Haivision:master
Choose a base branch
from
mszatmary-netflix:fix/dropreq-reversed-range
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+48
−0
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 doesn't guarantee to reject any "stupid set of data" received in the UMSG_DROPREQ message.
Check on
srt::CRcvBuffer::dropMessagefor any real vulnerabilities that any kind of stupid data can cause. This function has important base data to check the incoming message if it provided any sensible data - it may need a fix, but any check like that here is completely pointless.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.
processCtrlDropReq does more than call dropMessage; after that call it also runs dropFromLossLists(lo, hi) and conditionally writes m_iRcvCurrSeqNo = dropdata[1]. Those don't go through the buffer, so a hostile (lo, hi) slips past any defense that lives only in dropMessage.
The pattern matches processCtrlLossReport. That handler does the identical seqcmp > 0 check at the caller layer
I mirrored an existing codebase convention. If their argument is right, that check is "pointless" too and the LOSSREPORT path needs the same restructuring
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.
Yes, and these functions do their checks as well.
If the data are sent by a rogue party, all we need to do is to perform only the minimum checks to prevent the code from crashing or the procedures from going haywire. Not from destroying the data or killing the transmission.
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 where we disagree. You also need to prevent a malicious party from setting internal state to arbitrary values that they control and are outside any valid range.
m_iRcvCurrSeqNo = dropdata[1]for example. Perhaps as part of a longer attack chain.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.
Yes, that's what I call the "haywire". Can you state that this field can potentially be set to the value that is outside of the range of sent packets?
Uh oh!
There was an error while loading. Please reload this page.
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, Not potentially, absolutely. But even if I'm wrong. Why take the risk?
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.
It's not that I'm ignoring the danger, I'm only trying to prevent things from getting worse.
The whole transmission bases on the premise that both sides cooperate with one another. So if one goes rogue, all the other party has to do is "you'll get what you deserve", in the form of stuck connection, inability to transmit, or even breaking the connection. A crazy sequence number in DROPREQ is the same problem as a crazy sequence number in the DATA packet or virtually anything else that uses a sequence number. The only things that we need to prevent are things like:
The field
m_iRcvCurrSeqNokeeps the newest sequence number of the incoming packet. Here it's set only if the sequence number is further in the future than the current value (see condition). If the value is further than any packet this party is about to send, because it's rogue, SO BE IT. The sending party KNOWS BETTER, even if it's stupid. The consequences of that will be at best that every packet with an older sequence will be treated as being in the past. The same thing would happen if you once receive a data packet with such a sequence. Of course this will be tried to be inserted into the buffer, which will possibly fail because it's outside the capacity.If you think this additional verification is worth doing just to limit the risk, I agree completely, but we need to have some basis for the verification, as sequence number are cirtular numbers: they represent a fragment of an infinite axis by being approximated to a fragmet of a wheel. To stay safe, we define the operational range for the numbers on the half of the wheel (see
CSeqNo::m_iSeqNoTH). But we need to have the first hook, and the best I think would be the base sequence of the receiver buffer, and the incoming sequence numbers shall not be distant to this value by more than quater of a wheel (CSeqNo::m_iSeqNoTH/2). Then, if this passes, we can compare these two numbers themselves, or even better, the relationship between offset values between them and the first sequence.As the
dropMessagefunction is called first, I think it is most suited to do this verification, and this can be upgraded by doing the rogue value verification, hence it can also return -1 in case when the values are rogue. The value would have to be remember in a variable of wider scope so that after exiting the lock section it can be verified and further operations would be rejected.