-
Notifications
You must be signed in to change notification settings - Fork 34
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
Fix bounds checking pattern in parser #539
Conversation
4b8e0a9
to
126d578
Compare
Codecov Report
@@ Coverage Diff @@
## master #539 +/- ##
=======================================
Coverage 98.73% 98.73%
=======================================
Files 58 58
Lines 8681 8703 +22
=======================================
+ Hits 8571 8593 +22
Misses 110 110 |
Good refactoring/optimization opportunity after is to pass |
lib/fizzy/parser.hpp
Outdated
@@ -29,8 +29,8 @@ inline parser_result<uint8_t> parse_byte(const uint8_t* pos, const uint8_t* end) | |||
template <typename T> | |||
inline parser_result<T> parse_value(const uint8_t* pos, const uint8_t* end) | |||
{ | |||
constexpr auto size = sizeof(T); | |||
if (pos + size > end) | |||
static constexpr int size = sizeof(T); |
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.
why static?
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.
And why int
, isn't it then signed-unsigned comparison 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.
Pointer subtraction returns signed integer. I will use ptrdiff_t
for clarity if easily available.
For static
I don't remember, I will remove it.
lib/fizzy/utf8.cpp
Outdated
@@ -105,11 +105,12 @@ bool utf8_validate(const uint8_t* pos, const uint8_t* end) noexcept | |||
else | |||
return false; | |||
|
|||
assert(required_bytes > 1); |
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.
Could put this line after the comment 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.
Oh yeah, good point.
when would it be UB? |
The adversarial element is The first issue is in
And later this provokes another issue in pointer comparison
In practice, this is a security bug because in case there is a way to have a wasm module with |
126d578
to
a07aa2c
Compare
Use smaller (often exact size) buffers for test cases of input bounds checking in parser. This way we can detect incorrect pointer comparisons with ASan's pointer-compare and pointer-subtract instrumentation.
The previous pattern `pos + size < end` was incorrect leading to possible undefined behavior and potential addition overflow allowing the check bypass. The correct check is to compute the remaining size and compare with the declared size. This way invalid pointer comparison is replaced with correct pointer subtraction (pos and end are from the same memory buffer) and integer comparison: `(end - pos) < size`.
See previous commit for explanation.
a07aa2c
to
56978eb
Compare
The previous pattern
pos + size < end
was incorrect leading topossible undefined behavior and potential addition overflow allowing
the check bypass. The correct check is to compute the remaining size
and compare with the declared size. This way invalid pointer comparison
is replaced with correct pointer subtraction (pos and end are from the
same memory buffer) and integer comparison:
(end - pos) < size
.This will be additionally check with extended ASan options in #469.