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 |