| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #ifndef NACL_TRUSTED_BUT_NOT_TCB | 7 #ifndef NACL_TRUSTED_BUT_NOT_TCB |
| 8 #error This file is not meant for use in the TCB | 8 #error This file is not meant for use in the TCB |
| 9 #endif | 9 #endif |
| 10 | 10 |
| (...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 << undefined_insts[i].about; | 513 << undefined_insts[i].about; |
| 514 EXPECT_EQ(nacl_arm_dec::UNDEFINED, spy.GetSafetyLevel(first)) | 514 EXPECT_EQ(nacl_arm_dec::UNDEFINED, spy.GetSafetyLevel(first)) |
| 515 << "Instruction must be flagged as UNDEFINED: " | 515 << "Instruction must be flagged as UNDEFINED: " |
| 516 << undefined_insts[i].about; | 516 << undefined_insts[i].about; |
| 517 EXPECT_EQ(nacl_arm_val::kProblemUnsafe, first.problem()) | 517 EXPECT_EQ(nacl_arm_val::kProblemUnsafe, first.problem()) |
| 518 << "Instruction must be marked unsafe: " | 518 << "Instruction must be marked unsafe: " |
| 519 << undefined_insts[i].about; | 519 << undefined_insts[i].about; |
| 520 } | 520 } |
| 521 } | 521 } |
| 522 | 522 |
| 523 TEST_F(ValidatorTests, LessScaryUndefinedInstructions) { | |
| 524 // These instructions are specified by ARM as *permanently* undefined, so we | |
| 525 // treat them as a reliable Illegal Instruction trap. | |
| 526 | |
| 527 static const AnnotatedInstruction perm_undefined[] = { | |
| 528 { 0xE7FFDEFE, "permanently undefined instruction produced by LLVM" }, | |
| 529 }; | |
| 530 | |
| 531 for (unsigned i = 0; i < NACL_ARRAY_SIZE(perm_undefined); i++) { | |
| 532 arm_inst program[] = { perm_undefined[i].inst }; | |
| 533 validation_should_pass(program, | |
| 534 1, | |
| 535 kDefaultBaseAddr, | |
| 536 perm_undefined[i].about); | |
| 537 } | |
| 538 } | |
| 539 | |
| 540 TEST_F(ValidatorTests, PcRelativeFirstInst) { | 523 TEST_F(ValidatorTests, PcRelativeFirstInst) { |
| 541 // Note: This tests the fix for issue 2771. | 524 // Note: This tests the fix for issue 2771. |
| 542 static const arm_inst pcrel_boundary_tests[] = { | 525 static const arm_inst pcrel_boundary_tests[] = { |
| 543 0xe59f0000, // ldr r0, [pc, #0] | 526 0xe59f0000, // ldr r0, [pc, #0] |
| 544 0xe320f000, // nop {0} | 527 0xe320f000, // nop {0} |
| 545 0xe320f000, // nop {0} | 528 0xe320f000, // nop {0} |
| 546 0xe320f000, // nop {0}" | 529 0xe320f000, // nop {0}" |
| 547 }; | 530 }; |
| 548 validation_should_pass(pcrel_boundary_tests, | 531 validation_should_pass(pcrel_boundary_tests, |
| 549 NACL_ARRAY_SIZE(pcrel_boundary_tests), | 532 NACL_ARRAY_SIZE(pcrel_boundary_tests), |
| (...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1019 // Run test to verify that "Push {pc}", encoding A2 on a8-248 of ARM manual, | 1002 // Run test to verify that "Push {pc}", encoding A2 on a8-248 of ARM manual, |
| 1020 // is unsafe. | 1003 // is unsafe. |
| 1021 all_cond_values_fail(0xe52dF004, // push {pc} | 1004 all_cond_values_fail(0xe52dF004, // push {pc} |
| 1022 kDefaultBaseAddr, | 1005 kDefaultBaseAddr, |
| 1023 "push {pc} (A2 A8-248) should be unpredictable"); | 1006 "push {pc} (A2 A8-248) should be unpredictable"); |
| 1024 } | 1007 } |
| 1025 | 1008 |
| 1026 TEST_F(ValidatorTests, ConditionalBreakpoints) { | 1009 TEST_F(ValidatorTests, ConditionalBreakpoints) { |
| 1027 ProblemSpy spy; | 1010 ProblemSpy spy; |
| 1028 arm_inst bkpt = 0xE1200070; // BKPT #0 | 1011 arm_inst bkpt = 0xE1200070; // BKPT #0 |
| 1029 arm_inst pool_head = nacl_arm_dec::kLiteralPoolHeadInstruction; | 1012 arm_inst pool_head = nacl_arm_dec::kLiteralPoolHead; |
| 1030 for (Instruction::Condition cond = Instruction::EQ; | 1013 for (Instruction::Condition cond = Instruction::EQ; |
| 1031 cond < Instruction::AL; | 1014 cond < Instruction::AL; |
| 1032 cond = Instruction::Next(cond)) { | 1015 cond = Instruction::Next(cond)) { |
| 1033 bkpt = ChangeCond(bkpt, cond); | 1016 bkpt = ChangeCond(bkpt, cond); |
| 1034 pool_head = ChangeCond(pool_head, cond); | 1017 pool_head = ChangeCond(pool_head, cond); |
| 1035 EXPECT_FALSE(validate(&bkpt, 1, kDefaultBaseAddr, &spy)) | 1018 EXPECT_FALSE(validate(&bkpt, 1, kDefaultBaseAddr, &spy)) |
| 1036 << "conditional breakpoint should be unpredictable"; | 1019 << "conditional breakpoint should be unpredictable"; |
| 1037 EXPECT_FALSE(validate(&pool_head, 1, kDefaultBaseAddr, &spy)) | 1020 EXPECT_FALSE(validate(&pool_head, 1, kDefaultBaseAddr, &spy)) |
| 1038 << "conditional literal pool head should be unpredictable"; | 1021 << "conditional literal pool head should be unpredictable"; |
| 1039 } | 1022 } |
| 1040 } | 1023 } |
| 1041 | 1024 |
| 1042 TEST_F(ValidatorTests, LiteralPoolHeadIsBreakpoint) { | 1025 TEST_F(ValidatorTests, LiteralPoolHeadIsBreakpoint) { |
| 1043 EXPECT_EQ(nacl_arm_dec::kLiteralPoolHeadInstruction & 0xFFF000F0, | 1026 EXPECT_EQ(nacl_arm_dec::kLiteralPoolHead & 0xFFF000F0, |
| 1044 0xE1200070) // BKPT #0 | 1027 0xE1200070) // BKPT #0 |
| 1045 << ("the literal pool head should be a breakpoint: " | 1028 << ("the literal pool head should be a breakpoint: " |
| 1046 "it needs to act as a roadblock"); | 1029 "it needs to act as a roadblock"); |
| 1047 } | 1030 } |
| 1048 | 1031 |
| 1032 TEST_F(ValidatorTests, Breakpoint) { |
| 1033 EXPECT_EQ(nacl_arm_dec::kBreakpoint & 0xFFF000F0, |
| 1034 0xE1200070) // BKPT #0 |
| 1035 << ("the breakpoint instruction should be a breakpoint: " |
| 1036 "it needs to trap"); |
| 1037 } |
| 1038 |
| 1039 TEST_F(ValidatorTests, HaltFill) { |
| 1040 EXPECT_EQ(nacl_arm_dec::kHaltFill & 0xFFF000F0, |
| 1041 0xE7F000F0) // UDF #0 |
| 1042 << ("the halt fill instruction should be UDF: " |
| 1043 "it needs to trap"); |
| 1044 } |
| 1045 |
| 1046 TEST_F(ValidatorTests, AbortNow) { |
| 1047 EXPECT_EQ(nacl_arm_dec::kAbortNow & 0xFFF000F0, |
| 1048 0xE7F000F0) // UDF #0 |
| 1049 << ("the abort now instruction should be UDF: " |
| 1050 "it needs to trap"); |
| 1051 } |
| 1052 |
| 1053 TEST_F(ValidatorTests, FailValidation) { |
| 1054 EXPECT_EQ(nacl_arm_dec::kFailValidation & 0xFFF000F0, |
| 1055 0xE7F000F0) // UDF #0 |
| 1056 << ("the fail validation instruction should be UDF: " |
| 1057 "it needs to trap"); |
| 1058 } |
| 1059 |
| 1060 TEST_F(ValidatorTests, UDFAndBKPTValidateAsExpected) { |
| 1061 ProblemSpy spy; |
| 1062 for (uint32_t i = 0; i < 0xFFFF; ++i) { |
| 1063 arm_inst bkpt_inst = 0xE1200070 | ((i & 0xFFF0) << 4) | (i & 0xF); |
| 1064 arm_inst udf_inst = 0xE7F000F0 | ((i & 0xFFF0) << 4) | (i & 0xF); |
| 1065 EXPECT_EQ(validate(&bkpt_inst, 1, kDefaultBaseAddr, &spy), |
| 1066 ((bkpt_inst == nacl_arm_dec::kLiteralPoolHead) || |
| 1067 (bkpt_inst == nacl_arm_dec::kBreakpoint))); |
| 1068 EXPECT_EQ(validate(&udf_inst, 1, kDefaultBaseAddr, &spy), |
| 1069 ((udf_inst == nacl_arm_dec::kHaltFill) || |
| 1070 (udf_inst == nacl_arm_dec::kAbortNow))); |
| 1071 // Tautological note: kFailValidation should fail validation. |
| 1072 } |
| 1073 } |
| 1074 |
| 1049 TEST_F(ValidatorTests, LiteralPoolHeadInstruction) { | 1075 TEST_F(ValidatorTests, LiteralPoolHeadInstruction) { |
| 1050 // Make sure that literal pools are handled properly: they should be preceded | 1076 // Make sure that literal pools are handled properly: they should be preceded |
| 1051 // by a special breakpoint instruction at the start of the bundle, and can | 1077 // by a special breakpoint instruction at the start of the bundle, and can |
| 1052 // then contain any bits that would otherwise look malicious. | 1078 // then contain any bits that would otherwise look malicious. |
| 1053 // Each literal pool bundle has to start with such a literal pool head. | 1079 // Each literal pool bundle has to start with such a literal pool head. |
| 1054 vector<arm_inst> literal_pool(_validator.InstructionsPerBundle(), | 1080 vector<arm_inst> literal_pool(_validator.InstructionsPerBundle(), |
| 1055 0xEF000000); // SVC #0 | 1081 0xEF000000); // SVC #0 |
| 1056 literal_pool[0] = 0xE1200070; // BKPT #0 | 1082 literal_pool[0] = 0xE1200070; // BKPT #0 |
| 1057 // Try out all BKPT encodings, and make sure only one of them works. | 1083 // Try out all BKPT encodings, and make sure only one of them works. |
| 1058 for (uint32_t imm16 = 0; imm16 <= 0xFFFF; ++imm16) { | 1084 for (uint32_t imm16 = 0; imm16 <= 0xFFFF; ++imm16) { |
| 1059 literal_pool[0] = (literal_pool[0] & 0xFFF000F0) | | 1085 literal_pool[0] = (literal_pool[0] & 0xFFF000F0) | |
| 1060 (imm16 & 0xF) | | 1086 (imm16 & 0xF) | |
| 1061 ((imm16 & 0xFFF0) << 8); | 1087 ((imm16 & 0xFFF0) << 8); |
| 1062 if (literal_pool[0] == nacl_arm_dec::kLiteralPoolHeadInstruction) { | 1088 if (literal_pool[0] == nacl_arm_dec::kLiteralPoolHead) { |
| 1063 validation_should_pass(literal_pool.data(), | 1089 validation_should_pass(literal_pool.data(), |
| 1064 literal_pool.size(), | 1090 literal_pool.size(), |
| 1065 kDefaultBaseAddr, | 1091 kDefaultBaseAddr, |
| 1066 "valid literal pool: " | 1092 "valid literal pool: " |
| 1067 "starts with special BKPT"); | 1093 "starts with special BKPT"); |
| 1068 } else { | 1094 } else { |
| 1069 validation_should_fail(literal_pool.data(), | 1095 validation_should_fail(literal_pool.data(), |
| 1070 literal_pool.size(), | 1096 literal_pool.size(), |
| 1071 kDefaultBaseAddr, | 1097 kDefaultBaseAddr, |
| 1072 "invalid literal pool: " | 1098 "invalid literal pool: " |
| 1073 "starts with just a regular BKPT"); | 1099 "starts with just a regular BKPT"); |
| 1074 } | 1100 } |
| 1075 } | 1101 } |
| 1076 } | 1102 } |
| 1077 | 1103 |
| 1078 TEST_F(ValidatorTests, LiteralPoolHeadPosition) { | 1104 TEST_F(ValidatorTests, LiteralPoolHeadPosition) { |
| 1079 // Literal pools should only work when the head instruction is indeed at | 1105 // Literal pools should only work when the head instruction is indeed at |
| 1080 // the head. | 1106 // the head. |
| 1081 vector<arm_inst> literal_pool(_validator.InstructionsPerBundle()); | 1107 vector<arm_inst> literal_pool(_validator.InstructionsPerBundle()); |
| 1082 for (size_t pos = 0; pos <= literal_pool.size(); ++pos) { | 1108 for (size_t pos = 0; pos <= literal_pool.size(); ++pos) { |
| 1083 std::fill(literal_pool.begin(), literal_pool.end(), 0xEF000000); // SVC #0 | 1109 std::fill(literal_pool.begin(), literal_pool.end(), 0xEF000000); // SVC #0 |
| 1084 if (pos != literal_pool.size()) { | 1110 if (pos != literal_pool.size()) { |
| 1085 // We do one iteration without a literal pool head at all. | 1111 // We do one iteration without a literal pool head at all. |
| 1086 literal_pool[pos] = nacl_arm_dec::kLiteralPoolHeadInstruction; | 1112 literal_pool[pos] = nacl_arm_dec::kLiteralPoolHead; |
| 1087 } | 1113 } |
| 1088 if (pos == 0) { | 1114 if (pos == 0) { |
| 1089 validation_should_pass(literal_pool.data(), | 1115 validation_should_pass(literal_pool.data(), |
| 1090 literal_pool.size(), | 1116 literal_pool.size(), |
| 1091 kDefaultBaseAddr, | 1117 kDefaultBaseAddr, |
| 1092 "valid literal pool: " | 1118 "valid literal pool: " |
| 1093 "starts with special head instruction"); | 1119 "starts with special head instruction"); |
| 1094 } else { | 1120 } else { |
| 1095 validation_should_fail(literal_pool.data(), | 1121 validation_should_fail(literal_pool.data(), |
| 1096 literal_pool.size(), | 1122 literal_pool.size(), |
| 1097 kDefaultBaseAddr, | 1123 kDefaultBaseAddr, |
| 1098 "invalid literal pool: " | 1124 "invalid literal pool: " |
| 1099 "doesn't start with special head instruction"); | 1125 "doesn't start with special head instruction"); |
| 1100 } | 1126 } |
| 1101 } | 1127 } |
| 1102 } | 1128 } |
| 1103 | 1129 |
| 1104 TEST_F(ValidatorTests, LiteralPoolBig) { | 1130 TEST_F(ValidatorTests, LiteralPoolBig) { |
| 1105 // Literal pools should be a single bundle wide, each must be preceded by | 1131 // Literal pools should be a single bundle wide, each must be preceded by |
| 1106 // a pool head. | 1132 // a pool head. |
| 1107 vector<arm_inst> literal_pools(2 * _validator.InstructionsPerBundle()); | 1133 vector<arm_inst> literal_pools(2 * _validator.InstructionsPerBundle()); |
| 1108 for (size_t pos = 0; pos <= literal_pools.size(); ++pos) { | 1134 for (size_t pos = 0; pos <= literal_pools.size(); ++pos) { |
| 1109 std::fill(literal_pools.begin(), literal_pools.end(), | 1135 std::fill(literal_pools.begin(), literal_pools.end(), |
| 1110 0xEF000000); // SVC #0 | 1136 0xEF000000); // SVC #0 |
| 1111 literal_pools[pos] = nacl_arm_dec::kLiteralPoolHeadInstruction; | 1137 literal_pools[pos] = nacl_arm_dec::kLiteralPoolHead; |
| 1112 validation_should_fail(literal_pools.data(), | 1138 validation_should_fail(literal_pools.data(), |
| 1113 literal_pools.size(), | 1139 literal_pools.size(), |
| 1114 kDefaultBaseAddr, | 1140 kDefaultBaseAddr, |
| 1115 "invalid literal pool: two pools, one head"); | 1141 "invalid literal pool: two pools, one head"); |
| 1116 } | 1142 } |
| 1117 } | 1143 } |
| 1118 | 1144 |
| 1119 TEST_F(ValidatorTests, LiteralPoolBranch) { | 1145 TEST_F(ValidatorTests, LiteralPoolBranch) { |
| 1120 // Branching to a literal pool should only work at the head. | 1146 // Branching to a literal pool should only work at the head. |
| 1121 // Construct a code region with a bundle of code, then a bundle-wide | 1147 // Construct a code region with a bundle of code, then a bundle-wide |
| 1122 // literal pool, then another bundle of code. | 1148 // literal pool, then another bundle of code. |
| 1123 // Add a branch from different code locations, pointing at different | 1149 // Add a branch from different code locations, pointing at different |
| 1124 // parts of the code. Pointing in the literal pool should fail, except | 1150 // parts of the code. Pointing in the literal pool should fail, except |
| 1125 // when pointing at the head. | 1151 // when pointing at the head. |
| 1126 // Note that we don't actually put anything malicious in the literal pool, | 1152 // Note that we don't actually put anything malicious in the literal pool, |
| 1127 // and we still shouldn't be able to jump in the middle of it. | 1153 // and we still shouldn't be able to jump in the middle of it. |
| 1128 const size_t bundle_pos = _validator.InstructionsPerBundle(); | 1154 const size_t bundle_pos = _validator.InstructionsPerBundle(); |
| 1129 vector<arm_inst> code(3 * bundle_pos); | 1155 vector<arm_inst> code(3 * bundle_pos); |
| 1130 for (size_t b_pos = 0; b_pos < code.size(); ++b_pos) { | 1156 for (size_t b_pos = 0; b_pos < code.size(); ++b_pos) { |
| 1131 if ((bundle_pos <= b_pos) && (b_pos < bundle_pos * 2)) { | 1157 if ((bundle_pos <= b_pos) && (b_pos < bundle_pos * 2)) { |
| 1132 // Don't try putting the branch in the middle of the literal pool. | 1158 // Don't try putting the branch in the middle of the literal pool. |
| 1133 continue; | 1159 continue; |
| 1134 } | 1160 } |
| 1135 std::fill(code.begin(), code.end(), 0xE320F000); // NOP | 1161 std::fill(code.begin(), code.end(), 0xE320F000); // NOP |
| 1136 code[bundle_pos] = nacl_arm_dec::kLiteralPoolHeadInstruction; | 1162 code[bundle_pos] = nacl_arm_dec::kLiteralPoolHead; |
| 1137 for (size_t b_target = 0; b_target < code.size(); ++b_target) { | 1163 for (size_t b_target = 0; b_target < code.size(); ++b_target) { |
| 1138 // PC reads as current instruction address plus 8 (e.g. two instructions | 1164 // PC reads as current instruction address plus 8 (e.g. two instructions |
| 1139 // ahead of b_pos). | 1165 // ahead of b_pos). |
| 1140 // imm24 is encoded with the bottom two bits zeroed out, which we | 1166 // imm24 is encoded with the bottom two bits zeroed out, which we |
| 1141 // implicitly do by working with instructions instead of bytes. | 1167 // implicitly do by working with instructions instead of bytes. |
| 1142 uint32_t imm24 = (b_target - b_pos - 2) & 0x00FFFFFF; | 1168 uint32_t imm24 = (b_target - b_pos - 2) & 0x00FFFFFF; |
| 1143 code[b_pos] = 0xEA000000 | imm24; // B #imm | 1169 code[b_pos] = 0xEA000000 | imm24; // B #imm |
| 1144 bool target_in_pool = (bundle_pos < b_target) && | 1170 bool target_in_pool = (bundle_pos < b_target) && |
| 1145 (b_target < bundle_pos * 2); // Excluding head. | 1171 (b_target < bundle_pos * 2); // Excluding head. |
| 1146 if (target_in_pool) { | 1172 if (target_in_pool) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1158 } | 1184 } |
| 1159 } | 1185 } |
| 1160 | 1186 |
| 1161 }; // anonymous namespace | 1187 }; // anonymous namespace |
| 1162 | 1188 |
| 1163 // Test driver function. | 1189 // Test driver function. |
| 1164 int main(int argc, char *argv[]) { | 1190 int main(int argc, char *argv[]) { |
| 1165 testing::InitGoogleTest(&argc, argv); | 1191 testing::InitGoogleTest(&argc, argv); |
| 1166 return RUN_ALL_TESTS(); | 1192 return RUN_ALL_TESTS(); |
| 1167 } | 1193 } |
| OLD | NEW |