Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1409)

Side by Side Diff: src/trusted/validator_arm/validator_small_tests.cc

Issue 11194045: Change BKPT and UDF encodings on ARM. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: Update copyright. Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/trusted/validator_arm/validator_huge_tests.cc ('k') | tests/debug_stub/debugger_test.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « src/trusted/validator_arm/validator_huge_tests.cc ('k') | tests/debug_stub/debugger_test.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698