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 /* | 7 /* |
8 * This file contains common parts of x86-32 and x86-64 internals (inline | 8 * This file contains common parts of x86-32 and x86-64 internals (inline |
9 * functions and defines). | 9 * functions and defines). |
10 */ | 10 */ |
11 | 11 |
12 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_VALIDATOR_INTERNAL_H_ | 12 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_VALIDATOR_INTERNAL_H_ |
13 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_VALIDATOR_INTERNAL_H_ | 13 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_VALIDATOR_INTERNAL_H_ |
14 | 14 |
15 #include "native_client/src/shared/platform/nacl_check.h" | 15 #include "native_client/src/shared/platform/nacl_check.h" |
16 #include "native_client/src/shared/utils/types.h" | 16 #include "native_client/src/shared/utils/types.h" |
17 #include "native_client/src/trusted/validator_ragel/unreviewed/decoding.h" | 17 #include "native_client/src/trusted/validator_ragel/decoding.h" |
18 #include "native_client/src/trusted/validator_ragel/unreviewed/validator.h" | 18 #include "native_client/src/trusted/validator_ragel/unreviewed/validator.h" |
19 | 19 |
20 /* Maximum set of R-DFA allowable CPUID features. */ | 20 /* Maximum set of R-DFA allowable CPUID features. */ |
21 extern const NaClCPUFeaturesX86 kValidatorCPUIDFeatures; | 21 extern const NaClCPUFeaturesX86 kValidatorCPUIDFeatures; |
22 | 22 |
23 /* Macroses to suppport CPUID handling. */ | 23 /* Macroses to suppport CPUID handling. */ |
24 #define SET_CPU_FEATURE(F) \ | 24 #define SET_CPU_FEATURE(F) \ |
25 if (!(F##_Allowed)) { \ | 25 if (!(F##_Allowed)) { \ |
26 instruction_info_collected |= UNRECOGNIZED_INSTRUCTION; \ | 26 instruction_info_collected |= UNRECOGNIZED_INSTRUCTION; \ |
27 } \ | 27 } \ |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
183 /* Remember some information about instruction for further processing. */ | 183 /* Remember some information about instruction for further processing. */ |
184 #define GET_REX_PREFIX() rex_prefix | 184 #define GET_REX_PREFIX() rex_prefix |
185 #define SET_REX_PREFIX(P) rex_prefix = (P) | 185 #define SET_REX_PREFIX(P) rex_prefix = (P) |
186 #define GET_VEX_PREFIX2() vex_prefix2 | 186 #define GET_VEX_PREFIX2() vex_prefix2 |
187 #define SET_VEX_PREFIX2(P) vex_prefix2 = (P) | 187 #define SET_VEX_PREFIX2(P) vex_prefix2 = (P) |
188 #define GET_VEX_PREFIX3() vex_prefix3 | 188 #define GET_VEX_PREFIX3() vex_prefix3 |
189 #define SET_VEX_PREFIX3(P) vex_prefix3 = (P) | 189 #define SET_VEX_PREFIX3(P) vex_prefix3 = (P) |
190 #define SET_MODRM_BASE(N) base = (N) | 190 #define SET_MODRM_BASE(N) base = (N) |
191 #define SET_MODRM_INDEX(N) index = (N) | 191 #define SET_MODRM_INDEX(N) index = (N) |
192 | 192 |
193 enum { | |
194 REX_B = 1, | |
195 REX_X = 2, | |
196 REX_R = 4, | |
197 REX_W = 8 | |
198 }; | |
199 | |
200 enum operand_kind { | 193 enum operand_kind { |
201 OperandSandboxIrrelevant = 0, | 194 OperandSandboxIrrelevant = 0, |
202 /* | 195 /* |
203 * Currently we do not distinguish 8bit and 16bit modifications from | 196 * Currently we do not distinguish 8bit and 16bit modifications from |
204 * OperandSandboxUnrestricted to match the behavior of the old validator. | 197 * OperandSandboxUnrestricted to match the behavior of the old validator. |
205 * | 198 * |
206 * 8bit operands must be distinguished from other types because the REX prefix | 199 * 8bit operands must be distinguished from other types because the REX prefix |
207 * regulates the choice between %ah and %spl, as well as %ch and %bpl. | 200 * regulates the choice between %ah and %spl, as well as %ch and %bpl. |
208 */ | 201 */ |
209 OperandSandbox8bit, | 202 OperandSandbox8bit, |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
315 if ((jump_dest & kBundleMask) == 0) { | 308 if ((jump_dest & kBundleMask) == 0) { |
316 return TRUE; | 309 return TRUE; |
317 } | 310 } |
318 if (jump_dest >= size) { | 311 if (jump_dest >= size) { |
319 return FALSE; | 312 return FALSE; |
320 } | 313 } |
321 BitmapSetBit(jump_dests, jump_dest); | 314 BitmapSetBit(jump_dests, jump_dest); |
322 return TRUE; | 315 return TRUE; |
323 } | 316 } |
324 | 317 |
318 /* | |
319 * Mark the given address as valid jump target address. | |
320 */ | |
321 static FORCEINLINE void MakeJumpTargetValid(size_t address, | |
322 bitmap_word *valid_targets) { | |
323 BitmapSetBit(valid_targets, address); | |
324 } | |
325 | |
326 /* | |
327 * Mark the given address as invalid jump target address. | |
328 */ | |
329 static FORCEINLINE void MakeInvalidJumpTarget(size_t address, | |
330 bitmap_word *valid_targets) { | |
331 BitmapClearBit(valid_targets, address); | |
332 } | |
333 | |
325 | 334 |
326 static INLINE Bool ProcessInvalidJumpTargets( | 335 static INLINE Bool ProcessInvalidJumpTargets( |
327 const uint8_t *data, | 336 const uint8_t *data, |
328 size_t size, | 337 size_t size, |
329 bitmap_word *valid_targets, | 338 bitmap_word *valid_targets, |
330 bitmap_word *jump_dests, | 339 bitmap_word *jump_dests, |
331 ValidationCallbackFunc user_callback, | 340 ValidationCallbackFunc user_callback, |
332 void *callback_data) { | 341 void *callback_data) { |
333 size_t elements = (size + NACL_HOST_WORDSIZE - 1) / NACL_HOST_WORDSIZE; | 342 size_t elements = (size + NACL_HOST_WORDSIZE - 1) / NACL_HOST_WORDSIZE; |
334 size_t i, j; | 343 size_t i, j; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
406 BitmapClearBit(valid_targets, instruction_start), | 415 BitmapClearBit(valid_targets, instruction_start), |
407 *instruction_info_collected |= RESTRICTED_REGISTER_USED; | 416 *instruction_info_collected |= RESTRICTED_REGISTER_USED; |
408 else | 417 else |
409 *instruction_info_collected |= UNRESTRICTED_INDEX_REGISTER; | 418 *instruction_info_collected |= UNRESTRICTED_INDEX_REGISTER; |
410 } else { | 419 } else { |
411 *instruction_info_collected |= FORBIDDEN_BASE_REGISTER; | 420 *instruction_info_collected |= FORBIDDEN_BASE_REGISTER; |
412 } | 421 } |
413 } | 422 } |
414 | 423 |
415 | 424 |
416 static INLINE void process_0_operands(enum OperandName *restricted_register, | 425 static INLINE void Process0Operands(enum OperandName *restricted_register, |
417 uint32_t *instruction_info_collected) { | 426 uint32_t *instruction_info_collected) { |
418 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special | 427 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special |
419 * instruction, not with regular instruction. */ | 428 * instruction, not with regular instruction. */ |
420 if (*restricted_register == REG_RSP) { | 429 if (*restricted_register == REG_RSP) { |
421 *instruction_info_collected |= RESTRICTED_RSP_UNPROCESSED; | 430 *instruction_info_collected |= RESTRICTED_RSP_UNPROCESSED; |
422 } else if (*restricted_register == REG_RBP) { | 431 } else if (*restricted_register == REG_RBP) { |
423 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED; | 432 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED; |
424 } | 433 } |
425 *restricted_register = NO_REG; | 434 *restricted_register = NO_REG; |
426 } | 435 } |
427 | 436 |
428 static INLINE void process_1_operand(enum OperandName *restricted_register, | 437 static INLINE void Process1Operand(enum OperandName *restricted_register, |
429 uint32_t *instruction_info_collected, | 438 uint32_t *instruction_info_collected, |
430 uint8_t rex_prefix, | 439 uint8_t rex_prefix, |
431 uint32_t operand_states) { | 440 uint32_t operand_states) { |
432 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special | 441 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special |
433 * instruction, not with regular instruction. */ | 442 * instruction, not with regular instruction. */ |
434 if (*restricted_register == REG_RSP) { | 443 if (*restricted_register == REG_RSP) { |
435 *instruction_info_collected |= RESTRICTED_RSP_UNPROCESSED; | 444 *instruction_info_collected |= RESTRICTED_RSP_UNPROCESSED; |
436 } else if (*restricted_register == REG_RBP) { | 445 } else if (*restricted_register == REG_RBP) { |
437 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED; | 446 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED; |
438 } | 447 } |
439 *restricted_register = NO_REG; | 448 *restricted_register = NO_REG; |
440 if (CHECK_OPERAND(0, REG_R15, OperandSandbox8bit) || | 449 if (CHECK_OPERAND(0, REG_R15, OperandSandbox8bit) || |
441 CHECK_OPERAND(0, REG_R15, OperandSandboxRestricted) || | 450 CHECK_OPERAND(0, REG_R15, OperandSandboxRestricted) || |
442 CHECK_OPERAND(0, REG_R15, OperandSandboxUnrestricted)) { | 451 CHECK_OPERAND(0, REG_R15, OperandSandboxUnrestricted)) { |
443 *instruction_info_collected |= R15_MODIFIED; | 452 *instruction_info_collected |= R15_MODIFIED; |
444 } else if ((CHECK_OPERAND(0, REG_RBP, OperandSandbox8bit) && rex_prefix) || | 453 } else if ((CHECK_OPERAND(0, REG_RBP, OperandSandbox8bit) && rex_prefix) || |
445 CHECK_OPERAND(0, REG_RBP, OperandSandboxRestricted) || | 454 CHECK_OPERAND(0, REG_RBP, OperandSandboxRestricted) || |
446 CHECK_OPERAND(0, REG_RBP, OperandSandboxUnrestricted)) { | 455 CHECK_OPERAND(0, REG_RBP, OperandSandboxUnrestricted)) { |
447 *instruction_info_collected |= BPL_MODIFIED; | 456 *instruction_info_collected |= BPL_MODIFIED; |
448 } else if ((CHECK_OPERAND(0, REG_RSP, OperandSandbox8bit) && rex_prefix) || | 457 } else if ((CHECK_OPERAND(0, REG_RSP, OperandSandbox8bit) && rex_prefix) || |
449 CHECK_OPERAND(0, REG_RSP, OperandSandboxRestricted) || | 458 CHECK_OPERAND(0, REG_RSP, OperandSandboxRestricted) || |
450 CHECK_OPERAND(0, REG_RSP, OperandSandboxUnrestricted)) { | 459 CHECK_OPERAND(0, REG_RSP, OperandSandboxUnrestricted)) { |
451 *instruction_info_collected |= SPL_MODIFIED; | 460 *instruction_info_collected |= SPL_MODIFIED; |
452 } | 461 } |
453 } | 462 } |
454 | 463 |
455 static INLINE void process_1_operand_zero_extends( | 464 static INLINE void Process1OperandZeroExtends( |
456 enum OperandName *restricted_register, | 465 enum OperandName *restricted_register, |
457 uint32_t *instruction_info_collected, uint8_t rex_prefix, | 466 uint32_t *instruction_info_collected, uint8_t rex_prefix, |
458 uint32_t operand_states) { | 467 uint32_t operand_states) { |
459 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special | 468 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special |
460 * instruction, not with regular instruction. */ | 469 * instruction, not with regular instruction. */ |
461 if (*restricted_register == REG_RSP) { | 470 if (*restricted_register == REG_RSP) { |
462 *instruction_info_collected |= RESTRICTED_RSP_UNPROCESSED; | 471 *instruction_info_collected |= RESTRICTED_RSP_UNPROCESSED; |
463 } else if (*restricted_register == REG_RBP) { | 472 } else if (*restricted_register == REG_RBP) { |
464 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED; | 473 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED; |
465 } | 474 } |
466 *restricted_register = NO_REG; | 475 *restricted_register = NO_REG; |
467 if (CHECK_OPERAND(0, REG_R15, OperandSandbox8bit) || | 476 if (CHECK_OPERAND(0, REG_R15, OperandSandbox8bit) || |
468 CHECK_OPERAND(0, REG_R15, OperandSandboxRestricted) || | 477 CHECK_OPERAND(0, REG_R15, OperandSandboxRestricted) || |
469 CHECK_OPERAND(0, REG_R15, OperandSandboxUnrestricted)) { | 478 CHECK_OPERAND(0, REG_R15, OperandSandboxUnrestricted)) { |
470 *instruction_info_collected |= R15_MODIFIED; | 479 *instruction_info_collected |= R15_MODIFIED; |
471 } else if ((CHECK_OPERAND(0, REG_RBP, OperandSandbox8bit) && rex_prefix) || | 480 } else if ((CHECK_OPERAND(0, REG_RBP, OperandSandbox8bit) && rex_prefix) || |
472 CHECK_OPERAND(0, REG_RBP, OperandSandboxUnrestricted)) { | 481 CHECK_OPERAND(0, REG_RBP, OperandSandboxUnrestricted)) { |
473 *instruction_info_collected |= BPL_MODIFIED; | 482 *instruction_info_collected |= BPL_MODIFIED; |
474 } else if ((CHECK_OPERAND(0, REG_RSP, OperandSandbox8bit) && rex_prefix) || | 483 } else if ((CHECK_OPERAND(0, REG_RSP, OperandSandbox8bit) && rex_prefix) || |
475 CHECK_OPERAND(0, REG_RSP, OperandSandboxUnrestricted)) { | 484 CHECK_OPERAND(0, REG_RSP, OperandSandboxUnrestricted)) { |
476 *instruction_info_collected |= SPL_MODIFIED; | 485 *instruction_info_collected |= SPL_MODIFIED; |
477 /* Take 2 bits of operand type from operand_states as *restricted_register, | 486 /* Take 2 bits of operand type from operand_states as *restricted_register, |
478 * make sure operand_states denotes a register (4th bit == 0). */ | 487 * make sure operand_states denotes a register (4th bit == 0). */ |
479 } else if ((operand_states & 0x70) == (OperandSandboxRestricted << 5)) { | 488 } else if ((operand_states & 0x70) == (OperandSandboxRestricted << 5)) { |
480 *restricted_register = operand_states & 0x0f; | 489 *restricted_register = operand_states & 0x0f; |
481 } | 490 } |
482 } | 491 } |
483 | 492 |
484 static INLINE void process_2_operands(enum OperandName *restricted_register, | 493 static INLINE void Process2Operands(enum OperandName *restricted_register, |
485 uint32_t *instruction_info_collected, | 494 uint32_t *instruction_info_collected, |
486 uint8_t rex_prefix, | 495 uint8_t rex_prefix, |
487 uint32_t operand_states) { | 496 uint32_t operand_states) { |
488 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special | 497 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special |
489 * instruction, not with regular instruction. */ | 498 * instruction, not with regular instruction. */ |
490 if (*restricted_register == REG_RSP) { | 499 if (*restricted_register == REG_RSP) { |
491 *instruction_info_collected |= RESTRICTED_RSP_UNPROCESSED; | 500 *instruction_info_collected |= RESTRICTED_RSP_UNPROCESSED; |
492 } else if (*restricted_register == REG_RBP) { | 501 } else if (*restricted_register == REG_RBP) { |
493 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED; | 502 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED; |
494 } | 503 } |
495 *restricted_register = NO_REG; | 504 *restricted_register = NO_REG; |
496 if (CHECK_OPERAND(0, REG_R15, OperandSandbox8bit) || | 505 if (CHECK_OPERAND(0, REG_R15, OperandSandbox8bit) || |
497 CHECK_OPERAND(0, REG_R15, OperandSandboxRestricted) || | 506 CHECK_OPERAND(0, REG_R15, OperandSandboxRestricted) || |
(...skipping 12 matching lines...) Expand all Loading... | |
510 } else if ((CHECK_OPERAND(0, REG_RSP, OperandSandbox8bit) && rex_prefix) || | 519 } else if ((CHECK_OPERAND(0, REG_RSP, OperandSandbox8bit) && rex_prefix) || |
511 CHECK_OPERAND(0, REG_RSP, OperandSandboxRestricted) || | 520 CHECK_OPERAND(0, REG_RSP, OperandSandboxRestricted) || |
512 CHECK_OPERAND(0, REG_RSP, OperandSandboxUnrestricted) || | 521 CHECK_OPERAND(0, REG_RSP, OperandSandboxUnrestricted) || |
513 (CHECK_OPERAND(1, REG_RSP, OperandSandbox8bit) && rex_prefix) || | 522 (CHECK_OPERAND(1, REG_RSP, OperandSandbox8bit) && rex_prefix) || |
514 CHECK_OPERAND(1, REG_RSP, OperandSandboxRestricted) || | 523 CHECK_OPERAND(1, REG_RSP, OperandSandboxRestricted) || |
515 CHECK_OPERAND(1, REG_RSP, OperandSandboxUnrestricted)) { | 524 CHECK_OPERAND(1, REG_RSP, OperandSandboxUnrestricted)) { |
516 *instruction_info_collected |= SPL_MODIFIED; | 525 *instruction_info_collected |= SPL_MODIFIED; |
517 } | 526 } |
518 } | 527 } |
519 | 528 |
520 static INLINE void process_2_operands_zero_extends( | 529 static INLINE void Process2OperandsZeroExtends( |
521 enum OperandName *restricted_register, | 530 enum OperandName *restricted_register, |
522 uint32_t *instruction_info_collected, | 531 uint32_t *instruction_info_collected, |
523 uint8_t rex_prefix, uint32_t operand_states) { | 532 uint8_t rex_prefix, uint32_t operand_states) { |
524 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special | 533 /* Restricted %rsp or %rbp must be processed by appropriate nacl-special |
525 * instruction, not with regular instruction. */ | 534 * instruction, not with regular instruction. */ |
526 if (*restricted_register == REG_RSP) { | 535 if (*restricted_register == REG_RSP) { |
527 *instruction_info_collected |= RESTRICTED_RSP_UNPROCESSED; | 536 *instruction_info_collected |= RESTRICTED_RSP_UNPROCESSED; |
528 } else if (*restricted_register == REG_RBP) { | 537 } else if (*restricted_register == REG_RBP) { |
529 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED; | 538 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED; |
530 } | 539 } |
(...skipping 24 matching lines...) Expand all Loading... | |
555 } else if (CHECK_OPERAND(1, REG_RBP, OperandSandboxRestricted)) { | 564 } else if (CHECK_OPERAND(1, REG_RBP, OperandSandboxRestricted)) { |
556 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED; | 565 *instruction_info_collected |= RESTRICTED_RBP_UNPROCESSED; |
557 } | 566 } |
558 /* Take 2 bits of operand type from operand_states as *restricted_register, | 567 /* Take 2 bits of operand type from operand_states as *restricted_register, |
559 * make sure operand_states denotes a register (12th bit == 0). */ | 568 * make sure operand_states denotes a register (12th bit == 0). */ |
560 } else if ((operand_states & 0x7000) == (OperandSandboxRestricted << 13)) { | 569 } else if ((operand_states & 0x7000) == (OperandSandboxRestricted << 13)) { |
561 *restricted_register = (operand_states & 0x0f00) >> 8; | 570 *restricted_register = (operand_states & 0x0f00) >> 8; |
562 } | 571 } |
563 } | 572 } |
564 | 573 |
574 /* | |
575 * This action redefines the range of the superinstruction to include the | |
576 * preceding sandboxing sequence then invalidates jump targets on the | |
577 * interior of the superinstructions and finally clears “the restricted | |
578 * register” variable. | |
579 */ | |
580 static INLINE void ProcessNaclCallOrJmp( | |
581 uint32_t *instruction_info_collected, const uint8_t **instruction_start, | |
582 const uint8_t *current_position, const uint8_t *data, | |
583 bitmap_word *valid_targets, Bool and_have_rex, Bool add_stores_to_reg) { | |
584 /* Expand the range. Only expand by 6 bytes: this covers “add” (second | |
585 * instruction) and “and” WITHOUT it's REX prefix. | |
586 */ | |
587 *instruction_start -= 6; | |
588 /* Compare registers used by “and”, “add”, and “call” or “jmp”. */ | |
589 if (RMFromModRM((*instruction_start)[1]) != | |
590 (add_stores_to_reg ? RegFromModRM((*instruction_start)[5]) : | |
591 RMFromModRM((*instruction_start)[5])) || | |
592 RMFromModRM((*instruction_start)[1]) != RMFromModRM(current_position[0])) | |
593 *instruction_info_collected |= UNRECOGNIZED_INSTRUCTION; | |
594 /* Make start of the second and third instruction not valid targets. */ | |
595 MakeInvalidJumpTarget((*instruction_start - data) + 3, valid_targets); | |
596 MakeInvalidJumpTarget((*instruction_start - data) + 6, valid_targets); | |
597 /* Expand the range again. This time to cover REX prefix (if any). */ | |
598 if (and_have_rex) --*instruction_start; | |
599 } | |
600 static INLINE void ProcessNaclCallOrJmpAddToRMNoRex( | |
Brad Chen
2012/10/22 21:29:05
Nit: empty line between function decls.
khim
2013/03/08 17:59:53
Done.
| |
601 uint32_t *instruction_info_collected, const uint8_t **instruction_start, | |
602 const uint8_t *current_position, const uint8_t *data, | |
603 bitmap_word *valid_targets) { | |
604 ProcessNaclCallOrJmp(instruction_info_collected, instruction_start, | |
605 current_position, data, valid_targets, FALSE, FALSE); | |
Brad Chen
2012/10/22 21:29:05
As noted elsewhere I'm not happy with these boolea
khim
2013/03/08 17:59:53
Reworked the procedures to exclude bools and added
| |
606 } | |
607 static INLINE void ProcessNaclCallOrJmpAddToRegNoRex( | |
608 uint32_t *instruction_info_collected, const uint8_t **instruction_start, | |
609 const uint8_t *current_position, const uint8_t *data, | |
610 bitmap_word *valid_targets) { | |
611 ProcessNaclCallOrJmp(instruction_info_collected, instruction_start, | |
612 current_position, data, valid_targets, FALSE, TRUE); | |
613 } | |
614 static INLINE void ProcessNaclCallOrJmpAddToRMWithRex( | |
615 uint32_t *instruction_info_collected, const uint8_t **instruction_start, | |
616 const uint8_t *current_position, const uint8_t *data, | |
617 bitmap_word *valid_targets) { | |
618 ProcessNaclCallOrJmp(instruction_info_collected, instruction_start, | |
619 current_position, data, valid_targets, TRUE, FALSE); | |
620 } | |
621 static INLINE void ProcessNaclCallOrJmpAddToRegWithRex( | |
622 uint32_t *instruction_info_collected, const uint8_t **instruction_start, | |
623 const uint8_t *current_position, const uint8_t *data, | |
624 bitmap_word *valid_targets) { | |
625 ProcessNaclCallOrJmp(instruction_info_collected, instruction_start, | |
626 current_position, data, valid_targets, TRUE, TRUE); | |
627 } | |
628 | |
629 /* | |
630 * This action redefines the range of the superinstruction to include the | |
631 * preceding sandboxing sequence then invalidates jump targets on the interior | |
632 * of the superinstruction. | |
633 */ | |
634 static INLINE void SandboxRxiSuperInst( | |
635 const uint8_t **instruction_start, const uint8_t *data, | |
636 bitmap_word *valid_targets, Bool mov_have_rex) { | |
637 /* Expand the range. Only expand by 6 bytes: this covers “lea” (second | |
638 * instruction) and “mov” WITHOUT it's REX prefix. | |
639 */ | |
640 *instruction_start -= 6; | |
641 MakeInvalidJumpTarget((*instruction_start - data) + 2, valid_targets); | |
642 MakeInvalidJumpTarget((*instruction_start - data) + 6, valid_targets); | |
643 /* Expand the range again. This time to cover REX prefix (if any). */ | |
644 if (mov_have_rex) --*instruction_start; | |
645 } | |
646 static INLINE void SandboxRxiSuperInstNoRexOnMov( | |
647 const uint8_t **instruction_start, const uint8_t *data, | |
648 bitmap_word *valid_targets) { | |
649 SandboxRxiSuperInst(instruction_start, data, valid_targets, FALSE); | |
650 } | |
651 static INLINE void SandboxRxiSuperInstWithRexOnMov( | |
652 const uint8_t **instruction_start, const uint8_t *data, | |
653 bitmap_word *valid_targets) { | |
654 SandboxRxiSuperInst(instruction_start, data, valid_targets, TRUE); | |
655 } | |
656 | |
565 #endif /* NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_VALIDATOR_INTERNAL_H_ */ | 657 #endif /* NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_VALIDATOR_INTERNAL_H_ */ |
OLD | NEW |