Commit 1e06ed35 authored by Jaroslav Sevcik's avatar Jaroslav Sevcik Committed by Commit Bot

[test] Add type confusion poisoning test for polymorhic access.

Bug: chromium:866847
Change-Id: Icfda750c64c31ab48a882822883f6cef51c5bf92
Reviewed-on: https://chromium-review.googlesource.com/c/1270918Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56537}
parent bc2d6ccf
......@@ -30,6 +30,29 @@ std::string DisassembleFunction(const char* function) {
return os.str();
}
struct Matchers {
std::string start = "0x[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +";
std::regex map_load_re =
std::regex(start + "ldr r([0-9]+), \\[r([0-9]+), #-1\\]");
std::regex load_const_re = std::regex(start + "ldr r([0-9]+), \\[pc, .*");
std::regex cmp_re = std::regex(start + "cmp r([0-9]+), r([0-9]+)");
std::regex bne_re = std::regex(start + "bne (.*)");
std::regex beq_re = std::regex(start + "beq (.*)");
std::regex b_re = std::regex(start + "b (.*)");
std::regex eorne_re =
std::regex(start + "eorne r([0-9]+), r([0-9]+), r([0-9]+)");
std::regex eoreq_re =
std::regex(start + "eoreq r([0-9]+), r([0-9]+), r([0-9]+)");
std::regex csdb_re = std::regex(start + "csdb");
std::regex load_field_re =
std::regex(start + "ldr r([0-9]+), \\[r([0-9]+), #\\+[0-9]+\\]");
std::regex mask_re =
std::regex(start + "and r([0-9]+), r([0-9]+), r([0-9]+)");
std::regex untag_re = std::regex(start + "mov r([0-9]+), r([0-9]+), asr #1");
std::string poison_reg = "9";
};
TEST(DisasmPoisonMonomorphicLoad) {
#ifdef ENABLE_DISASSEMBLER
if (i::FLAG_always_opt || !i::FLAG_opt) return;
......@@ -47,25 +70,14 @@ TEST(DisasmPoisonMonomorphicLoad) {
"%OptimizeFunctionOnNextCall(mono);"
"mono({ x : 1 });");
std::string start("0x[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +");
std::regex map_load_re(start + "ldr r([0-9]+), \\[r([0-9]+), #-1\\]");
std::regex load_const_re(start + "ldr r([0-9]+), \\[pc, .*");
std::regex cmp_re(start + "cmp r([0-9]+), r([0-9]+)");
std::regex bne_re(start + "bne(.*)");
std::regex eorne_re(start + "eorne r([0-9]+), r([0-9]+), r([0-9]+)");
std::regex csdb_re(start + "csdb");
std::regex load_field_re(start +
"ldr r([0-9]+), \\[r([0-9]+), #\\+[0-9]+\\]");
std::regex mask_re(start + "and r([0-9]+), r([0-9]+), r([0-9]+)");
std::string poison_reg = "9";
Matchers m;
std::smatch match;
std::string line;
std::istringstream reader(DisassembleFunction("mono"));
bool poisoning_sequence_found = false;
while (std::getline(reader, line)) {
if (std::regex_match(line, match, map_load_re)) {
if (std::regex_match(line, match, m.map_load_re)) {
std::string map_reg = match[1];
std::string object_reg = match[2];
// Matches that the property access sequence is instrumented with
......@@ -81,34 +93,194 @@ TEST(DisasmPoisonMonomorphicLoad) {
// and r0, r0, r9 ; apply the poison
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, load_const_re));
CHECK(std::regex_match(line, match, m.load_const_re));
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, m.cmp_re));
CHECK_EQ(match[1], map_reg);
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, m.bne_re));
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, m.eorne_re));
CHECK_EQ(match[1], m.poison_reg);
CHECK_EQ(match[2], m.poison_reg);
CHECK_EQ(match[3], m.poison_reg);
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, m.csdb_re));
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, m.load_field_re));
CHECK_EQ(match[2], object_reg);
std::string field_reg = match[1];
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, m.mask_re));
CHECK_EQ(match[1], field_reg);
CHECK_EQ(match[2], field_reg);
CHECK_EQ(match[3], m.poison_reg);
poisoning_sequence_found = true;
break;
}
}
CHECK(poisoning_sequence_found);
#endif // ENABLE_DISASSEMBLER
}
TEST(DisasmPoisonPolymorphicLoad) {
#ifdef ENABLE_DISASSEMBLER
if (i::FLAG_always_opt || !i::FLAG_opt) return;
i::FLAG_allow_natives_syntax = true;
i::FLAG_untrusted_code_mitigations = true;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
CompileRun(
"function poly(o) { return o.x + 1; };"
"let o1 = { x : 1 };"
"let o2 = { y : 1 };"
"o2.x = 2;"
"poly(o1);"
"poly(o2);"
"poly(o1);"
"poly(o2);"
"%OptimizeFunctionOnNextCall(poly);"
"poly(o1);");
Matchers m;
std::smatch match;
std::string line;
std::istringstream reader(DisassembleFunction("poly"));
bool poisoning_sequence_found = false;
while (std::getline(reader, line)) {
if (std::regex_match(line, match, m.map_load_re)) {
std::string map_reg = match[1];
std::string object_reg = match[2];
// Matches that the property access sequence is instrumented with
// poisoning. We match the following sequence:
//
// ldr r1, [r0, #-1] ; load map
// ldr r2, [pc, #+104] ; load map constant #1
// cmp r1, r2 ; compare maps
// beq +Lcase1 ; if match, got to the load
// eoreq r9, r9, r9 ; update the poison
// csdb ; speculation barrier
// ldr r1, [r0, #-1] ; load map
// ldr r2, [pc, #+304] ; load map constant #2
// cmp r1, r2 ; compare maps
// bne +Ldeopt ; deopt if different
// eorne r9, r9, r9 ; update the poison
// csdb ; speculation barrier
// ldr r0, [r0, #+11] ; load the field
// and r0, r0, r9 ; apply the poison
// mov r0, r0, asr #1 ; untag
// b +Ldone ; goto merge point
// Lcase1:
// eorne r9, r9, r9 ; update the poison
// csdb ; speculation barrier
// ldr r0, [r0, #+3] ; load property backing store
// and r0, r0, r9 ; apply the poison
// ldr r0, [r0, #+3] ; load the property
// and r0, r0, r9 ; apply the poison
// Ldone:
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, m.load_const_re));
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, m.cmp_re));
CHECK_EQ(match[1], map_reg);
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, m.beq_re));
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, m.eoreq_re));
CHECK_EQ(match[1], m.poison_reg);
CHECK_EQ(match[2], m.poison_reg);
CHECK_EQ(match[3], m.poison_reg);
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, m.csdb_re));
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, m.map_load_re));
map_reg = match[1];
CHECK_EQ(match[2], object_reg);
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, m.load_const_re));
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, cmp_re));
CHECK(std::regex_match(line, match, m.cmp_re));
CHECK_EQ(match[1], map_reg);
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, bne_re));
CHECK(std::regex_match(line, match, m.bne_re));
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, eorne_re));
CHECK_EQ(match[1], poison_reg);
CHECK_EQ(match[2], poison_reg);
CHECK_EQ(match[3], poison_reg);
CHECK(std::regex_match(line, match, m.eorne_re));
CHECK_EQ(match[1], m.poison_reg);
CHECK_EQ(match[2], m.poison_reg);
CHECK_EQ(match[3], m.poison_reg);
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, csdb_re));
CHECK(std::regex_match(line, match, m.csdb_re));
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, load_field_re));
CHECK(std::regex_match(line, match, m.load_field_re));
CHECK_EQ(match[2], object_reg);
std::string field_reg = match[1];
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, mask_re));
CHECK(std::regex_match(line, match, m.mask_re));
CHECK_EQ(match[1], field_reg);
CHECK_EQ(match[2], field_reg);
CHECK_EQ(match[3], m.poison_reg);
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, m.untag_re));
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, m.b_re));
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, m.eorne_re));
CHECK_EQ(match[1], m.poison_reg);
CHECK_EQ(match[2], m.poison_reg);
CHECK_EQ(match[3], m.poison_reg);
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, m.csdb_re));
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, m.load_field_re));
CHECK_EQ(match[2], object_reg);
std::string storage_reg = match[1];
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, m.mask_re));
CHECK_EQ(match[1], storage_reg);
CHECK_EQ(match[2], storage_reg);
CHECK_EQ(match[3], m.poison_reg);
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, m.load_field_re));
CHECK_EQ(match[2], storage_reg);
field_reg = match[1];
CHECK(std::getline(reader, line));
CHECK(std::regex_match(line, match, m.mask_re));
CHECK_EQ(match[1], field_reg);
CHECK_EQ(match[2], field_reg);
CHECK_EQ(match[3], poison_reg);
CHECK_EQ(match[3], m.poison_reg);
poisoning_sequence_found = true;
break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment