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

Side by Side Diff: src/trusted/service_runtime/sel_validate_image.c

Issue 10134056: Refactor the process of choosing validators. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: draft that does not fully build Created 8 years, 7 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) 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 #include "native_client/src/shared/platform/nacl_log.h" 7 #include "native_client/src/shared/platform/nacl_log.h"
8 #include "native_client/src/trusted/service_runtime/sel_ldr.h" 8 #include "native_client/src/trusted/service_runtime/sel_ldr.h"
9 #include "native_client/src/trusted/validator/ncvalidate.h" 9 #include "native_client/src/trusted/validator/ncvalidate.h"
10 10
11 const size_t kMinimumCachedCodeSize = 40000; 11 const size_t kMinimumCachedCodeSize = 40000;
12 12
13 /* Translate validation status to values wanted by sel_ldr. */ 13 /* Translate validation status to values wanted by sel_ldr. */
14 static int NaClValidateStatus(NaClValidationStatus status) { 14 static int NaClValidateStatus(NaClValidationStatus status) {
15 switch (status) { 15 switch (status) {
16 case NaClValidationSucceeded: 16 case NaClValidationSucceeded:
17 return LOAD_OK; 17 return LOAD_OK;
18 case NaClValidationFailedOutOfMemory: 18 case NaClValidationFailedOutOfMemory:
19 /* Note: this is confusing, but is what sel_ldr is expecting. */ 19 /* Note: this is confusing, but is what sel_ldr is expecting. */
20 return LOAD_BAD_FILE; 20 return LOAD_BAD_FILE;
21 case NaClValidationFailed: 21 case NaClValidationFailed:
22 case NaClValidationFailedNotImplemented: 22 case NaClValidationFailedNotImplemented:
23 case NaClValidationFailedCpuNotSupported: 23 case NaClValidationFailedCpuNotSupported:
24 case NaClValidationFailedSegmentationIssue: 24 case NaClValidationFailedSegmentationIssue:
25 default: 25 default:
26 return LOAD_VALIDATION_FAILED; 26 return LOAD_VALIDATION_FAILED;
27 } 27 }
28 } 28 }
29 29
30 typedef NaClValidationStatus (*ValidateFunc) ( 30 Bool UseDfaValidator() {
31 uintptr_t, uint8_t*, size_t, int, int, 31 if (getenv("NACL_DANGEROUS_USE_DFA_VALIDATOR") != NULL) {
32 const NaClCPUFeatures*, struct NaClValidationCache*); 32 return TRUE;
33 }
34 return FALSE;
35 }
33 36
34 static ValidateFunc NaClSelectValidator(struct NaClApp *nap) { 37 void NaClSelectValidator(struct NaClValidatorInterface **val) {
35 ValidateFunc ret = NACL_SUBARCH_NAME(ApplyValidator, 38 /* TODO: make it more nested. */
Nick Bray 2012/04/27 22:21:36 I started with it being nested, but unless you ind
pasko-google - do not use 2012/05/12 12:18:40 to me it looks almost equally horrible, so I'd bet
36 NACL_TARGET_ARCH, NACL_TARGET_SUBARCH); 39 #if defined(__i386__) && defined(NACL_STANDALONE)
37 /* Avoid linking two validators into Chromium to keep download size small. */ 40 if (UseDfaValidator()) {
38 #if defined(__arm__) || !defined(NACL_STANDALONE) 41 fprintf(stderr, "DANGER! USING THE UNSTABLE DFA VALIDATOR!\n");
Nick Bray 2012/04/27 22:21:36 Nit: Experimental? Untested?
pasko-google - do not use 2012/05/12 12:18:40 Done.
39 UNREFERENCED_PARAMETER(nap); 42 NaClDfaValidatorInit_x86_32(val);
43 } else {
44 NaClValidatorInit_x86_32(val);
45 }
46 #elif defined(__i386__)
47 NaClValidatorInit_x86_32(val);
48 #elif defined(__x86_64__) && defined(NACL_STANDALONE)
49 if (UseDfaValidator()) {
50 fprintf(stderr, "DANGER! USING THE UNSTABLE DFA VALIDATOR!\n");
51 NaClDfaValidatorInit_x86_64(val);
52 } else {
53 NaClValidatorInit_x86_64(val);
54 }
55 #elif defined(__x86_64__)
56 NaClValidatorInit_x86_64(val);
57 #elif defined(__arm__)
58 NaClValidatorInitArm(val);
40 #else 59 #else
41 if (nap->enable_dfa_validator) { 60 #error "No validator available for this architecture!"
42 ret = NACL_SUBARCH_NAME(ApplyDfaValidator, 61 #endif
43 NACL_TARGET_ARCH, NACL_TARGET_SUBARCH); 62 }
63
64 #if 0
65 void NaClSelectValidator(struct NaClApp *nap) {
66 nap->validate_func = NACL_SUBARCH_NAME(ApplyValidator,
67 NACL_TARGET_ARCH, NACL_TARGET_SUBARCH);
68 #if !defined(__arm__) && defined(NACL_STANDALONE)
69 if (getenv("NACL_DANGEROUS_USE_DFA_VALIDATOR") != NULL) {
70 fprintf(stderr, "DANGER! USING THE UNSTABLE DFA VALIDATOR!\n");
71 nap->validate_func = NACL_SUBARCH_NAME(ApplyDfaValidator,
72 NACL_TARGET_ARCH, NACL_TARGET_SUBARCH);
44 } 73 }
45 #endif 74 #endif
46 return ret; 75 nap->validate_copy_func = ValidatorCopyNotImplemented;
76 nap->validate_code_replacement_func = ValidatorCodeReplacementNotImplemented;
77 #ifndef __arm__
78 nap->validate_copy_func = NACL_SUBARCH_NAME(ApplyValidatorCopy,
79 NACL_TARGET_ARCH, NACL_TARGET_SUBARCH);
80 nap->validate_code_replacement_func = NACL_SUBARCH_NAME(
81 ApplyValidatorCodeReplacement, NACL_TARGET_ARCH, NACL_TARGET_SUBARCH);
82 #endif
47 } 83 }
84 #endif
48 85
49 int NaClValidateCode(struct NaClApp *nap, uintptr_t guest_addr, 86 int NaClValidateCode(struct NaClApp *nap, uintptr_t guest_addr,
50 uint8_t *data, size_t size) { 87 uint8_t *data, size_t size) {
51 NaClValidationStatus status = NaClValidationSucceeded; 88 NaClValidationStatus status = NaClValidationSucceeded;
52 struct NaClValidationCache *cache = nap->validation_cache; 89 struct NaClValidationCache *cache = nap->validation_cache;
53 ValidateFunc validate_func = NaClSelectValidator(nap); 90 struct NaClValidatorInterface *validator = nap->validator;
54 91
55 if (size < kMinimumCachedCodeSize) { 92 if (size < kMinimumCachedCodeSize) {
56 /* 93 /*
57 * Don't cache the validation of small code chunks for three reasons: 94 * Don't cache the validation of small code chunks for three reasons:
58 * 1) The size of the validation cache will be bounded. Cache entries are 95 * 1) The size of the validation cache will be bounded. Cache entries are
59 * better used for bigger code. 96 * better used for bigger code.
60 * 2) The per-transaction overhead of validation caching is more noticeable 97 * 2) The per-transaction overhead of validation caching is more noticeable
61 * for small code. 98 * for small code.
62 * 3) JITs tend to generate a lot of small code chunks, and JITed code may 99 * 3) JITs tend to generate a lot of small code chunks, and JITed code may
63 * never be seen again. Currently code size is the best mechanism we 100 * never be seen again. Currently code size is the best mechanism we
64 * have for heuristically distinguishing between JIT and static code. 101 * have for heuristically distinguishing between JIT and static code.
65 * (In practice most Mono JIT blocks are less than 1k, and a quick look 102 * (In practice most Mono JIT blocks are less than 1k, and a quick look
66 * didn't show any above 35k.) 103 * didn't show any above 35k.)
67 * The choice of what constitutes "small" is arbitrary, and should be 104 * The choice of what constitutes "small" is arbitrary, and should be
68 * empirically tuned. 105 * empirically tuned.
69 * TODO(ncbray) let the syscall specify if the code is cached or not. 106 * TODO(ncbray) let the syscall specify if the code is cached or not.
70 */ 107 */
71 cache = NULL; 108 cache = NULL;
72 } 109 }
73 110
74 /* As fixed feature mode implies the text should be readonly, and 111 /* As fixed feature mode implies the text should be readonly, and
75 * stubout mode implies updating the text, disallow their use together. 112 * stubout mode implies updating the text, disallow their use together.
76 */ 113 */
77 if (nap->validator_stub_out_mode && nap->fixed_feature_cpu_mode) { 114 if (nap->validator_stub_out_mode && nap->fixed_feature_cpu_mode) {
78 NaClLog(LOG_FATAL, 115 NaClLog(LOG_FATAL,
79 "stub_out_mode and fixed_feature_cpu_mode are incompatible\n"); 116 "stub_out_mode and fixed_feature_cpu_mode are incompatible\n");
80 return LOAD_VALIDATION_FAILED; 117 return LOAD_VALIDATION_FAILED;
81 } 118 }
119
82 if (nap->validator_stub_out_mode) { 120 if (nap->validator_stub_out_mode) {
83 /* Validation caching is currently incompatible with stubout. */ 121 /* Validation caching is currently incompatible with stubout. */
84 cache = NULL; 122 cache = NULL;
85 /* In stub out mode, we do two passes. The second pass acts as a 123 /* In stub out mode, we do two passes. The second pass acts as a
86 sanity check that bad instructions were indeed overwritten with 124 sanity check that bad instructions were indeed overwritten with
87 allowable HLTs. */ 125 allowable HLTs. */
88 status = validate_func(guest_addr, data, size, 126 status = validator->Validate(guest_addr, data, size,
89 TRUE, /* stub out */ 127 TRUE, /* stub out */
90 FALSE, /* text is not read-only */ 128 FALSE, /* text is not read-only */
91 &nap->cpu_features, 129 &nap->cpu_features,
92 cache); 130 cache);
93 } 131 }
94 if (status == NaClValidationSucceeded) { 132 if (status == NaClValidationSucceeded) {
95 /* Fixed feature CPU mode implies read-only. */ 133 /* Fixed feature CPU mode implies read-only. */
96 int readonly_text = nap->fixed_feature_cpu_mode; 134 int readonly_text = nap->fixed_feature_cpu_mode;
97 status = validate_func(guest_addr, data, size, 135 status = validator->Validate(guest_addr, data, size,
98 FALSE, /* do not stub out */ 136 FALSE, /* do not stub out */
99 readonly_text, 137 readonly_text,
100 &nap->cpu_features, 138 &nap->cpu_features,
101 cache); 139 cache);
102 } 140 }
103 return NaClValidateStatus(status); 141 return NaClValidateStatus(status);
104 } 142 }
105 143
106 int NaClValidateCodeReplacement(struct NaClApp *nap, uintptr_t guest_addr, 144 int NaClValidateCodeReplacement(struct NaClApp *nap, uintptr_t guest_addr,
107 uint8_t *data_old, uint8_t *data_new, 145 uint8_t *data_old, uint8_t *data_new,
108 size_t size) { 146 size_t size) {
109 if (nap->validator_stub_out_mode) return LOAD_BAD_FILE; 147 if (nap->validator_stub_out_mode) return LOAD_BAD_FILE;
110 if (nap->fixed_feature_cpu_mode) return LOAD_BAD_FILE; 148 if (nap->fixed_feature_cpu_mode) return LOAD_BAD_FILE;
111 149
112 if ((guest_addr % nap->bundle_size) != 0 || 150 if ((guest_addr % nap->bundle_size) != 0 ||
113 (size % nap->bundle_size) != 0) { 151 (size % nap->bundle_size) != 0) {
114 return LOAD_BAD_FILE; 152 return LOAD_BAD_FILE;
115 } 153 }
116 154
117 return NaClValidateStatus( 155 return NaClValidateStatus(nap->validator->ValidateCodeReplacement(
118 NACL_SUBARCH_NAME(ApplyValidatorCodeReplacement, 156 guest_addr, data_old, data_new, size, &nap->cpu_features));
119 NACL_TARGET_ARCH,
120 NACL_TARGET_SUBARCH)
121 (guest_addr, data_old, data_new, size, &nap->cpu_features));
122 } 157 }
123 158
124 int NaClCopyCode(struct NaClApp *nap, uintptr_t guest_addr, 159 int NaClCopyCode(struct NaClApp *nap, uintptr_t guest_addr,
125 uint8_t *data_old, uint8_t *data_new, 160 uint8_t *data_old, uint8_t *data_new,
126 size_t size) { 161 size_t size) {
127 /* Fixed-feature mode disables any code copying for now. Currently 162 /* Fixed-feature mode disables any code copying for now. Currently
128 * the only use of NaClCodeCopy() seems to be for dynamic code 163 * the only use of NaClCodeCopy() seems to be for dynamic code
129 * modification, which should fail in NaClValidateCodeReplacement() 164 * modification, which should fail in NaClValidateCodeReplacement()
130 * before reaching this. 165 * before reaching this.
131 */ 166 */
132 if (nap->fixed_feature_cpu_mode) return LOAD_BAD_FILE; 167 if (nap->fixed_feature_cpu_mode) return LOAD_BAD_FILE;
133 return NaClValidateStatus( 168 return NaClValidateStatus(nap->validator->ValidateCopy(
Nick Bray 2012/04/27 22:21:36 Bad name. Validating a copy of what? Hence why I
134 NACL_SUBARCH_NAME(ApplyValidatorCopy, 169 guest_addr, data_old, data_new, size, &nap->cpu_features));
135 NACL_TARGET_ARCH,
136 NACL_TARGET_SUBARCH)
137 (guest_addr, data_old, data_new, size, &nap->cpu_features));
138 } 170 }
139 171
140 NaClErrorCode NaClValidateImage(struct NaClApp *nap) { 172 NaClErrorCode NaClValidateImage(struct NaClApp *nap) {
141 uintptr_t memp; 173 uintptr_t memp;
142 uintptr_t endp; 174 uintptr_t endp;
143 size_t regionsize; 175 size_t regionsize;
144 NaClErrorCode rcode; 176 NaClErrorCode rcode;
145 177
146 memp = nap->mem_start + NACL_TRAMPOLINE_END; 178 memp = nap->mem_start + NACL_TRAMPOLINE_END;
147 endp = nap->mem_start + nap->static_text_end; 179 endp = nap->mem_start + nap->static_text_end;
(...skipping 17 matching lines...) Expand all
165 NaClLog(LOG_ERROR, 197 NaClLog(LOG_ERROR,
166 "Run sel_ldr in debug mode to ignore validation failure.\n"); 198 "Run sel_ldr in debug mode to ignore validation failure.\n");
167 NaClLog(LOG_ERROR, 199 NaClLog(LOG_ERROR,
168 "Run ncval <module-name> for validation error details.\n"); 200 "Run ncval <module-name> for validation error details.\n");
169 rcode = LOAD_VALIDATION_FAILED; 201 rcode = LOAD_VALIDATION_FAILED;
170 } 202 }
171 } 203 }
172 } 204 }
173 return rcode; 205 return rcode;
174 } 206 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698