| 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 | 
|---|