New issue
Advanced search Search tips

Issue 740591 link

Starred by 1 user

Issue metadata

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



Sign in to add a comment

Function expressions in initializers of for-of/in loops are incorrectly scoped

Project Member Reported by ClusterFuzz, Jul 10 2017

Issue description

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

Fuzzer: inferno_js_fuzzer_c
Job Type: linux_asan_d8_dbg
Platform Id: linux

Crash Type: CHECK failure
Crash Address: 
Crash State:
  !v8::internal::FLAG_enable_slow_asserts || (object->IsJSReceiver()) in objects-i
  v8::internal::JSReceiver::cast
  cast<v8::internal::Object>
  
Sanitizer: address (ASAN)

Regressed: V8: 43441:43442

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


Issue filed automatically.

See https://dev.chromium.org/Home/chromium-security/bugs/reproducing-clusterfuzz-bugs for more information.
 
Cc: bmeu...@chromium.org
Probably caused by https://chromium-review.googlesource.com/c/563399/, and this CL was already reverted. 

+bmeurer@chromium.org, could you take a look?  Thanks!
Owner: mstarzinger@chromium.org
Status: Assigned (was: Untriaged)
Quite possible. Assigning to proper clusterfuzz rotation.
Nope, unrelated to the CL mentioned in comment #1, still reproduces on tip-of-tree. Will triage.
Reduced repro ...

for (let [a, b = c = function() { return a + b }] of [[0]]) {
  function f() { return a };
}
c();
Project Member

Comment 5 by sheriffbot@chromium.org, Jul 11 2017

Labels: M-61
Project Member

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

Labels: ReleaseBlock-Stable
This is a serious security regression. If you are not able to fix this quickly, please revert the change that introduced it.

If this doesn't affect a release branch, or has not been properly classified for severity, please update the Security_Impact or Security_Severity labels, and remove the ReleaseBlock label. To disable this altogether, apply ReleaseBlock-NA.

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

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

Labels: Pri-1

Comment 8 by gov...@chromium.org, Jul 11 2017

A friendly reminder that M61 branch is coming soon on 07/20! Your bug is labelled as Stable ReleaseBlock, pls make sure to land the fix ASAP to trunk. This way we branch M61 from a high quality trunk. Thank you.
Cc: mstarzinger@chromium.org adamk@chromium.org
Owner: neis@chromium.org
This seems to be caused by the function "c" binding the context of the iteration body but having scope information from outside of the iteration body. Georg agreed to take a look. Thanks!

---

The following is the scope information showing the function "c" to be in the surrounding block:

  block { // (0x467d748) (1133, 1221)
    // is hidden
    // 6 heap slots
    // local vars:
    LET a;  // (0x4687f98) context[4], forced context allocation, never assigned
    LET b;  // (0x4688008) context[5], forced context allocation, never assigned

    block { // (0x467e1c8) (1187, 1221)
      // 5 heap slots
      // local vars:
      LET a;  // (0x4685468) context[4], forced context allocation, never assigned
      LET b;  // (0x4685c80) local[1], never assigned, hole initialization elided

      block { // (0x467e3b8) (1189, 1221)
        // local vars:
        LET f;  // (0x467e730) local[0], never assigned

        function f () { // (0x467e528) (1203, 1218)
          // lazily parsed
          // 4 heap slots
        }
      }
    }

    function () { // (0x467d998) (1158, 1177)
    }
  }

---

But the bound context belong to the iteration body and only has a context[4] slot, not context[5] slot:

0x32acc060cbd1: [FixedArray]
 - map = 0x22b0f802e09 <Map(HOLEY_ELEMENTS)>
 - length: 5
           0: 0x2289ce604661 <JSFunction (sfi = 0x3af5bbc07c11)>
           1: 0x32acc060caa9 <FixedArray[6]>
           2: 0x2289ce62eeb1 <FixedArray[9]>
           3: 0x2289ce603d91 <FixedArray[280]>
           4: 0

 Issue 742677  has been merged into this issue.

Comment 11 by adamk@chromium.org, Jul 14 2017

Cc: neis@chromium.org
Owner: adamk@chromium.org
Status: Started (was: Assigned)
Looking into this now (as MUC is gone for the weekend)

Comment 12 by adamk@chromium.org, Jul 14 2017

Still digging here, but there are some major problems with for loop initializers that capture loop variables. E.g., the following should print 1 but prints 0:

for (let a = 0, b = () => a; a < 1; ++a) {
  a = 1;
  print(b());
}

(this one doesn't seem to be crashy, but it's quite wrong).

Comment 13 by adamk@chromium.org, Jul 14 2017

My mistake, it appears that I misread the spec and the stuff in #12 is per-spec (there are indeed two "a" variables in the spec).

Comment 14 by adamk@chromium.org, Jul 14 2017

I think the root of the problem is that the function expression in the initializer has the wrong scope chain: it closes over the dummy variables created in CreateForEachStatementTDZ (https://cs.chromium.org/chromium/src/v8/src/parsing/parser.cc?rcl=a47a2b11cb904b87c10c50ad2ff54668042d62ee&l=2069).

I have a (hacky) patch which uses the ParameterInitializerRewriter to reparent that function's scope, and that fixes these problems (while causing other problems elsewhere, which I've yet to track down).

What we really want to do is have a non-contiguous scope, which contains the declaration (including any sub-expressions) and the body of the loop, and have a sibling scope in which we evaluate the iterable expression (this is basically what the spec does). But we don't currently support non-contiguous scopes (every scope is assumed to extend from its start_position to its end_position).
 Issue 743540  has been merged into this issue.

Comment 16 by adamk@chromium.org, Jul 17 2017

Labels: -OS-Linux OS-All
Summary: Function expressions in initializers of for-of/in loops are incorrectly scoped (was: CHECK failure: !v8::internal::FLAG_enable_slow_asserts || (object->IsJSReceiver()) in objects-i)
Project Member

Comment 17 by ClusterFuzz, Jul 17 2017

Labels: OS-Linux

Comment 18 by adamk@chromium.org, Jul 18 2017

Cc: ca...@igalia.com

Comment 19 by adamk@chromium.org, Jul 21 2017

An easier-to-work-with test case, which doesn't have all the extra for-of scopes and temporaries:

for (const {length: a, b = function() { return a, +b }} in {foo: 42}) {
  (function() { b() })();
}

Comment 20 by adamk@chromium.org, Jul 24 2017

Labels: -ReleaseBlock-Stable
This bug has been around for years, so I'm inclined to say it shouldn't be a release blocker. Removing label, feel free to chime in if you disagree.

I'm still pondering a proper solution: what I really don't want to do is paper over the problem with another layer of AST-scope-rewriting and then have to revisit again in a couple months when an edge case there breaks.

Comment 21 by adamk@chromium.org, Jul 24 2017

After more discussion with neis, managed to find a related bug without involving context allocation or closures:

for (const {length: a, b = a } in {foo: 42}) {
  print(b);
}

should print "3", but instead throws a reference error. The problem is that the VariableProxy "a" in the initializer for "b" is in the wrong scope (it's in the for-loop scope, the same scope the enumerable expression is evaluated in).

Comment 22 by adamk@chromium.org, Jul 24 2017

Work in progress fix up at https://chromium-review.googlesource.com/c/583531/ (using AST-walking to find scopes to rewrite, despite my comments in #20).
Project Member

Comment 23 by sheriffbot@chromium.org, Jul 25 2017

Labels: ReleaseBlock-Stable
This is a serious security regression. If you are not able to fix this quickly, please revert the change that introduced it.

If this doesn't affect a release branch, or has not been properly classified for severity, please update the Security_Impact or Security_Severity labels, and remove the ReleaseBlock label. To disable this altogether, apply ReleaseBlock-NA.

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
High severity bugs block stable release, regardless of if they are regression or existed for a long time. We understand that you are trying to best to fix this properly, so this can slip the stable if you cannot have a proper fix by then. But it will definitely block the next stable then.
Project Member

Comment 25 by bugdroid1@chromium.org, Jul 25 2017

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

commit f1f228571578e57e84af428ef41e8cf44c191272
Author: Adam Klein <adamk@chromium.org>
Date: Tue Jul 25 18:26:16 2017

Rewrite scopes of initializers in for-in/of destructured declarations

Bug:  chromium:740591 
Change-Id: I869be41d8630b23704b9470c4d3db8a21bbde873
Reviewed-on: https://chromium-review.googlesource.com/583531
Reviewed-by: Georg Neis <neis@chromium.org>
Commit-Queue: Adam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46881}
[modify] https://crrev.com/f1f228571578e57e84af428ef41e8cf44c191272/src/parsing/parameter-initializer-rewriter.cc
[modify] https://crrev.com/f1f228571578e57e84af428ef41e8cf44c191272/src/parsing/parameter-initializer-rewriter.h
[modify] https://crrev.com/f1f228571578e57e84af428ef41e8cf44c191272/src/parsing/parser-base.h
[modify] https://crrev.com/f1f228571578e57e84af428ef41e8cf44c191272/src/parsing/parser.cc
[modify] https://crrev.com/f1f228571578e57e84af428ef41e8cf44c191272/src/parsing/pattern-rewriter.cc
[modify] https://crrev.com/f1f228571578e57e84af428ef41e8cf44c191272/test/cctest/interpreter/bytecode_expectations/AsyncGenerators.golden
[modify] https://crrev.com/f1f228571578e57e84af428ef41e8cf44c191272/test/cctest/interpreter/bytecode_expectations/ForAwaitOf.golden
[modify] https://crrev.com/f1f228571578e57e84af428ef41e8cf44c191272/test/cctest/interpreter/bytecode_expectations/ForOfLoop.golden
[modify] https://crrev.com/f1f228571578e57e84af428ef41e8cf44c191272/test/cctest/interpreter/bytecode_expectations/Generators.golden
[add] https://crrev.com/f1f228571578e57e84af428ef41e8cf44c191272/test/mjsunit/regress/regress-crbug-740591.js

Comment 26 by adamk@chromium.org, Jul 25 2017

Labels: Merge-Request-61
Status: Fixed (was: Started)
Project Member

Comment 27 by ClusterFuzz, Jul 26 2017

ClusterFuzz has detected this issue as fixed in range 46880:46881.

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

Fuzzer: inferno_js_fuzzer_c
Job Type: linux_asan_d8_dbg
Platform Id: linux

Crash Type: CHECK failure
Crash Address: 
Crash State:
  !v8::internal::FLAG_enable_slow_asserts || (object->IsJSReceiver()) in objects-i
  v8::internal::JSReceiver::cast
  cast<v8::internal::Object>
  
Sanitizer: address (ASAN)

Regressed: V8: 43441:43442
Fixed: V8: 46880:46881

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


See https://github.com/google/clusterfuzz-tools 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 28 by ClusterFuzz, Jul 26 2017

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

If this is incorrect, please add ClusterFuzz-Wrong label and re-open the issue.
Project Member

Comment 29 by bugdroid1@chromium.org, Jul 26 2017

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

commit 6d17cb3dc1bf8455f4748404f9bf31ac0acbc675
Author: Adam Klein <adamk@chromium.org>
Date: Wed Jul 26 09:22:42 2017

[ignition] Add DCHECK for FunctionLiteral scoping

This DCHECK would have triggered in the test cases in the attached bug.

Bug:  chromium:740591 
Change-Id: Ib8e866fe60f5f4ee825e6772f68be768925ed792
Reviewed-on: https://chromium-review.googlesource.com/585401
Commit-Queue: Georg Neis <neis@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46891}
[modify] https://crrev.com/6d17cb3dc1bf8455f4748404f9bf31ac0acbc675/src/interpreter/bytecode-generator.cc

Project Member

Comment 30 by sheriffbot@chromium.org, Jul 26 2017

Labels: -Restrict-View-SecurityTeam Restrict-View-SecurityNotify
Project Member

Comment 31 by sheriffbot@chromium.org, Jul 27 2017

Labels: -Merge-Request-61 Hotlist-Merge-Approved Merge-Approved-61
Your change meets the bar and is auto-approved for M61. Please go ahead and merge the CL to branch 3163 manually. Please contact milestone owner if you have questions.
Owners: amineer@(Android), cmasso@(iOS), ketakid @(ChromeOS), govind@(Desktop)

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Pls merge you change to M61 branch 3163 by 5:00 PM today, Thursday if possible so we can take it in for next week M61 last dev release. Thank you.

Comment 33 by adamk@chromium.org, Jul 27 2017

Note that I expect one more followup patch. Should I wait to merge till I have that as well?
Project Member

Comment 34 by bugdroid1@chromium.org, Jul 27 2017

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

commit 48a903eb3fecec0f88cd3d51dfd9f220456e34b6
Author: Adam Klein <adamk@chromium.org>
Date: Thu Jul 27 18:22:57 2017

Properly fix-up ClassLiterals in ReparentExpressionScope()

Everything inside a class lives inside the class scope, so
reparenting the class scope is the only operation that
should be done to ClassLiterals during reparenting.

Bug:  chromium:740591 
Change-Id: Ia5b96b44ff1ca6cfa274effb5a04651809bab9bd
Reviewed-on: https://chromium-review.googlesource.com/588054
Commit-Queue: Adam Klein <adamk@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46951}
[modify] https://crrev.com/48a903eb3fecec0f88cd3d51dfd9f220456e34b6/src/parsing/parameter-initializer-rewriter.cc
[modify] https://crrev.com/48a903eb3fecec0f88cd3d51dfd9f220456e34b6/test/mjsunit/regress/regress-crbug-740591.js

Comment 35 by adamk@chromium.org, Jul 28 2017

Labels: -Merge-Approved-61 Merge-Request-61
Re-tagging for a merge request, I'd like to take both f1f228571578e57e84af428ef41e8cf44c191272 and 48a903eb3fecec0f88cd3d51dfd9f220456e34b6.
Project Member

Comment 36 by sheriffbot@chromium.org, Jul 29 2017

Labels: -Merge-Request-61 Merge-Approved-61
Your change meets the bar and is auto-approved for M61. Please go ahead and merge the CL to branch 3163 manually. Please contact milestone owner if you have questions.
Owners: amineer@(Android), cmasso@(iOS), ketakid @(ChromeOS), govind@(Desktop)

For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Pls merge you change to M61 branch 3163 before 3:00 PM PT on Monday so we can take it in for next week last M61 Dev release. Thank you.
Project Member

Comment 38 by bugdroid1@chromium.org, Jul 31 2017

Labels: merge-merged-6.1
The following revision refers to this bug:
  https://chromium.googlesource.com/v8/v8.git/+/5acf7ebfbd7504b1e5d772a4505a0694b09c9902

commit 5acf7ebfbd7504b1e5d772a4505a0694b09c9902
Author: Adam Klein <adamk@chromium.org>
Date: Mon Jul 31 17:22:42 2017

Merged: Squashed multiple commits.

Merged: Rewrite scopes of initializers in for-in/of destructured declarations
Revision: f1f228571578e57e84af428ef41e8cf44c191272

Merged: Properly fix-up ClassLiterals in ReparentExpressionScope()
Revision: 48a903eb3fecec0f88cd3d51dfd9f220456e34b6

NOTRY=true
NOPRESUBMIT=true
NOTREECHECKS=true
TBR=neis@chromium.org

Bug:  chromium:740591 
Change-Id: I8697ff18d9588204e5911dc905771fe380e60752
Reviewed-on: https://chromium-review.googlesource.com/594470
Reviewed-by: Adam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/branch-heads/6.1@{#26}
Cr-Branched-From: 1bf2e10ddb194d4c2871a87a4732613419de892d-refs/heads/6.1.534@{#1}
Cr-Branched-From: e825c4318eb2065ffdf9044aa6a5278635c36427-refs/heads/master@{#46746}
[modify] https://crrev.com/5acf7ebfbd7504b1e5d772a4505a0694b09c9902/src/parsing/parameter-initializer-rewriter.cc
[modify] https://crrev.com/5acf7ebfbd7504b1e5d772a4505a0694b09c9902/src/parsing/parameter-initializer-rewriter.h
[modify] https://crrev.com/5acf7ebfbd7504b1e5d772a4505a0694b09c9902/src/parsing/parser-base.h
[modify] https://crrev.com/5acf7ebfbd7504b1e5d772a4505a0694b09c9902/src/parsing/parser.cc
[modify] https://crrev.com/5acf7ebfbd7504b1e5d772a4505a0694b09c9902/src/parsing/pattern-rewriter.cc
[modify] https://crrev.com/5acf7ebfbd7504b1e5d772a4505a0694b09c9902/test/cctest/interpreter/bytecode_expectations/AsyncGenerators.golden
[modify] https://crrev.com/5acf7ebfbd7504b1e5d772a4505a0694b09c9902/test/cctest/interpreter/bytecode_expectations/ForAwaitOf.golden
[modify] https://crrev.com/5acf7ebfbd7504b1e5d772a4505a0694b09c9902/test/cctest/interpreter/bytecode_expectations/ForOfLoop.golden
[modify] https://crrev.com/5acf7ebfbd7504b1e5d772a4505a0694b09c9902/test/cctest/interpreter/bytecode_expectations/Generators.golden
[add] https://crrev.com/5acf7ebfbd7504b1e5d772a4505a0694b09c9902/test/mjsunit/regress/regress-crbug-740591.js

Comment 39 by adamk@chromium.org, Jul 31 2017

Labels: -Merge-Approved-61 Merge-Merged-61
Labels: -ReleaseBlock-Stable
(Side track warning!)

Re: comment 12 & 13, I'm surprised that this:

for (let a = 0, b = () => a; a < 2; ++a) {
  print(b());
}

prints out
0
0

instead of
0
1

Wait, no, I'm not surprised (based on the previous example). Pls ignore.

Comment 43 by neis@chromium.org, Aug 8 2017

Cc: yangguo@chromium.org
Project Member

Comment 44 by bugdroid1@chromium.org, Aug 9 2017

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

commit 3e6cf71a779719c33a8ce4b2ada345d468459c27
Author: Marja Hölttä <marja@chromium.org>
Date: Wed Aug 09 10:54:09 2017

[parser] Alternative fix for chromium:740591

- Previous fix is https://chromium-review.googlesource.com/c/583531 but it
  diverges Scopes created by PreParser from Scopes created by Parser.

- This CL creates the inner block scope a bit earlier and (temporarily) pushes
  it into the scope chain for parsing the variable declarations in a for
  loop. The previous approach was to first parse the variable declarations and
  then reparent the AST nodes / Scopes created while parsing it afterwards.

- This CL partially reverts https://chromium-review.googlesource.com/c/583531;
  the new fix only touches parser-base.h (diff between patch sets 2 and 3 is the
  fix).

- The Ignition golden changes are basically undoing the changes done in that CL
  too.

Bug:  chromium:740591 
Change-Id: Iceff1383ef066317e754942bb5ff0c70a91bc937
Reviewed-on: https://chromium-review.googlesource.com/603787
Commit-Queue: Marja Hölttä <marja@chromium.org>
Reviewed-by: Adam Klein <adamk@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Reviewed-by: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47241}
[modify] https://crrev.com/3e6cf71a779719c33a8ce4b2ada345d468459c27/src/parsing/expression-scope-reparenter.cc
[modify] https://crrev.com/3e6cf71a779719c33a8ce4b2ada345d468459c27/src/parsing/expression-scope-reparenter.h
[modify] https://crrev.com/3e6cf71a779719c33a8ce4b2ada345d468459c27/src/parsing/parser-base.h
[modify] https://crrev.com/3e6cf71a779719c33a8ce4b2ada345d468459c27/src/parsing/parser.cc
[modify] https://crrev.com/3e6cf71a779719c33a8ce4b2ada345d468459c27/src/parsing/pattern-rewriter.cc
[modify] https://crrev.com/3e6cf71a779719c33a8ce4b2ada345d468459c27/test/cctest/interpreter/bytecode_expectations/AsyncGenerators.golden
[modify] https://crrev.com/3e6cf71a779719c33a8ce4b2ada345d468459c27/test/cctest/interpreter/bytecode_expectations/ForAwaitOf.golden
[modify] https://crrev.com/3e6cf71a779719c33a8ce4b2ada345d468459c27/test/cctest/interpreter/bytecode_expectations/ForOfLoop.golden
[modify] https://crrev.com/3e6cf71a779719c33a8ce4b2ada345d468459c27/test/cctest/interpreter/bytecode_expectations/Generators.golden

Project Member

Comment 45 by sheriffbot@chromium.org, Nov 1 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