Repository navigation
Bound the UTF-8 decode in napi_create_string_utf8 - #2267
Open
Medios-lgtm wants to merge 1 commit into
Open
Medios-lgtm wants to merge 1 commit into
Medios-lgtm wants to merge 1 commit into
Conversation
decodeUTF8 reads the continuation bytes of a sequence without an end check and relies on a terminator. With an explicit length, the input to napi_create_string_utf8 does not have to be null-terminated, so input that ends inside a multi-byte sequence was read past str + length. Decode a null-terminated copy instead.
This branch was successfully deployed
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
napi_create_string_utf8decodes non-ASCII input withhermes::decodeUTF8, which reads the continuation bytes of a multi-byte sequence without an end check and relies on a terminator to stop. With an explicitlength,strdoes not have to be null-terminated, so input that ends inside a multi-byte sequence (for example a slice of a larger buffer that cuts a character in half) is read up to 3 bytes paststr + length, and those bytes are decoded into the string when they happen to be continuation bytes. Under ASan, a 1-byte heap buffer holding0xE2passed withlength == 1gives a heap-buffer-overflow READ in_decodeUTF8SlowPathcalled fromnapi_create_string_utf8.The fix decodes a null-terminated copy, so a truncated sequence becomes U+FFFD, which is what the existing
CreateStringUtf8_Truncated*tests already expect for terminated input. The other UTF-8 entry points (property keys,node_api_symbol_for, function names) go through the boundedllvh::ConvertUTF8toUTF16and are not affected.Test Plan
Added
CreateStringUtf8_TruncatedAtLengthNotTerminated, which passes a length that ends inside a 2-byte and a 4-byte sequence. Before the fix it decodes the bytes afterlength(U+00E9, and a surrogate pair); after the fix each is a single U+FFFD.Also checked by hand in an ASan build with exact-size heap buffers (
new char[1]holding0xC3,0xE2or0xF0, length 1): heap-buffer-overflow before the fix, clean after.LIT_FILTER="napi|Napi" check-hermespasses.