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.
After seeing how useful this library has proven to be to within the Arduino community, I decided to fuzz the parser.
All the fuzzing and testing was done in a Linux x64 environment, using AFL and LLVM's AddressSanitizer in order to hunt for weird behavior.
Shortly after beginning to fuzz the parser, I encountered a crash with the following sequence:
This interesting sequence produces a buffer over-read and overflow in the stack or heap, depending on where the JSON string is located, and can cause memory corruptions that crash the program.
The culprit is the escaped characters at the end of the quoted string, they cause the
extractFrom
function to miss the NULL terminator on the next cycle.The original
extractFrom
code is as follows:As you can see, this operation will eventually lead the NULL check to miss the string's null terminator, effectively causing a buffer over-read and overflow which can lead to security issues.
In order to illustrate the issue, let
[]
denote the pointer position, let!
denote NULL, and let this be the pointer state:The
unescapeChar
function will move the pointer to:At the beginning of the next cycle, the pointer will move one more step to:
And the
unescapeChar
function will once again move the pointer to:And, finally, at the beginning of the next cycle, the pointer will move and skip the null terminator:
The fix I propose simply checks to see if we've reached a premature ending after unescaping the character:
The ArduinoJson library passes all built-in tests with this fix.