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

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: The actual refactoring Created 8 years, 8 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 static NaClValidationStatus ValidatorCopyNotImplemented(
Nick Bray 2012/04/25 20:57:42 I think that each validator that doesn't implement
pasko-google - do not use 2012/04/26 15:17:01 hm, we seem to agreed that validator selection is
Nick Bray 2012/04/27 00:41:30 As I see it, each "validator" will always behave t
pasko-google - do not use 2012/04/27 17:32:11 Purely hypothetical: if we want to choose validato
Nick Bray 2012/04/27 22:21:36 That would affect the choice of validator and woul
31 uintptr_t, uint8_t*, size_t, int, int, 31 uintptr_t guest_addr,
32 const NaClCPUFeatures*, struct NaClValidationCache*); 32 uint8_t *data_old,
33 uint8_t *data_new,
34 size_t size,
35 const NaClCPUFeatures *cpu_features) {
36 UNREFERENCED_PARAMETER(guest_addr);
37 UNREFERENCED_PARAMETER(data_old);
38 UNREFERENCED_PARAMETER(data_new);
39 UNREFERENCED_PARAMETER(size);
40 UNREFERENCED_PARAMETER(cpu_features);
41 return NaClValidationFailedNotImplemented;
42 }
33 43
34 static ValidateFunc NaClSelectValidator(struct NaClApp *nap) { 44 static NaClValidationStatus ValidatorCodeReplacementNotImplemented(
35 ValidateFunc ret = NACL_SUBARCH_NAME(ApplyValidator, 45 uintptr_t guest_addr,
36 NACL_TARGET_ARCH, NACL_TARGET_SUBARCH); 46 uint8_t *data_old,
37 #ifdef __arm__ 47 uint8_t *data_new,
38 UNREFERENCED_PARAMETER(nap); 48 size_t size,
39 #else 49 const NaClCPUFeatures *cpu_features) {
40 if (nap->enable_dfa_validator) { 50 UNREFERENCED_PARAMETER(guest_addr);
41 ret = NACL_SUBARCH_NAME(ApplyDfaValidator, 51 UNREFERENCED_PARAMETER(data_old);
42 NACL_TARGET_ARCH, NACL_TARGET_SUBARCH); 52 UNREFERENCED_PARAMETER(data_new);
53 UNREFERENCED_PARAMETER(size);
54 UNREFERENCED_PARAMETER(cpu_features);
55 return NaClValidationFailedNotImplemented;
56 }
57
58 void NaClSelectValidator(struct NaClApp *nap) {
59 nap->validate_func = NACL_SUBARCH_NAME(ApplyValidator,
Nick Bray 2012/04/25 20:57:42 I'd reorganize this into mutually exclusive ifdefs
pasko-google - do not use 2012/04/26 15:17:01 That was my first thought as well. Mutually exclus
Nick Bray 2012/04/27 00:41:30 But if you require each validator declare its own
60 NACL_TARGET_ARCH, NACL_TARGET_SUBARCH);
61 #if !defined(__arm__) && defined(NACL_STANDALONE)
62 if (getenv("NACL_DANGEROUS_USE_DFA_VALIDATOR") != NULL) {
63 fprintf(stderr, "DANGER! USING THE UNSTABLE DFA VALIDATOR!\n");
64 nap->validate_func = NACL_SUBARCH_NAME(ApplyDfaValidator,
65 NACL_TARGET_ARCH, NACL_TARGET_SUBARCH);
43 } 66 }
44 #endif 67 #endif
45 return ret; 68 nap->validate_copy_func = ValidatorCopyNotImplemented;
69 nap->validate_code_replacement_func = ValidatorCodeReplacementNotImplemented;
70 #ifndef __arm__
71 nap->validate_copy_func = NACL_SUBARCH_NAME(ApplyValidatorCopy,
72 NACL_TARGET_ARCH, NACL_TARGET_SUBARCH);
73 nap->validate_code_replacement_func = NACL_SUBARCH_NAME(
74 ApplyValidatorCodeReplacement, NACL_TARGET_ARCH, NACL_TARGET_SUBARCH);
75 #endif
46 } 76 }
47 77
48 int NaClValidateCode(struct NaClApp *nap, uintptr_t guest_addr, 78 int NaClValidateCode(struct NaClApp *nap, uintptr_t guest_addr,
49 uint8_t *data, size_t size) { 79 uint8_t *data, size_t size) {
50 NaClValidationStatus status = NaClValidationSucceeded; 80 NaClValidationStatus status = NaClValidationSucceeded;
51 struct NaClValidationCache *cache = nap->validation_cache; 81 struct NaClValidationCache *cache = nap->validation_cache;
52 ValidateFunc validate_func = NaClSelectValidator(nap);
53 82
54 if (size < kMinimumCachedCodeSize) { 83 if (size < kMinimumCachedCodeSize) {
55 /* 84 /*
56 * Don't cache the validation of small code chunks for three reasons: 85 * Don't cache the validation of small code chunks for three reasons:
57 * 1) The size of the validation cache will be bounded. Cache entries are 86 * 1) The size of the validation cache will be bounded. Cache entries are
58 * better used for bigger code. 87 * better used for bigger code.
59 * 2) The per-transaction overhead of validation caching is more noticeable 88 * 2) The per-transaction overhead of validation caching is more noticeable
60 * for small code. 89 * for small code.
61 * 3) JITs tend to generate a lot of small code chunks, and JITed code may 90 * 3) JITs tend to generate a lot of small code chunks, and JITed code may
62 * never be seen again. Currently code size is the best mechanism we 91 * never be seen again. Currently code size is the best mechanism we
(...skipping 14 matching lines...) Expand all
77 NaClLog(LOG_FATAL, 106 NaClLog(LOG_FATAL,
78 "stub_out_mode and fixed_feature_cpu_mode are incompatible\n"); 107 "stub_out_mode and fixed_feature_cpu_mode are incompatible\n");
79 return LOAD_VALIDATION_FAILED; 108 return LOAD_VALIDATION_FAILED;
80 } 109 }
81 if (nap->validator_stub_out_mode) { 110 if (nap->validator_stub_out_mode) {
82 /* Validation caching is currently incompatible with stubout. */ 111 /* Validation caching is currently incompatible with stubout. */
83 cache = NULL; 112 cache = NULL;
84 /* In stub out mode, we do two passes. The second pass acts as a 113 /* In stub out mode, we do two passes. The second pass acts as a
85 sanity check that bad instructions were indeed overwritten with 114 sanity check that bad instructions were indeed overwritten with
86 allowable HLTs. */ 115 allowable HLTs. */
87 status = validate_func(guest_addr, data, size, 116 status = nap->validate_func(guest_addr, data, size,
88 TRUE, /* stub out */ 117 TRUE, /* stub out */
89 FALSE, /* text is not read-only */ 118 FALSE, /* text is not read-only */
90 &nap->cpu_features, 119 &nap->cpu_features,
91 cache); 120 cache);
92 } 121 }
93 if (status == NaClValidationSucceeded) { 122 if (status == NaClValidationSucceeded) {
94 /* Fixed feature CPU mode implies read-only. */ 123 /* Fixed feature CPU mode implies read-only. */
95 int readonly_text = nap->fixed_feature_cpu_mode; 124 int readonly_text = nap->fixed_feature_cpu_mode;
96 status = validate_func(guest_addr, data, size, 125 status = nap->validate_func(guest_addr, data, size,
97 FALSE, /* do not stub out */ 126 FALSE, /* do not stub out */
98 readonly_text, 127 readonly_text,
99 &nap->cpu_features, 128 &nap->cpu_features,
100 cache); 129 cache);
101 } 130 }
102 return NaClValidateStatus(status); 131 return NaClValidateStatus(status);
103 } 132 }
104 133
105 int NaClValidateCodeReplacement(struct NaClApp *nap, uintptr_t guest_addr, 134 int NaClValidateCodeReplacement(struct NaClApp *nap, uintptr_t guest_addr,
106 uint8_t *data_old, uint8_t *data_new, 135 uint8_t *data_old, uint8_t *data_new,
107 size_t size) { 136 size_t size) {
108 if (nap->validator_stub_out_mode) return LOAD_BAD_FILE; 137 if (nap->validator_stub_out_mode) return LOAD_BAD_FILE;
109 if (nap->fixed_feature_cpu_mode) return LOAD_BAD_FILE; 138 if (nap->fixed_feature_cpu_mode) return LOAD_BAD_FILE;
110 139
111 if ((guest_addr % nap->bundle_size) != 0 || 140 if ((guest_addr % nap->bundle_size) != 0 ||
112 (size % nap->bundle_size) != 0) { 141 (size % nap->bundle_size) != 0) {
113 return LOAD_BAD_FILE; 142 return LOAD_BAD_FILE;
114 } 143 }
115 144
116 return NaClValidateStatus( 145 return NaClValidateStatus(nap->validate_code_replacement_func(
117 NACL_SUBARCH_NAME(ApplyValidatorCodeReplacement, 146 guest_addr, data_old, data_new, size, &nap->cpu_features));
118 NACL_TARGET_ARCH,
119 NACL_TARGET_SUBARCH)
120 (guest_addr, data_old, data_new, size, &nap->cpu_features));
121 } 147 }
122 148
123 int NaClCopyCode(struct NaClApp *nap, uintptr_t guest_addr, 149 int NaClCopyCode(struct NaClApp *nap, uintptr_t guest_addr,
124 uint8_t *data_old, uint8_t *data_new, 150 uint8_t *data_old, uint8_t *data_new,
125 size_t size) { 151 size_t size) {
126 /* Fixed-feature mode disables any code copying for now. Currently 152 /* Fixed-feature mode disables any code copying for now. Currently
127 * the only use of NaClCodeCopy() seems to be for dynamic code 153 * the only use of NaClCodeCopy() seems to be for dynamic code
128 * modification, which should fail in NaClValidateCodeReplacement() 154 * modification, which should fail in NaClValidateCodeReplacement()
129 * before reaching this. 155 * before reaching this.
130 */ 156 */
131 if (nap->fixed_feature_cpu_mode) return LOAD_BAD_FILE; 157 if (nap->fixed_feature_cpu_mode) return LOAD_BAD_FILE;
132 return NaClValidateStatus( 158 return NaClValidateStatus(nap->validate_copy_func(
133 NACL_SUBARCH_NAME(ApplyValidatorCopy, 159 guest_addr, data_old, data_new, size, &nap->cpu_features));
134 NACL_TARGET_ARCH,
135 NACL_TARGET_SUBARCH)
136 (guest_addr, data_old, data_new, size, &nap->cpu_features));
137 } 160 }
138 161
139 NaClErrorCode NaClValidateImage(struct NaClApp *nap) { 162 NaClErrorCode NaClValidateImage(struct NaClApp *nap) {
140 uintptr_t memp; 163 uintptr_t memp;
141 uintptr_t endp; 164 uintptr_t endp;
142 size_t regionsize; 165 size_t regionsize;
143 NaClErrorCode rcode; 166 NaClErrorCode rcode;
144 167
145 memp = nap->mem_start + NACL_TRAMPOLINE_END; 168 memp = nap->mem_start + NACL_TRAMPOLINE_END;
146 endp = nap->mem_start + nap->static_text_end; 169 endp = nap->mem_start + nap->static_text_end;
(...skipping 17 matching lines...) Expand all
164 NaClLog(LOG_ERROR, 187 NaClLog(LOG_ERROR,
165 "Run sel_ldr in debug mode to ignore validation failure.\n"); 188 "Run sel_ldr in debug mode to ignore validation failure.\n");
166 NaClLog(LOG_ERROR, 189 NaClLog(LOG_ERROR,
167 "Run ncval <module-name> for validation error details.\n"); 190 "Run ncval <module-name> for validation error details.\n");
168 rcode = LOAD_VALIDATION_FAILED; 191 rcode = LOAD_VALIDATION_FAILED;
169 } 192 }
170 } 193 }
171 } 194 }
172 return rcode; 195 return rcode;
173 } 196 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698