Chromium Code Reviews| Index: src/trusted/validator_ragel/validator_internal.h |
| =================================================================== |
| --- src/trusted/validator_ragel/validator_internal.h (revision 9944) |
| +++ src/trusted/validator_ragel/validator_internal.h (working copy) |
| @@ -14,7 +14,7 @@ |
| #include "native_client/src/shared/platform/nacl_check.h" |
| #include "native_client/src/shared/utils/types.h" |
| -#include "native_client/src/trusted/validator_ragel/unreviewed/decoding.h" |
| +#include "native_client/src/trusted/validator_ragel/decoding.h" |
| #include "native_client/src/trusted/validator_ragel/unreviewed/validator.h" |
| /* Maximum set of R-DFA allowable CPUID features. */ |
| @@ -190,13 +190,6 @@ |
| #define SET_MODRM_BASE(N) base = (N) |
| #define SET_MODRM_INDEX(N) index = (N) |
| -enum { |
| - REX_B = 1, |
| - REX_X = 2, |
| - REX_R = 4, |
| - REX_W = 8 |
| -}; |
| - |
| enum operand_kind { |
| OperandSandboxIrrelevant = 0, |
| /* |
| @@ -322,7 +315,23 @@ |
| return TRUE; |
| } |
| +/* |
| + * Mark the given address as valid jump target address. |
| + */ |
| +static FORCEINLINE void MakeJumpTargetValid(size_t address, |
| + bitmap_word *valid_targets) { |
| + BitmapSetBit(valid_targets, address); |
| +} |
| +/* |
| + * Mark the given address as invalid jump target address. |
| + */ |
| +static FORCEINLINE void MakeInvalidJumpTarget(size_t address, |
| + bitmap_word *valid_targets) { |
| + BitmapClearBit(valid_targets, address); |
| +} |
| + |
| + |
| static INLINE Bool ProcessInvalidJumpTargets( |
| const uint8_t *data, |
| size_t size, |
| @@ -413,8 +422,8 @@ |
| } |
| -static INLINE void process_0_operands(enum OperandName *restricted_register, |
| - uint32_t *instruction_info_collected) { |
| +static INLINE void Process0Operands(enum OperandName *restricted_register, |
| + uint32_t *instruction_info_collected) { |
| /* Restricted %rsp or %rbp must be processed by appropriate nacl-special |
| * instruction, not with regular instruction. */ |
| if (*restricted_register == REG_RSP) { |
| @@ -425,10 +434,10 @@ |
| *restricted_register = NO_REG; |
| } |
| -static INLINE void process_1_operand(enum OperandName *restricted_register, |
| - uint32_t *instruction_info_collected, |
| - uint8_t rex_prefix, |
| - uint32_t operand_states) { |
| +static INLINE void Process1Operand(enum OperandName *restricted_register, |
| + uint32_t *instruction_info_collected, |
| + uint8_t rex_prefix, |
| + uint32_t operand_states) { |
| /* Restricted %rsp or %rbp must be processed by appropriate nacl-special |
| * instruction, not with regular instruction. */ |
| if (*restricted_register == REG_RSP) { |
| @@ -452,7 +461,7 @@ |
| } |
| } |
| -static INLINE void process_1_operand_zero_extends( |
| +static INLINE void Process1OperandZeroExtends( |
| enum OperandName *restricted_register, |
| uint32_t *instruction_info_collected, uint8_t rex_prefix, |
| uint32_t operand_states) { |
| @@ -481,10 +490,10 @@ |
| } |
| } |
| -static INLINE void process_2_operands(enum OperandName *restricted_register, |
| - uint32_t *instruction_info_collected, |
| - uint8_t rex_prefix, |
| - uint32_t operand_states) { |
| +static INLINE void Process2Operands(enum OperandName *restricted_register, |
| + uint32_t *instruction_info_collected, |
| + uint8_t rex_prefix, |
| + uint32_t operand_states) { |
| /* Restricted %rsp or %rbp must be processed by appropriate nacl-special |
| * instruction, not with regular instruction. */ |
| if (*restricted_register == REG_RSP) { |
| @@ -517,7 +526,7 @@ |
| } |
| } |
| -static INLINE void process_2_operands_zero_extends( |
| +static INLINE void Process2OperandsZeroExtends( |
| enum OperandName *restricted_register, |
| uint32_t *instruction_info_collected, |
| uint8_t rex_prefix, uint32_t operand_states) { |
| @@ -562,4 +571,87 @@ |
| } |
| } |
| +/* |
| + * This action redefines the range of the superinstruction to include the |
| + * preceding sandboxing sequence then invalidates jump targets on the |
| + * interior of the superinstructions and finally clears “the restricted |
| + * register” variable. |
| + */ |
| +static INLINE void ProcessNaclCallOrJmp( |
| + uint32_t *instruction_info_collected, const uint8_t **instruction_start, |
| + const uint8_t *current_position, const uint8_t *data, |
| + bitmap_word *valid_targets, Bool and_have_rex, Bool add_stores_to_reg) { |
| + /* Expand the range. Only expand by 6 bytes: this covers “add” (second |
| + * instruction) and “and” WITHOUT it's REX prefix. |
| + */ |
| + *instruction_start -= 6; |
| + /* Compare registers used by “and”, “add”, and “call” or “jmp”. */ |
| + if (RMFromModRM((*instruction_start)[1]) != |
| + (add_stores_to_reg ? RegFromModRM((*instruction_start)[5]) : |
| + RMFromModRM((*instruction_start)[5])) || |
| + RMFromModRM((*instruction_start)[1]) != RMFromModRM(current_position[0])) |
| + *instruction_info_collected |= UNRECOGNIZED_INSTRUCTION; |
| + /* Make start of the second and third instruction not valid targets. */ |
| + MakeInvalidJumpTarget((*instruction_start - data) + 3, valid_targets); |
| + MakeInvalidJumpTarget((*instruction_start - data) + 6, valid_targets); |
| + /* Expand the range again. This time to cover REX prefix (if any). */ |
| + if (and_have_rex) --*instruction_start; |
| +} |
| +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.
|
| + uint32_t *instruction_info_collected, const uint8_t **instruction_start, |
| + const uint8_t *current_position, const uint8_t *data, |
| + bitmap_word *valid_targets) { |
| + ProcessNaclCallOrJmp(instruction_info_collected, instruction_start, |
| + 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
|
| +} |
| +static INLINE void ProcessNaclCallOrJmpAddToRegNoRex( |
| + uint32_t *instruction_info_collected, const uint8_t **instruction_start, |
| + const uint8_t *current_position, const uint8_t *data, |
| + bitmap_word *valid_targets) { |
| + ProcessNaclCallOrJmp(instruction_info_collected, instruction_start, |
| + current_position, data, valid_targets, FALSE, TRUE); |
| +} |
| +static INLINE void ProcessNaclCallOrJmpAddToRMWithRex( |
| + uint32_t *instruction_info_collected, const uint8_t **instruction_start, |
| + const uint8_t *current_position, const uint8_t *data, |
| + bitmap_word *valid_targets) { |
| + ProcessNaclCallOrJmp(instruction_info_collected, instruction_start, |
| + current_position, data, valid_targets, TRUE, FALSE); |
| +} |
| +static INLINE void ProcessNaclCallOrJmpAddToRegWithRex( |
| + uint32_t *instruction_info_collected, const uint8_t **instruction_start, |
| + const uint8_t *current_position, const uint8_t *data, |
| + bitmap_word *valid_targets) { |
| + ProcessNaclCallOrJmp(instruction_info_collected, instruction_start, |
| + current_position, data, valid_targets, TRUE, TRUE); |
| +} |
| + |
| +/* |
| + * This action redefines the range of the superinstruction to include the |
| + * preceding sandboxing sequence then invalidates jump targets on the interior |
| + * of the superinstruction. |
| + */ |
| +static INLINE void SandboxRxiSuperInst( |
| + const uint8_t **instruction_start, const uint8_t *data, |
| + bitmap_word *valid_targets, Bool mov_have_rex) { |
| + /* Expand the range. Only expand by 6 bytes: this covers “lea” (second |
| + * instruction) and “mov” WITHOUT it's REX prefix. |
| + */ |
| + *instruction_start -= 6; |
| + MakeInvalidJumpTarget((*instruction_start - data) + 2, valid_targets); |
| + MakeInvalidJumpTarget((*instruction_start - data) + 6, valid_targets); |
| + /* Expand the range again. This time to cover REX prefix (if any). */ |
| + if (mov_have_rex) --*instruction_start; |
| +} |
| +static INLINE void SandboxRxiSuperInstNoRexOnMov( |
| + const uint8_t **instruction_start, const uint8_t *data, |
| + bitmap_word *valid_targets) { |
| + SandboxRxiSuperInst(instruction_start, data, valid_targets, FALSE); |
| +} |
| +static INLINE void SandboxRxiSuperInstWithRexOnMov( |
| + const uint8_t **instruction_start, const uint8_t *data, |
| + bitmap_word *valid_targets) { |
| + SandboxRxiSuperInst(instruction_start, data, valid_targets, TRUE); |
| +} |
| + |
| #endif /* NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_VALIDATOR_INTERNAL_H_ */ |