OLD | NEW |
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/include/concurrency_ops.h" | 7 #include "native_client/src/include/concurrency_ops.h" |
8 #include "native_client/src/shared/platform/nacl_log.h" | 8 #include "native_client/src/shared/platform/nacl_log.h" |
9 #include "native_client/src/shared/utils/types.h" | 9 #include "native_client/src/shared/utils/types.h" |
10 #include "native_client/src/trusted/service_runtime/sel_ldr.h" | 10 #include "native_client/src/trusted/service_runtime/sel_ldr.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 case NaClValidationFailed: | 23 case NaClValidationFailed: |
24 case NaClValidationFailedNotImplemented: | 24 case NaClValidationFailedNotImplemented: |
25 case NaClValidationFailedCpuNotSupported: | 25 case NaClValidationFailedCpuNotSupported: |
26 case NaClValidationFailedSegmentationIssue: | 26 case NaClValidationFailedSegmentationIssue: |
27 default: | 27 default: |
28 return LOAD_VALIDATION_FAILED; | 28 return LOAD_VALIDATION_FAILED; |
29 } | 29 } |
30 } | 30 } |
31 | 31 |
32 int NaClValidateCode(struct NaClApp *nap, uintptr_t guest_addr, | 32 int NaClValidateCode(struct NaClApp *nap, uintptr_t guest_addr, |
33 uint8_t *data, size_t size) { | 33 uint8_t *data, size_t size, |
| 34 const struct NaClValidationMetadata *metadata) { |
34 NaClValidationStatus status = NaClValidationSucceeded; | 35 NaClValidationStatus status = NaClValidationSucceeded; |
35 struct NaClValidationCache *cache = nap->validation_cache; | 36 struct NaClValidationCache *cache = nap->validation_cache; |
36 const struct NaClValidatorInterface *validator = nap->validator; | 37 const struct NaClValidatorInterface *validator = nap->validator; |
37 | 38 |
38 if (size < kMinimumCachedCodeSize) { | 39 if (size < kMinimumCachedCodeSize) { |
39 /* | 40 /* |
40 * Don't cache the validation of small code chunks for three reasons: | 41 * Don't cache the validation of small code chunks for three reasons: |
41 * 1) The size of the validation cache will be bounded. Cache entries are | 42 * 1) The size of the validation cache will be bounded. Cache entries are |
42 * better used for bigger code. | 43 * better used for bigger code. |
43 * 2) The per-transaction overhead of validation caching is more noticeable | 44 * 2) The per-transaction overhead of validation caching is more noticeable |
44 * for small code. | 45 * for small code. |
45 * 3) JITs tend to generate a lot of small code chunks, and JITed code may | 46 * 3) JITs tend to generate a lot of small code chunks, and JITed code may |
46 * never be seen again. Currently code size is the best mechanism we | 47 * never be seen again. Currently code size is the best mechanism we |
47 * have for heuristically distinguishing between JIT and static code. | 48 * have for heuristically distinguishing between JIT and static code. |
48 * (In practice most Mono JIT blocks are less than 1k, and a quick look | 49 * (In practice most Mono JIT blocks are less than 1k, and a quick look |
49 * didn't show any above 35k.) | 50 * didn't show any above 35k.) |
50 * The choice of what constitutes "small" is arbitrary, and should be | 51 * The choice of what constitutes "small" is arbitrary, and should be |
51 * empirically tuned. | 52 * empirically tuned. |
52 * TODO(ncbray) let the syscall specify if the code is cached or not. | 53 * TODO(ncbray) let the syscall specify if the code is cached or not. |
53 */ | 54 */ |
| 55 metadata = NULL; |
54 cache = NULL; | 56 cache = NULL; |
55 } | 57 } |
56 | 58 |
57 /* As fixed feature mode implies the text should be readonly, and | 59 /* As fixed feature mode implies the text should be readonly, and |
58 * stubout mode implies updating the text, disallow their use together. | 60 * stubout mode implies updating the text, disallow their use together. |
59 */ | 61 */ |
60 if (nap->validator_stub_out_mode && nap->fixed_feature_cpu_mode) { | 62 if (nap->validator_stub_out_mode && nap->fixed_feature_cpu_mode) { |
61 NaClLog(LOG_FATAL, | 63 NaClLog(LOG_FATAL, |
62 "stub_out_mode and fixed_feature_cpu_mode are incompatible\n"); | 64 "stub_out_mode and fixed_feature_cpu_mode are incompatible\n"); |
63 return LOAD_VALIDATION_FAILED; | 65 return LOAD_VALIDATION_FAILED; |
64 } | 66 } |
65 if (nap->validator_stub_out_mode) { | 67 if (nap->validator_stub_out_mode) { |
66 /* Validation caching is currently incompatible with stubout. */ | 68 /* Validation caching is currently incompatible with stubout. */ |
| 69 metadata = NULL; |
67 cache = NULL; | 70 cache = NULL; |
68 /* In stub out mode, we do two passes. The second pass acts as a | 71 /* In stub out mode, we do two passes. The second pass acts as a |
69 sanity check that bad instructions were indeed overwritten with | 72 sanity check that bad instructions were indeed overwritten with |
70 allowable HLTs. */ | 73 allowable HLTs. */ |
71 status = validator->Validate(guest_addr, data, size, | 74 status = validator->Validate(guest_addr, data, size, |
72 TRUE, /* stub out */ | 75 TRUE, /* stub out */ |
73 FALSE, /* text is not read-only */ | 76 FALSE, /* text is not read-only */ |
74 nap->cpu_features, | 77 nap->cpu_features, |
| 78 metadata, |
75 cache); | 79 cache); |
76 } | 80 } |
77 if (status == NaClValidationSucceeded) { | 81 if (status == NaClValidationSucceeded) { |
78 /* Fixed feature CPU mode implies read-only. */ | 82 /* Fixed feature CPU mode implies read-only. */ |
79 int readonly_text = nap->fixed_feature_cpu_mode; | 83 int readonly_text = nap->fixed_feature_cpu_mode; |
80 status = validator->Validate(guest_addr, data, size, | 84 status = validator->Validate(guest_addr, data, size, |
81 FALSE, /* do not stub out */ | 85 FALSE, /* do not stub out */ |
82 readonly_text, | 86 readonly_text, |
83 nap->cpu_features, | 87 nap->cpu_features, |
| 88 metadata, |
84 cache); | 89 cache); |
85 } | 90 } |
86 return NaClValidateStatus(status); | 91 return NaClValidateStatus(status); |
87 } | 92 } |
88 | 93 |
89 int NaClValidateCodeReplacement(struct NaClApp *nap, uintptr_t guest_addr, | 94 int NaClValidateCodeReplacement(struct NaClApp *nap, uintptr_t guest_addr, |
90 uint8_t *data_old, uint8_t *data_new, | 95 uint8_t *data_old, uint8_t *data_new, |
91 size_t size) { | 96 size_t size) { |
92 if (nap->validator_stub_out_mode) return LOAD_BAD_FILE; | 97 if (nap->validator_stub_out_mode) return LOAD_BAD_FILE; |
93 if (nap->fixed_feature_cpu_mode) return LOAD_BAD_FILE; | 98 if (nap->fixed_feature_cpu_mode) return LOAD_BAD_FILE; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 endp = nap->mem_start + nap->static_text_end; | 145 endp = nap->mem_start + nap->static_text_end; |
141 regionsize = endp - memp; | 146 regionsize = endp - memp; |
142 if (endp < memp) { | 147 if (endp < memp) { |
143 return LOAD_NO_MEMORY; | 148 return LOAD_NO_MEMORY; |
144 } | 149 } |
145 | 150 |
146 if (nap->skip_validator) { | 151 if (nap->skip_validator) { |
147 NaClLog(LOG_ERROR, "VALIDATION SKIPPED.\n"); | 152 NaClLog(LOG_ERROR, "VALIDATION SKIPPED.\n"); |
148 return LOAD_OK; | 153 return LOAD_OK; |
149 } else { | 154 } else { |
| 155 /* TODO(ncbray) metadata for the main image. */ |
150 rcode = NaClValidateCode(nap, NACL_TRAMPOLINE_END, | 156 rcode = NaClValidateCode(nap, NACL_TRAMPOLINE_END, |
151 (uint8_t *) memp, regionsize); | 157 (uint8_t *) memp, regionsize, NULL); |
152 if (LOAD_OK != rcode) { | 158 if (LOAD_OK != rcode) { |
153 if (nap->ignore_validator_result) { | 159 if (nap->ignore_validator_result) { |
154 NaClLog(LOG_ERROR, "VALIDATION FAILED: continuing anyway...\n"); | 160 NaClLog(LOG_ERROR, "VALIDATION FAILED: continuing anyway...\n"); |
155 rcode = LOAD_OK; | 161 rcode = LOAD_OK; |
156 } else { | 162 } else { |
157 NaClLog(LOG_ERROR, "VALIDATION FAILED.\n"); | 163 NaClLog(LOG_ERROR, "VALIDATION FAILED.\n"); |
158 NaClLog(LOG_ERROR, | 164 NaClLog(LOG_ERROR, |
159 "Run sel_ldr in debug mode to ignore validation failure.\n"); | 165 "Run sel_ldr in debug mode to ignore validation failure.\n"); |
160 NaClLog(LOG_ERROR, | 166 NaClLog(LOG_ERROR, |
161 "Run ncval <module-name> for validation error details.\n"); | 167 "Run ncval <module-name> for validation error details.\n"); |
162 rcode = LOAD_VALIDATION_FAILED; | 168 rcode = LOAD_VALIDATION_FAILED; |
163 } | 169 } |
164 } | 170 } |
165 } | 171 } |
166 return rcode; | 172 return rcode; |
167 } | 173 } |
OLD | NEW |