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 |