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 |