Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 34.2k
Fix various overflows and UB in src/#7494
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
Uh oh!
There was an error while loading. Please reload this page.
Conversation
indutny commented Jun 30, 2016 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
`offset` is user supplied variable and may be bigger than `ts_obj_length`. There is no need to subtract them and pass along, so just throw when the subtraction result would overflow.
Many extensions are unknown to the `ClientHelloParser::ParseExtension`, do not cast user-supplied `uint16_t` to `enum`.
Before values are subtracted in C/C++ they are cast to a common type which depends on the types of lhs and rhs. Usually this means casting to a bigger type, and if the sizes are the same - casting to unsigned.
indutny commented Jun 30, 2016
Discovered with:
|
indutny commented Jun 30, 2016
addaleax commented Jun 30, 2016 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
For the |
bnoordhuis commented Jun 30, 2016
First two commits LGTM but as to the last one, it would be better to rewrite it to use unsigned types with proper bound checks, rather than haphazardly peppering it with static_casts. |
indutny commented Jun 30, 2016
@bnoordhuis it is using lots of negative integers, and I'm not too confident in the code at the moment to make serious refactoring. Adding casts, on other hand, makes things closer to what developer has intended. |
indutny commented Jun 30, 2016
@addaleax will it be? I think there is some algorithmic trickery there. |
jasnell commented Jun 30, 2016
I agree with @bnoordhuis ... the first two are fine, the third is questionable. Perhaps pull that one out into a separate PR where it can be iterated on? |
indutny commented Jun 30, 2016
Will surely do after I'll land the first two. Thanks! |
addaleax commented Jun 30, 2016 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
@indutny I’d actually say it’s a common pattern for descending |
indutny commented Jun 30, 2016
@addaleax oh yeah, I included that warning just for completeness. Sorry, forgot to comment! |
| if (offset >= ts_obj_length) | ||
| return env->ThrowRangeError("Offset is out of bounds"); | ||
trevnorrisJun 30, 2016 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
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.
just curious, are we missing test coverage that would have caught this?
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 is one edge case with max_length equal to 0, but otherwise nothing bad happens here. Btw, should we consider this as a breaking change?
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.
IMO you're simply making this defined behavior, which falls under a bug fix and a semver-minor.
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.
@trevnorris@indutny Tracked issue I got after upgrade to this point. Apparently this broke some of my code e.g. using protocol-buffers (and I'm sure some other binary encoders too) which, for certain data, are writing empty strings in the end of the buffer, which is safe operation (no-op) on its own and worked up until this PR without any extra checks.
I was going to prepare PR to fix this but sounds like it falls under
There is one edge case with max_length equal to 0
and I'm wondering whether we consider this an expected behavior?
Minimal sample: Buffer.alloc(0).write('') - works in pre-6.4.0, throws now.
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.
Yikes, sorry to break your code!
I don't have any strong opinion on how it should work, but to me it will be fine to not throw in this case.
cc @trevnorris
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.
@RReverser@indutny See #8127/#8154, it should already been fixed on master.
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.
@addaleax By master you mean v6.x? (because that's where issue is present, at least it was when I checked yesterday)
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.
@RReverser I’m a bit confused – the commit from #8154 is only in master, not yet on the v6.x branch, yes. I’d anticipate that it lands cleanly, so there should be no need for manual backporting?
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.
@addaleax Ah I thought you meant it should already work on v6.x branch (as in already landed). Sorry for misunderstanding.
indutny commented Jul 11, 2016
Landing first two commits, since there were no objection on them. |
indutny commented Jul 11, 2016
indutny commented Jul 11, 2016
Thank you everyone! |
`offset` is user supplied variable and may be bigger than `ts_obj_length`. There is no need to subtract them and pass along, so just throw when the subtraction result would overflow. PR-URL: #7494 Reviewed-By: Ben Noordhuis <[email protected]>
Many extensions are unknown to the `ClientHelloParser::ParseExtension`, do not cast user-supplied `uint16_t` to `enum`. PR-URL: #7494 Reviewed-By: Ben Noordhuis <[email protected]>
`offset` is user supplied variable and may be bigger than `ts_obj_length`. There is no need to subtract them and pass along, so just throw when the subtraction result would overflow. PR-URL: #7494 Reviewed-By: Ben Noordhuis <[email protected]>
Many extensions are unknown to the `ClientHelloParser::ParseExtension`, do not cast user-supplied `uint16_t` to `enum`. PR-URL: #7494 Reviewed-By: Ben Noordhuis <[email protected]>
addaleax commented Sep 30, 2016
I can’t quite see how either commit that landed qualifies as semver-minor… these seem like they could (should?) be backported to v4.x together with #8154? |
indutny commented Sep 30, 2016
@addaleax the |
addaleax commented Sep 30, 2016
I don’t think that difference can actually be triggered without touching the binding directly… but we don’t need to make a big fuzz about this, I’m perfectly fine with this not landing in v4. |
MylesBorins commented Sep 30, 2016
@addaleax it can still land as a minor |
addaleax commented Sep 30, 2016
Idk, maybe some people use things like |
Checklist
make -j4 test(UNIX), orvcbuild test nosign(Windows) passesAffected core subsystem(s)
src
Description of change
Fix various overflows and UB in src/
R= @bnoordhuis and/or @nodejs/collaborators
NOTE: This doesn't fix:
I'm open to suggestions how it could be approached, though.