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

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

Issue 8275008: Make validator require read sandboxing on ARM. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client/
Patch Set: '' Created 9 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
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. 2 * Copyright (c) 2011 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 "native_client/src/trusted/validator_arm/inst_classes.h" 7 #include "native_client/src/trusted/validator_arm/inst_classes.h"
8 8
9 /* 9 /*
10 * Implementations of instruction classes, for those not completely defined in 10 * Implementations of instruction classes, for those not completely defined in
11 * the header. 11 * the header.
12 */ 12 */
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS; 208 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS;
209 209
210 return MAY_BE_SAFE; 210 return MAY_BE_SAFE;
211 } 211 }
212 212
213 RegisterList AbstractLoad::defs(const Instruction i) const { 213 RegisterList AbstractLoad::defs(const Instruction i) const {
214 return i.reg(15, 12) + immediate_addressing_defs(i); 214 return i.reg(15, 12) + immediate_addressing_defs(i);
215 } 215 }
216 216
217 217
218 SafetyLevel LoadRegister::safety(const Instruction i) const {
219 bool pre_index = i.bit(24);
220 if (pre_index) {
221 // If pre_index is set, the address of the load is computed as the sum
222 // of the two register parameters. We have checked that the first register
223 // is within the sandbox, but this would allow adding an arbitrary value
224 // to it, so it is not safe.
225 return FORBIDDEN;
226 }
227
228 // Don't let addressing writeback alter PC.
229 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS;
230
231 return MAY_BE_SAFE;
232 }
233
218 RegisterList LoadRegister::defs(const Instruction i) const { 234 RegisterList LoadRegister::defs(const Instruction i) const {
219 if (writeback(i)) { 235 if (writeback(i)) {
220 Register rn(i.bits(19, 16)); 236 Register rn(i.bits(19, 16));
221 return AbstractLoad::defs(i) + rn; 237 return AbstractLoad::defs(i) + rn;
222 } else { 238 } else {
223 return AbstractLoad::defs(i); 239 return AbstractLoad::defs(i);
224 } 240 }
225 } 241 }
226 242
243 Register LoadRegister::base_address_register(const Instruction i) const {
244 return i.reg(19, 16);
245 }
246
227 247
228 RegisterList LoadImmediate::immediate_addressing_defs(const Instruction i) 248 RegisterList LoadImmediate::immediate_addressing_defs(const Instruction i)
229 const { 249 const {
230 if (writeback(i)) { 250 if (writeback(i)) {
231 Register rn(i.bits(19, 16)); 251 Register rn(i.bits(19, 16));
232 return rn; 252 return rn;
233 } else { 253 } else {
234 return kRegisterNone; 254 return kRegisterNone;
235 } 255 }
236 } 256 }
237 257
258 Register LoadImmediate::base_address_register(const Instruction i) const {
259 return i.reg(19, 16);
260 }
261
262 bool LoadImmediate::offset_is_immediate(Instruction i) const {
263 UNREFERENCED_PARAMETER(i);
264 return true;
265 }
266
238 267
239 RegisterList LoadDoubleI::defs(const Instruction i) const { 268 RegisterList LoadDoubleI::defs(const Instruction i) const {
240 return LoadImmediate::defs(i) + Register(i.bits(15, 12) + 1); 269 return LoadImmediate::defs(i) + Register(i.bits(15, 12) + 1);
241 } 270 }
242 271
272 Register LoadDoubleI::base_address_register(const Instruction i) const {
273 return i.reg(19, 16);
274 }
275
276 bool LoadDoubleI::offset_is_immediate(Instruction i) const {
277 UNREFERENCED_PARAMETER(i);
278 return true;
279 }
280
281
282 SafetyLevel LoadDoubleR::safety(const Instruction i) const {
283 bool pre_index = i.bit(24);
284 if (pre_index) {
285 // If pre_index is set, the address of the load is computed as the sum
286 // of the two register parameters. We have checked that the first register
287 // is within the sandbox, but this would allow adding an arbitrary value
288 // to it, so it is not safe.
289 return FORBIDDEN;
290 }
291
292 // Don't let addressing writeback alter PC.
293 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS;
294
295 return MAY_BE_SAFE;
296 }
243 297
244 RegisterList LoadDoubleR::defs(const Instruction i) const { 298 RegisterList LoadDoubleR::defs(const Instruction i) const {
245 return LoadRegister::defs(i) + Register(i.bits(15, 12) + 1); 299 return LoadRegister::defs(i) + Register(i.bits(15, 12) + 1);
246 } 300 }
247 301
302 Register LoadDoubleR::base_address_register(const Instruction i) const {
303 return i.reg(19, 16);
304 }
305
306 Register LoadExclusive::base_address_register(const Instruction i) const {
307 return i.reg(19, 16);
308 }
309
248 RegisterList LoadDoubleExclusive::defs(const Instruction i) const { 310 RegisterList LoadDoubleExclusive::defs(const Instruction i) const {
249 return LoadExclusive::defs(i) + Register(i.bits(15, 12) + 1); 311 return LoadExclusive::defs(i) + Register(i.bits(15, 12) + 1);
250 } 312 }
251 313
314 Register LoadDoubleExclusive::base_address_register(const Instruction i) const {
315 return i.reg(19, 16);
316 }
317
252 318
253 SafetyLevel LoadMultiple::safety(const Instruction i) const { 319 SafetyLevel LoadMultiple::safety(const Instruction i) const {
254 uint32_t rn = i.bits(19, 16); 320 uint32_t rn = i.bits(19, 16);
255 if (i.bit(21) && i.bit(rn)) { 321 if (i.bit(21) && i.bit(rn)) {
256 // In ARMv7, cannot update base register both by popping and by indexing. 322 // In ARMv7, cannot update base register both by popping and by indexing.
257 // (Pre-v7 this was still a weird thing to do.) 323 // (Pre-v7 this was still a weird thing to do.)
258 return UNPREDICTABLE; 324 return UNPREDICTABLE;
259 } 325 }
260 326
261 if (defs(i)[kRegisterPc]) { 327 if (defs(i)[kRegisterPc]) {
262 return FORBIDDEN_OPERANDS; 328 return FORBIDDEN_OPERANDS;
263 } 329 }
264 return MAY_BE_SAFE; 330 return MAY_BE_SAFE;
265 } 331 }
266 332
267 RegisterList LoadMultiple::defs(const Instruction i) const { 333 RegisterList LoadMultiple::defs(const Instruction i) const {
268 return RegisterList(i.bits(15, 0)) + immediate_addressing_defs(i); 334 return RegisterList(i.bits(15, 0)) + immediate_addressing_defs(i);
269 } 335 }
270 336
271 RegisterList LoadMultiple::immediate_addressing_defs( 337 RegisterList LoadMultiple::immediate_addressing_defs(
272 const Instruction i) const { 338 const Instruction i) const {
273 return i.bit(21)? i.reg(19, 16) : kRegisterNone; 339 return i.bit(21)? i.reg(19, 16) : kRegisterNone;
274 } 340 }
275 341
342 Register LoadMultiple::base_address_register(const Instruction i) const {
343 return i.reg(19, 16);
344 }
345
276 346
277 /* 347 /*
278 * Vector load/stores 348 * Vector load/stores
279 */ 349 */
280 350
281 SafetyLevel VectorLoad::safety(Instruction i) const { 351 SafetyLevel VectorLoad::safety(Instruction i) const {
282 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS; 352 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS;
283 353
284 return MAY_BE_SAFE; 354 return MAY_BE_SAFE;
285 } 355 }
(...skipping 11 matching lines...) Expand all
297 // Rm == SP indicates automatic update based on size of load. 367 // Rm == SP indicates automatic update based on size of load.
298 if (i.reg(3, 0) == kRegisterStack) { 368 if (i.reg(3, 0) == kRegisterStack) {
299 // Rn is updated by a small static displacement. 369 // Rn is updated by a small static displacement.
300 return i.reg(19, 16); 370 return i.reg(19, 16);
301 } 371 }
302 372
303 // Any writeback is not treated as immediate otherwise. 373 // Any writeback is not treated as immediate otherwise.
304 return kRegisterNone; 374 return kRegisterNone;
305 } 375 }
306 376
377 Register VectorLoad::base_address_register(const Instruction i) const {
378 return i.reg(19, 16);
379 }
380
307 381
308 SafetyLevel VectorStore::safety(Instruction i) const { 382 SafetyLevel VectorStore::safety(Instruction i) const {
309 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS; 383 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS;
310 384
311 return MAY_BE_SAFE; 385 return MAY_BE_SAFE;
312 } 386 }
313 387
314 RegisterList VectorStore::defs(Instruction i) const { 388 RegisterList VectorStore::defs(Instruction i) const {
315 // Rm == PC indicates no address writeback. Otherwise Rn is affected. 389 // Rm == PC indicates no address writeback. Otherwise Rn is affected.
316 if (i.reg(3, 0) != kRegisterPc) { 390 if (i.reg(3, 0) != kRegisterPc) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 return kRegisterPc + (i.bit(24)? kRegisterLink : kRegisterNone); 487 return kRegisterPc + (i.bit(24)? kRegisterLink : kRegisterNone);
414 } 488 }
415 489
416 int32_t Branch::branch_target_offset(const Instruction i) const { 490 int32_t Branch::branch_target_offset(const Instruction i) const {
417 // Sign extend and shift left 2: 491 // Sign extend and shift left 2:
418 int32_t offset = (int32_t)(i.bits(23, 0) << 8) >> 6; 492 int32_t offset = (int32_t)(i.bits(23, 0) << 8) >> 6;
419 return offset + 8; // because r15 reads as 8 bytes ahead 493 return offset + 8; // because r15 reads as 8 bytes ahead
420 } 494 }
421 495
422 } // namespace 496 } // namespace
OLDNEW
« no previous file with comments | « src/trusted/validator_arm/inst_classes.h ('k') | src/trusted/validator_arm/testdata/compile_tests.sh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698