| OLD | NEW |
| (Empty) |
| 1 /* | |
| 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 | |
| 4 * found in the LICENSE file. | |
| 5 */ | |
| 6 | |
| 7 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_VALIDATOR_H_ | |
| 8 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_VALIDATOR_H_ | |
| 9 | |
| 10 #include "native_client/src/trusted/validator_ragel/unreviewed/decoder.h" | |
| 11 | |
| 12 EXTERN_C_BEGIN | |
| 13 | |
| 14 enum validation_callback_info { | |
| 15 /* Anyfield info mask: you can use to parse information about anyfields. */ | |
| 16 ANYFIELD_INFO_MASK = 0x000000ff, | |
| 17 /* Immediate sizes (immediates always come at the end of instruction). */ | |
| 18 IMMEDIATES_SIZE_MASK = 0x0000000f, | |
| 19 IMMEDIATE_8BIT = 0x00000001, | |
| 20 IMMEDIATE_16BIT = 0x00000002, | |
| 21 IMMEDIATE_32BIT = 0x00000004, | |
| 22 IMMEDIATE_64BIT = 0x00000008, | |
| 23 /* Second 8bit immediate is only used in "extrq/insertq" instructions. */ | |
| 24 SECOND_IMMEDIATE_8BIT = 0x00000011, | |
| 25 /* Second 16bit immediate is only used in "enter" instruction. */ | |
| 26 SECOND_IMMEDIATE_16BIT = 0x00000012, | |
| 27 /* Displacement sizes (displacements come at the end - before immediates). */ | |
| 28 DISPLACEMENT_SIZE_MASK = 0x00000060, | |
| 29 DISPLACEMENT_8BIT = 0x00000021, | |
| 30 DISPLACEMENT_16BIT = 0x00000042, | |
| 31 DISPLACEMENT_32BIT = 0x00000064, | |
| 32 /* Relative size (relative fields always come at the end if instriction). */ | |
| 33 RELATIVE_8BIT = 0x00000081, | |
| 34 RELATIVE_16BIT = 0x00000082, | |
| 35 RELATIVE_32BIT = 0x00000084, | |
| 36 /* Not a normal immediate: only two bits can be changed. */ | |
| 37 IMMEDIATE_2BIT = 0x20000010, | |
| 38 /* Last restricted register. */ | |
| 39 RESTRICTED_REGISTER_MASK = 0x00001f00, | |
| 40 RESTRICTED_REGISTER_SHIFT = 8, | |
| 41 /* Was restricted from previous instruction used in the current one? */ | |
| 42 RESTRICTED_REGISTER_USED = 0x00002000, | |
| 43 /* Mask to select all validation errors. */ | |
| 44 VALIDATION_ERRORS_MASK = 0x01ffc000, | |
| 45 /* Unrecognized instruction: fatal error, processing stops here. */ | |
| 46 UNRECOGNIZED_INSTRUCTION = 0x00004000, | |
| 47 /* Direct jump to unaligned address outside of given region. */ | |
| 48 DIRECT_JUMP_OUT_OF_RANGE = 0x00008000, | |
| 49 /* Instruction is not allowed on current CPU. */ | |
| 50 CPUID_UNSUPPORTED_INSTRUCTION = 0x00010000, | |
| 51 /* Base register can be one of: %r15, %rbp, %rip, %rsp. */ | |
| 52 FORBIDDEN_BASE_REGISTER = 0x00020000, | |
| 53 /* Index must be restricted if present. */ | |
| 54 UNRESTRICTED_INDEX_REGISTER = 0x00040000, | |
| 55 BAD_RSP_RBP_PROCESSING_MASK = 0x00380000, | |
| 56 /* Operations with %ebp must be followed with sandboxing immediately. */ | |
| 57 RESTRICTED_RBP_UNPROCESSED = 0x00080000, | |
| 58 /* Attemp to "sandbox" %rbp without restricting it first. */ | |
| 59 UNRESTRICTED_RBP_PROCESSED = 0x00180000, | |
| 60 /* Operations with %esp must be followed with sandboxing immediately. */ | |
| 61 RESTRICTED_RSP_UNPROCESSED = 0x00280000, | |
| 62 /* Attemp to "sandbox" %rsp without restricting it first. */ | |
| 63 UNRESTRICTED_RSP_PROCESSED = 0x00380000, | |
| 64 /* Operations with %r15 are forbidden. */ | |
| 65 R15_MODIFIED = 0x00400000, | |
| 66 /* Operations with SPL are forbidden for compatibility with old validator. */ | |
| 67 BPL_MODIFIED = 0x00800000, | |
| 68 /* Operations with SPL are forbidden for compatibility with old validator. */ | |
| 69 SPL_MODIFIED = 0x01000000, | |
| 70 /* Bad call alignment: "call" must end at the end of the bundle. */ | |
| 71 BAD_CALL_ALIGNMENT = 0x02000000, | |
| 72 /* Instruction is modifiable by nacl_dyncode_modify. */ | |
| 73 MODIFIABLE_INSTRUCTION = 0x08000000, | |
| 74 /* Special instruction. Uses different, non-standard validation rules. */ | |
| 75 SPECIAL_INSTRUCTION = 0x10000000, | |
| 76 /* Some 3DNow! instructions use immediate byte as opcode extensions. */ | |
| 77 LAST_BYTE_IS_NOT_IMMEDIATE = 0x20000000, | |
| 78 /* Bad jump target. Note: in this case ptr points to jump target! */ | |
| 79 BAD_JUMP_TARGET = 0x40000000 | |
| 80 }; | |
| 81 | |
| 82 #define kBundleSize 32 | |
| 83 #define kBundleMask 31 | |
| 84 | |
| 85 enum validation_options { | |
| 86 /* Call process_error function on instruction. */ | |
| 87 CALL_USER_CALLBACK_ON_EACH_INSTRUCTION = 0x00000001, | |
| 88 /* Process all instruction as a contiguous stream. */ | |
| 89 PROCESS_CHUNK_AS_A_CONTIGUOUS_STREAM = 0x00000002 | |
| 90 }; | |
| 91 | |
| 92 /* | |
| 93 * Callback is invoked by ValidateChunk* for all erroneous instructions | |
| 94 * (or for all instructions if CALL_USER_CALLBACK_ON_EACH_INSTRUCTION is set). | |
| 95 * It's up to the callback to decide whether this particual place is indeed | |
| 96 * a violation. If callback returns FALSE at least once, validation result | |
| 97 * becomes FALSE. | |
| 98 * | |
| 99 * When callback is called for invalid jump tagret, | |
| 100 * instruction_start = instruction_end = jump target | |
| 101 * | |
| 102 * Minimal user_callback looks like this: | |
| 103 * ... | |
| 104 * if (validation_info & (VALIDATION_ERRORS_MASK | BAD_JUMP_TARGET)) | |
| 105 * return FALSE; | |
| 106 * else | |
| 107 * return TRUE; | |
| 108 * ... | |
| 109 */ | |
| 110 typedef Bool (*validation_callback_func) (const uint8_t *instruction_start, | |
| 111 const uint8_t *instruction_end, | |
| 112 uint32_t validation_info, | |
| 113 void *callback_data); | |
| 114 | |
| 115 /* | |
| 116 * Returns whether given piece of code is valid. | |
| 117 * It is assumed that size % kBundleSize = 0. | |
| 118 * For every error/warning, user_callback is called. | |
| 119 * Alternatively, if CALL_USER_CALLBACK_ON_EACH_INSTRUCTION flag in options is | |
| 120 * set, user_callback is called for every instruction. | |
| 121 * If PROCESS_CHUNK_AS_A_CONTIGUOUS_STREAM flag in options is set, | |
| 122 * instructions crossing bundle boundaries are not considered erroneous. | |
| 123 * | |
| 124 * Actually validation result is computed as conjunction of values returned | |
| 125 * by all invocations of user_callback, so custom validation logic can be | |
| 126 * placed there. | |
| 127 */ | |
| 128 Bool ValidateChunkAMD64(const uint8_t *data, size_t size, | |
| 129 enum validation_options options, | |
| 130 const NaClCPUFeaturesX86 *cpu_features, | |
| 131 validation_callback_func user_callback, | |
| 132 void *callback_data); | |
| 133 | |
| 134 /* | |
| 135 * See ValidateChunkAMD64 | |
| 136 */ | |
| 137 Bool ValidateChunkIA32(const uint8_t *data, size_t size, | |
| 138 enum validation_options options, | |
| 139 const NaClCPUFeaturesX86 *cpu_features, | |
| 140 validation_callback_func user_callback, | |
| 141 void *callback_data); | |
| 142 | |
| 143 EXTERN_C_END | |
| 144 | |
| 145 #endif /* NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_VALIDATOR_H_ */ | |
| OLD | NEW |