| 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 #include <assert.h> | 7 #include <assert.h> |
| 8 #include "native_client/src/trusted/service_runtime/nacl_config.h" | 8 #include "native_client/src/trusted/service_runtime/nacl_config.h" |
| 9 #include "native_client/src/trusted/validator_mips/validator.h" | 9 #include "native_client/src/trusted/validator_mips/validator.h" |
| 10 #include "native_client/src/include/nacl_macros.h" | 10 #include "native_client/src/include/nacl_macros.h" |
| 11 | 11 |
| 12 | 12 |
| 13 using nacl_mips_dec::Instruction; | 13 using nacl_mips_dec::Instruction; |
| 14 using nacl_mips_dec::ClassDecoder; | 14 using nacl_mips_dec::ClassDecoder; |
| 15 using nacl_mips_dec::Register; | 15 using nacl_mips_dec::Register; |
| 16 using nacl_mips_dec::RegisterList; | 16 using nacl_mips_dec::RegisterList; |
| 17 | 17 |
| 18 using nacl_mips_dec::kRegisterJumpMask; | |
| 19 using nacl_mips_dec::kRegisterLoadStoreMask; | |
| 20 | |
| 21 using nacl_mips_dec::kInstrSize; | 18 using nacl_mips_dec::kInstrSize; |
| 22 using nacl_mips_dec::kInstrAlign; | 19 using nacl_mips_dec::kInstrAlign; |
| 23 | 20 |
| 24 using std::vector; | 21 using std::vector; |
| 25 | 22 |
| 26 namespace nacl_mips_val { | 23 namespace nacl_mips_val { |
| 27 | 24 |
| 28 /* | 25 /* |
| 29 * TODO(petarj): MIPS validator and runtime port need an external security | 26 * TODO(petarj): MIPS validator and runtime port need an external security |
| 30 * review before they are delivered in products. | 27 * review before they are delivered in products. |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 | 136 |
| 140 /* | 137 /* |
| 141 * Checks if indirect jumps are guarded properly. | 138 * Checks if indirect jumps are guarded properly. |
| 142 */ | 139 */ |
| 143 static PatternMatch CheckJmpReg(const SfiValidator &sfi, | 140 static PatternMatch CheckJmpReg(const SfiValidator &sfi, |
| 144 const DecodedInstruction &first, | 141 const DecodedInstruction &first, |
| 145 const DecodedInstruction &second, | 142 const DecodedInstruction &second, |
| 146 ProblemSink *out) { | 143 ProblemSink *out) { |
| 147 UNREFERENCED_PARAMETER(sfi); | 144 UNREFERENCED_PARAMETER(sfi); |
| 148 if (second.IsJmpReg()) { | 145 if (second.IsJmpReg()) { |
| 149 if (first.IsMask(second.TargetReg(), kRegisterJumpMask)) { | 146 if (first.IsMask(second.TargetReg(), Register::JumpMask())) { |
| 150 return PATTERN_SAFE; | 147 return PATTERN_SAFE; |
| 151 } | 148 } |
| 152 out->ReportProblem(second.addr(), second.safety(), | 149 out->ReportProblem(second.addr(), second.safety(), |
| 153 kProblemUnsafeJumpRegister); | 150 kProblemUnsafeJumpRegister); |
| 154 return PATTERN_UNSAFE; | 151 return PATTERN_UNSAFE; |
| 155 } | 152 } |
| 156 return NO_MATCH; | 153 return NO_MATCH; |
| 157 } | 154 } |
| 158 | 155 |
| 159 | 156 |
| 160 /* | 157 /* |
| 161 * Checks if change of the data register ($sp) is followed by load/store mask. | 158 * Checks if change of the data register ($sp) is followed by load/store mask. |
| 162 */ | 159 */ |
| 163 static PatternMatch CheckDataRegisterUpdate(const SfiValidator &sfi, | 160 static PatternMatch CheckDataRegisterUpdate(const SfiValidator &sfi, |
| 164 const DecodedInstruction &first, | 161 const DecodedInstruction &first, |
| 165 const DecodedInstruction &second, | 162 const DecodedInstruction &second, |
| 166 ProblemSink *out) { | 163 ProblemSink *out) { |
| 167 if (first.IsDestGprReg(sfi.data_address_registers()) | 164 if (first.IsDestGprReg(sfi.data_address_registers()) |
| 168 && !first.IsMask(first.DestGprReg(), kRegisterLoadStoreMask)) { | 165 && !first.IsMask(first.DestGprReg(), Register::LoadStoreMask())) { |
| 169 if (second.IsMask(first.DestGprReg(), kRegisterLoadStoreMask)) { | 166 if (second.IsMask(first.DestGprReg(), Register::LoadStoreMask())) { |
| 170 return PATTERN_SAFE; | 167 return PATTERN_SAFE; |
| 171 } | 168 } |
| 172 out->ReportProblem(first.addr(), first.safety(), kProblemUnsafeDataWrite); | 169 out->ReportProblem(first.addr(), first.safety(), kProblemUnsafeDataWrite); |
| 173 return PATTERN_UNSAFE; | 170 return PATTERN_UNSAFE; |
| 174 } | 171 } |
| 175 return NO_MATCH; | 172 return NO_MATCH; |
| 176 } | 173 } |
| 177 | 174 |
| 178 /* | 175 /* |
| 179 * Checks if data register ($sp) change is in the delay slot. | 176 * Checks if data register ($sp) change is in the delay slot. |
| 180 */ | 177 */ |
| 181 static PatternMatch CheckDataRegisterDslot(const SfiValidator &sfi, | 178 static PatternMatch CheckDataRegisterDslot(const SfiValidator &sfi, |
| 182 const DecodedInstruction &first, | 179 const DecodedInstruction &first, |
| 183 const DecodedInstruction &second, | 180 const DecodedInstruction &second, |
| 184 ProblemSink *out) { | 181 ProblemSink *out) { |
| 185 if (second.IsDestGprReg(sfi.data_address_registers()) | 182 if (second.IsDestGprReg(sfi.data_address_registers()) |
| 186 && !second.IsMask(second.DestGprReg(), kRegisterLoadStoreMask)) { | 183 && !second.IsMask(second.DestGprReg(), Register::LoadStoreMask())) { |
| 187 if (first.HasDelaySlot()) { | 184 if (first.HasDelaySlot()) { |
| 188 out->ReportProblem(second.addr(), second.safety(), | 185 out->ReportProblem(second.addr(), second.safety(), |
| 189 kProblemDataRegInDelaySlot); | 186 kProblemDataRegInDelaySlot); |
| 190 return PATTERN_UNSAFE; | 187 return PATTERN_UNSAFE; |
| 191 } | 188 } |
| 192 } | 189 } |
| 193 return NO_MATCH; | 190 return NO_MATCH; |
| 194 } | 191 } |
| 195 | 192 |
| 196 /* | 193 /* |
| 197 * Checks if load and store instructions are preceded by load/store mask. | 194 * Checks if load and store instructions are preceded by load/store mask. |
| 198 */ | 195 */ |
| 199 static PatternMatch CheckLoadStore(const SfiValidator &sfi, | 196 static PatternMatch CheckLoadStore(const SfiValidator &sfi, |
| 200 const DecodedInstruction &first, | 197 const DecodedInstruction &first, |
| 201 const DecodedInstruction &second, | 198 const DecodedInstruction &second, |
| 202 ProblemSink *out) { | 199 ProblemSink *out) { |
| 203 if (second.IsLoadStore()) { | 200 if (second.IsLoadStore()) { |
| 204 Register base_addr_reg = second.BaseAddressRegister(); | 201 Register base_addr_reg = second.BaseAddressRegister(); |
| 205 if (!sfi.data_address_registers(). | 202 if (!sfi.data_address_registers(). |
| 206 ContainsAll(RegisterList(base_addr_reg))) { | 203 ContainsAll(RegisterList(base_addr_reg))) { |
| 207 if (first.IsMask(base_addr_reg, kRegisterLoadStoreMask)) { | 204 if (first.IsMask(base_addr_reg, Register::LoadStoreMask())) { |
| 208 return PATTERN_SAFE; | 205 return PATTERN_SAFE; |
| 209 } | 206 } |
| 210 out->ReportProblem(second.addr(), second.safety(), | 207 out->ReportProblem(second.addr(), second.safety(), |
| 211 kProblemUnsafeLoadStore); | 208 kProblemUnsafeLoadStore); |
| 212 return PATTERN_UNSAFE; | 209 return PATTERN_UNSAFE; |
| 213 } | 210 } |
| 214 } | 211 } |
| 215 return NO_MATCH; | 212 return NO_MATCH; |
| 216 } | 213 } |
| 217 | 214 |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 DecodedInstruction::DecodedInstruction(uint32_t vaddr, | 506 DecodedInstruction::DecodedInstruction(uint32_t vaddr, |
| 510 Instruction inst, | 507 Instruction inst, |
| 511 const ClassDecoder &decoder) | 508 const ClassDecoder &decoder) |
| 512 : vaddr_(vaddr), | 509 : vaddr_(vaddr), |
| 513 inst_(inst), | 510 inst_(inst), |
| 514 decoder_(&decoder), | 511 decoder_(&decoder), |
| 515 safety_(decoder.safety(inst_)) | 512 safety_(decoder.safety(inst_)) |
| 516 {} | 513 {} |
| 517 | 514 |
| 518 } // namespace | 515 } // namespace |
| OLD | NEW |