New issue
Advanced search Search tips

Issue 700285 link

Starred by 1 user

Issue metadata

Status: WontFix
Owner:
Closed: Mar 2017
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Android , Windows , Chrome , Mac
Pri: 1
Type: Bug-Security



Sign in to add a comment

Heap-use-after-free in v8::internal::ExternalOneByteStringUtf16CharacterStream::FillBuffer

Project Member Reported by ClusterFuzz, Mar 10 2017

Issue description

Detailed report: https://clusterfuzz.com/testcase?key=5742655402409984

Fuzzer: meacer_chromebot_extensions
Job Type: mac_asan_chrome
Platform Id: mac

Crash Type: Heap-use-after-free READ 8
Crash Address: 0x62d00139287f
Crash State:
  v8::internal::ExternalOneByteStringUtf16CharacterStream::FillBuffer
  v8::internal::BufferedUtf16CharacterStream::ReadBlock
  void v8::internal::Scanner::Advance<false, true>
  
Sanitizer: address (ASAN)

Recommended Security Severity: High

Reproducer Testcase: https://clusterfuzz.com/download/AMIfv95nSBMDgteM7zjccE0RVAupyrjuzUW5u1DS1VJZEmpGZmnJskzQQIcV-Ty62TNX45fx-2w6WJugcsvb-WZY_1ohrk6nQq1eCklEOGbA-pWw-WjpUcL6UEf83GW1dL-1NaI9sShZ10ys3FVQZDZX803_cWFMlrTOE_DFpgvf-Triep1Jr8PrkHuaZCYGrgka9hIcEE_yFE1dQJ8lDoxnPuVNUIloL-Lc_y2irN3f4GKyKJPdsbdnT-fJ7ljdC52olF0rIFXtDbE__RQ9Id0754MF4_qrzWSvhXQLHXLCk2NS53SrgtNHnGiXGHn48VRPumB60aIDvOC_vN-E7gd6Hf2G6gNo3BPGja78Rrl1uCZ0SMCTccg?testcase_id=5742655402409984


Issue manually filed by: machenbach

See https://dev.chromium.org/Home/chromium-security/bugs/reproducing-clusterfuzz-bugs for more information.
 
Cc: machenb...@chromium.org
Cc: marja@chromium.org jochen@chromium.org vogelheim@chromium.org
Labels: Pri-1
Not reproducible, but maybe parser folks could have a look and analyze how we can get into this situation? Or how we could stress the test case to maybe make it reproduce?

Comment 3 by jochen@chromium.org, Mar 10 2017

I'd guess that the buffer source for the character stream is invalid.

Comment 4 by marja@chromium.org, Mar 10 2017

Just looking at the report (trying to not judge whether it makes sense or not):

The buffer is originally created by:

#1 0x25b9b3f96 in NewArray<unsigned char> v8/src/allocation.h:46:15
#2 0x25b9b3f96 in v8::internal::Assembler::GrowBuffer() v8/src/x64/assembler-x64.cc:419
#3 0x25b9cd124 in EnsureSpace v8/src/x64/assembler-x64.h:2505:52
#4 0x25b9cd124 in EnsureSpace v8/src/x64/assembler-x64.h:2504
#5 0x25b9cd124 in v8::internal::Assembler::movp(v8::internal::Register, void*, v8::internal::RelocInfo::Mode) v8/src/x64/assembler-x64.cc:1523
#6 0x25ab7c4a6 in CallLoadIC v8/src/full-codegen/full-codegen.cc:209:6
#7 0x25ab7c4a6 in v8::internal::FullCodeGenerator::EmitNamedPropertyLoad(v8::internal::Property*) v8/src/full-codegen/full-codegen.cc:1049

And then freed by:

#1 0x25ab71ed5 in ~MacroAssembler v8/src/x64/macro-assembler-x64.h:91:7
#2 0x25ab71ed5 in ~MacroAssembler v8/src/x64/macro-assembler-x64.h:91
#3 0x25ab71ed5 in v8::internal::FullCodeGenerator::MakeCode(v8::internal::CompilationInfo*, unsigned long) v8/src/full-codegen/full-codegen.cc:137
#4 0x25ab8b964 in v8::internal::FullCodegenCompilationJob::ExecuteJobImpl() v8/src/full-codegen/full-codegen.cc:40:12
#5 0x25a1d4d5c in v8::internal::CompilationJob::ExecuteJob() v8/src/compiler.cc:132:22

And then used by:

#0 0x25b283bc3 in CopyCharsUnsigned<unsigned char, unsigned short> v8/src/utils.h:1219:58
#1 0x25b283bc3 in v8::internal::ExternalOneByteStringUtf16CharacterStream::FillBuffer(unsigned long) v8/src/parsing/scanner-character-streams.cc:183
#2 0x25b282bb6 in v8::internal::BufferedUtf16CharacterStream::ReadBlock() v8/src/parsing/scanner-character-streams.cc:55:27
#3 0x25b28f3a1 in Advance v8/src/parsing/scanner.h:46:16
#4 0x25b28f3a1 in void v8::internal::Scanner::Advance<false, true>() v8/src/parsing/scanner.h:565
#5 0x25b28bfce in Init v8/src/parsing/scanner.h:473:5
#6 0x25b28bfce in v8::internal::Scanner::Initialize(v8::internal::Utf16CharacterStream*) v8/src/parsing/scanner.cc:190
#7 0x25b11c7c6 in v8::internal::Parser::DoParseFunction(v8::internal::ParseInfo*, v8::internal::AstRawString const*, v8::internal::Utf16CharacterStream*) v8/src/parsing/parser.cc:825:12
#8 0x25b11bc7d in v8::internal::Parser::ParseFunction(v8::internal::Isolate*, v8::internal::ParseInfo*) v8/src/parsing/parser.cc:792:14
#9 0x25b1fe7cf in v8::internal::parsing::ParseFunction(v8::internal::ParseInfo*, bool) v8/src/parsing/parsing.cc:55:19
#10 0x25a1dfd5c in v8::internal::(anonymous namespace)::GetUnoptimizedCode(v8::internal::CompilationInfo*, v8::internal::Compiler::ConcurrencyMode) v8/src/compiler.cc:656:10
#11 0x25a1d9965 in GetLazyCode v8/src/compiler.cc:1120:3
#12 0x25a1d9965 in v8::internal::Compiler::Compile(v8::internal::Handle<v8::internal::JSFunction>, v8::internal::Compiler::ClearExceptionFlag) v8/src/compiler.cc:1258
#13 0x25b3fa236 in __RT_impl_Runtime_CompileLazy v8/src/runtime/runtime-compiler.cc:37:8
#14 0x25b3fa236 in v8::internal::Runtime_CompileLazy(int, v8::internal::Object**, v8::internal::Isolate*) v8/src/runtime/runtime-compiler.cc:22

So we're parsing a lazy function and somehow point to a memory area which was previously owned by code generation. Huh?

As the string is ExternalOneByteString, it should point into the memory owned by Blink, no?
Yeah... the stacktrace contains scanner.cc:190, which is the call to SkipWhiteSpace() in Scanner::Initialize().

In other words: We're trying to read the very first bytes of the stream and want to skip any initial whitespace, before having even started any actual scanning or parsing work. I think that supports comment #3, that we've probably received an invalid stream. If so, we're probably too late in this, in that we're merely tripping over a bug elsewhere.

----

Options might be that the input data is completely garbled or, given that it's use-after-free, that Blink free-d the source string despite us still holding on to it.

I've looked through the allocation + free stack traces in the full report, but none of that made any sense to me. In particular, the previous use for this memory apparently wasn't source code.

Not sure about how to stress test, since I don't really have a theory on what's going wrong.

Comment 6 by palmer@chromium.org, Mar 14 2017

Components: Blink>JavaScript
Labels: OS-Android OS-Chrome OS-Linux OS-Windows

Comment 7 by tsepez@chromium.org, Mar 14 2017

Labels: Security_Impact-Stable M-57
Owner: vogelheim@chromium.org
Status: Assigned (was: Untriaged)
Marking as impact stable, but maybe impact none if not reproducible.  Let us know if you are working on this or if it is just going to get closed out.  Thanks!
Status: WontFix (was: Assigned)
WontFix: Unfortunately, without a repro I have neither enough info to debug, nor enough info to determine who might be a better assignee.


As explained in #5, it looks like we're been given un-allocated memory to parse. This suggests that the actual error has already happened by the time we try to parse it and we merely trip over the condition, rather than having caused it. (Or at least, having caused it at or near the stack trace.) However, the stack trace doesn't give us much info on where/when the source bug might have happened.

Please do re-open/re-assign if additional information or a repro case emerges.
Project Member

Comment 9 by sheriffbot@chromium.org, Jun 24 2017

Labels: -Restrict-View-SecurityTeam allpublic
This bug has been closed for more than 14 weeks. Removing security view restrictions.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot

Sign in to add a comment