New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 738952 link

Starred by 1 user

Issue metadata

Status: Verified
Owner:
Closed: Jul 2017
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux
Pri: 1
Type: Bug-Security

Blocking:
issue 739186



Sign in to add a comment

Null-dereference READ in MemoryRead<unsigned

Project Member Reported by ClusterFuzz, Jul 4 2017

Issue description

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

Fuzzer: inferno_js_fuzzer
Job Type: linux_asan_d8_v8_arm64_dbg
Platform Id: linux

Crash Type: Null-dereference READ
Crash Address: 0x000000000000
Crash State:
  MemoryRead<unsigned
  v8::internal::Simulator::LoadStoreHelper
  v8::internal::Simulator::ExecuteInstruction
  
Sanitizer: address (ASAN)

Regressed: V8: 43047:43048

Reproducer Testcase: https://clusterfuzz.com/download?testcase_id=4656490341466112


Issue filed automatically.

See https://dev.chromium.org/Home/chromium-security/bugs/reproducing-clusterfuzz-bugs for more information.
 

Comment 1 by aarya@google.com, Jul 4 2017

Cc: ahaas@chromium.org
Owner: clemensh@chromium.org
Status: Assigned (was: Untriaged)
Blocking: 739186
Cc: titzer@chromium.org
Components: -Blink>JavaScript Blink>JavaScript>WebAssembly
Labels: -Type-Bug Security_Impact-Stable Restrict-View-SecurityTeam Type-Bug-Security
This actually looks like a code generation issue on arm64.
The problem is the f64->i32 conversion in the js-to-wasm wrapper.

The corresponding instruction in the schedule:
  27: TruncateFloat64ToWord32(26)

Then before register allocation:
      15: gap () () 
          v2(R) = ArchTruncateDoubleToI v3(R)

After register allocation (note the usage of x0, which is 64 bit):
      15: gap () () 
          [x0|R|w32] = ArchTruncateDoubleToI [d0|R|f64]

And then in the final code:
0x7f5dae08458c    2c  9e780000       fcvtzs x0, d0


Which (in the simulator) turns the value d0==-9.0072e+15 into x0==0xffe0000000000000.

Hence x0 contains a value bigger then 32 bit. This value is then passed to the wasm function, which assumes to receive a 32 bit integer. It bounds-check using a 32-bit comparison (w0 is the lower half of x0):
0x7f5dae084434    34  6b01001f       cmp w0, w1

And then accesses the memory using the 64 bit register:
0x7f5dae08443c    3c  58000321       ldr x1, pc+100 (addr 0x00007f5dae0844a0)    ;; wasm memory reference
0x7f5dae084440    40  b8606820       ldr w0, [x1, x0]

Which obviously crashes.
This crash reproduces (in the simulator!) all the way back to February, when we switched to version 0x1.

If this analysis is correct, this is a security issue. Flagging it appropriately, let's discuss solutions tomorrow. And find out whether it's a simulator-only bug, or whether it also happens on real hardware. I am not an arm expert, so maybe I also misinterpreted something.
Cc: -ahaas@chromium.org clemensh@chromium.org
Owner: ahaas@chromium.org
Project Member

Comment 5 by ClusterFuzz, Jul 5 2017

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

Fuzzer: inferno_js_fuzzer
Job Type: linux_asan_d8_v8_arm64_dbg
Platform Id: linux

Crash Type: Null-dereference READ
Crash Address: 0x000000000000
Crash State:
  MemoryWrite<unsigned
  v8::internal::Simulator::LoadStoreHelper
  v8::internal::Simulator::ExecuteInstruction
  
Sanitizer: address (ASAN)

Reproducer Testcase: https://clusterfuzz.com/download?testcase_id=4672370177736704


See https://dev.chromium.org/Home/chromium-security/bugs/reproducing-clusterfuzz-bugs for more information.

Comment 6 by ahaas@chromium.org, Jul 5 2017

Cc: martyn.c...@arm.com
I minimized the issue to a regression test which can be added to cctest/test-run-machops. The test crashes on arm64 but passes on x64.

  TEST(Regression738952) {                                                         
    BufferedRawMachineAssemblerTester<int32_t> m;                                  
                                                                                   
    int32_t sentinel = 1234;                                                       
    // The index can be any value where the lower bits are 0 and the upper bits    
    // are not 0;                                                                  
    int64_t index = 3224l << 32;                                                   
    double d = static_cast<double>(index);                                         
    m.Return(m.Load(MachineType::Int32(),                                          
                    m.PointerConstant(&sentinel),                                  
                    m.TruncateFloat64ToWord32(m.Float64Constant(d))));             
    CHECK_EQ(sentinel, m.Call());                                                  
  } 

The problem is that TruncateFloat64ToWord32 converts the float64 input into a int64, stored in an x register, and then assumes that the user of this value will use it with the w register. The comment in TruncateDoubleToI in the macro-assembler is the following:
    // Try to convert the double to an int64. If successful, the bottom 32 bits    
    // contain our truncated int32 result.

The code generation for a LOAD, however, assumes that it can always use the x-register for the address, even when the address actually comes in as a w-register. Therefore it uses the bits which should have been removed in the TruncateFloat64ToWord32.

Martyn, could you help me to find the right solution to this problem?
I think the addressing modes in MemoryOperand(size_t*) at the top of code-generator-arm64.cc should be changed to look more like the operations in the ASSEMBLE_CHECKED_* macros.

Specifically, if a load/store node is defined to use an address with a 64-bit base pointer and a signed 32-bit offset pointer, the kMode_Operand2_R_LSL_I, kMode_MRI and kMode_MRR addressing modes should use InputRegister32, and SXTW as the extension mode.

Though this disagrees with machine-graph-verifier.cc, which for kLoad/kAtomicLoad, says the offset representation is Pointer.

Comment 8 by ahaas@chromium.org, Jul 5 2017

Cc: jarin@chromium.org
Labels: Security_Severity-Medium
Status: Started (was: Assigned)
Project Member

Comment 11 by bugdroid1@chromium.org, Jul 6 2017

The following revision refers to this bug:
  https://chromium.googlesource.com/v8/v8.git/+/124ff5322da9c9064253b145278876607404ac78

commit 124ff5322da9c9064253b145278876607404ac78
Author: Andreas Haas <ahaas@chromium.org>
Date: Thu Jul 06 11:29:18 2017

[arm64] Clear the upper 32 bits after a TruncateDoubleToI

TruncateDoubleToI generated a 32-bit result but did not clear the upper
32 bits. This violated the invariant that the upper 32 bits should be
cleared when the result is 32 bits. This change fixes the bug mentioned
below. Clearing the upper 32 bits is also done on x64.

R=v8-arm-ports@googlegroups.com, titzer@chromium.org, martyn.capewell@arm.com

Bug:  chromium:738952 
Change-Id: I7e23e03fbed380ff08803db41fbae6382957ba08
Reviewed-on: https://chromium-review.googlesource.com/559671
Reviewed-by: Martyn Capewell <martyn.capewell@arm.com>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46440}
[modify] https://crrev.com/124ff5322da9c9064253b145278876607404ac78/src/arm64/macro-assembler-arm64.cc
[modify] https://crrev.com/124ff5322da9c9064253b145278876607404ac78/test/cctest/compiler/test-run-machops.cc

Project Member

Comment 12 by sheriffbot@chromium.org, Jul 6 2017

Labels: M-60
Project Member

Comment 13 by ClusterFuzz, Jul 7 2017

ClusterFuzz has detected this issue as fixed in range 46439:46440.

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

Fuzzer: inferno_js_fuzzer
Job Type: linux_asan_d8_v8_arm64_dbg
Platform Id: linux

Crash Type: Null-dereference READ
Crash Address: 0x000000000000
Crash State:
  MemoryRead<unsigned
  v8::internal::Simulator::LoadStoreHelper
  v8::internal::Simulator::ExecuteInstruction
  
Sanitizer: address (ASAN)

Regressed: V8: 43047:43048
Fixed: V8: 46439:46440

Reproducer Testcase: https://clusterfuzz.com/download?testcase_id=4656490341466112


See https://dev.chromium.org/Home/chromium-security/bugs/reproducing-clusterfuzz-bugs for more information.

If you suspect that the result above is incorrect, try re-doing that job on the test case report page.
Project Member

Comment 14 by ClusterFuzz, Jul 7 2017

ClusterFuzz has detected this issue as fixed in range 46439:46440.

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

Fuzzer: inferno_js_fuzzer
Job Type: linux_asan_d8_v8_arm64_dbg
Platform Id: linux

Crash Type: Null-dereference READ
Crash Address: 0x000000000000
Crash State:
  MemoryWrite<unsigned
  v8::internal::Simulator::LoadStoreHelper
  v8::internal::Simulator::ExecuteInstruction
  
Sanitizer: address (ASAN)

Regressed: V8: 43047:43048
Fixed: V8: 46439:46440

Reproducer Testcase: https://clusterfuzz.com/download?testcase_id=4672370177736704


See https://dev.chromium.org/Home/chromium-security/bugs/reproducing-clusterfuzz-bugs for more information.

If you suspect that the result above is incorrect, try re-doing that job on the test case report page.
Project Member

Comment 15 by ClusterFuzz, Jul 7 2017

Labels: ClusterFuzz-Verified
Status: Verified (was: Started)
ClusterFuzz testcase 4656490341466112 is verified as fixed, so closing issue.

If this is incorrect, please add ClusterFuzz-Wrong label and re-open the issue.
Labels: Merge-Request-60
Project Member

Comment 17 by sheriffbot@chromium.org, Jul 7 2017

Labels: -Merge-Request-60 Hotlist-Merge-Review Merge-Review-60
This bug requires manual review: M60 has already been promoted to the beta branch, so this requires manual review
Please contact the milestone owner if you have questions.
Owners: amineer@(Android), cmasso@(iOS), josafat@(ChromeOS), bustamante@(Desktop)

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

Comment 18 by sheriffbot@chromium.org, Jul 7 2017

Labels: -Restrict-View-SecurityTeam Restrict-View-SecurityNotify
Labels: -Merge-Review-60 Merge-Approved-60
Approving merge to M60.
Project Member

Comment 20 by bugdroid1@chromium.org, Jul 10 2017

Labels: merge-merged-6.0
The following revision refers to this bug:
  https://chromium.googlesource.com/v8/v8.git/+/985568950716273538a778f410683633e6487e57

commit 985568950716273538a778f410683633e6487e57
Author: Andreas Haas <ahaas@google.com>
Date: Mon Jul 10 09:47:11 2017

Merged: [arm64] Clear the upper 32 bits after a TruncateDoubleToI

Revision: 124ff5322da9c9064253b145278876607404ac78

BUG= chromium:738952 
LOG=N
NOTRY=true
NOPRESUBMIT=true
NOTREECHECKS=true
R=titzer@chromium.org

Change-Id: I9f57b8e6951113b34de63488b328db185bf10743
Reviewed-on: https://chromium-review.googlesource.com/564612
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/branch-heads/6.0@{#59}
Cr-Branched-From: 97dbf624a5eeffb3a8df36d24cdb2a883137385f-refs/heads/6.0.286@{#1}
Cr-Branched-From: 12e6f1cb5cd9616da7b9d4a7655c088778a6d415-refs/heads/master@{#45439}
[modify] https://crrev.com/985568950716273538a778f410683633e6487e57/src/arm64/macro-assembler-arm64.cc
[modify] https://crrev.com/985568950716273538a778f410683633e6487e57/test/cctest/compiler/test-run-machops.cc

Please merge this to M60 ASAP. branch:3112

Comment 22 by ahaas@chromium.org, Jul 10 2017

Labels: -Merge-Approved-60
Labels: Release-0-M60
Project Member

Comment 24 by sheriffbot@chromium.org, Oct 13 2017

Labels: -Restrict-View-SecurityNotify 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