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/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) ( |
| 31 uintptr_t, uint8_t*, size_t, int, int, |
| 32 const NaClCPUFeatures*, struct NaClValidationCache*); |
| 33 |
| 34 static ValidateFunc NaClSelectValidator(struct NaClApp *nap) { |
| 35 ValidateFunc ret = NACL_SUBARCH_NAME(ApplyValidator, |
| 36 NACL_TARGET_ARCH, NACL_TARGET_SUBARCH); |
| 37 #ifdef __arm__ |
| 38 UNREFERENCED_PARAMETER(nap); |
| 39 #else |
| 40 if (nap->enable_dfa_validator) { |
| 41 ret = NACL_SUBARCH_NAME(ApplyDfaValidator, |
| 42 NACL_TARGET_ARCH, NACL_TARGET_SUBARCH); |
| 43 } |
| 44 #endif |
| 45 return ret; |
| 46 } |
| 47 |
30 int NaClValidateCode(struct NaClApp *nap, uintptr_t guest_addr, | 48 int NaClValidateCode(struct NaClApp *nap, uintptr_t guest_addr, |
31 uint8_t *data, size_t size) { | 49 uint8_t *data, size_t size) { |
32 NaClValidationStatus status = NaClValidationSucceeded; | 50 NaClValidationStatus status = NaClValidationSucceeded; |
33 | |
34 struct NaClValidationCache *cache = nap->validation_cache; | 51 struct NaClValidationCache *cache = nap->validation_cache; |
| 52 ValidateFunc validate_func = NaClSelectValidator(nap); |
35 | 53 |
36 if (size < kMinimumCachedCodeSize) { | 54 if (size < kMinimumCachedCodeSize) { |
37 /* | 55 /* |
38 * Don't cache the validation of small code chunks for three reasons: | 56 * Don't cache the validation of small code chunks for three reasons: |
39 * 1) The size of the validation cache will be bounded. Cache entries are | 57 * 1) The size of the validation cache will be bounded. Cache entries are |
40 * better used for bigger code. | 58 * better used for bigger code. |
41 * 2) The per-transaction overhead of validation caching is more noticeable | 59 * 2) The per-transaction overhead of validation caching is more noticeable |
42 * for small code. | 60 * for small code. |
43 * 3) JITs tend to generate a lot of small code chunks, and JITed code may | 61 * 3) JITs tend to generate a lot of small code chunks, and JITed code may |
44 * never be seen again. Currently code size is the best mechanism we | 62 * never be seen again. Currently code size is the best mechanism we |
(...skipping 14 matching lines...) Expand all Loading... |
59 NaClLog(LOG_FATAL, | 77 NaClLog(LOG_FATAL, |
60 "stub_out_mode and fixed_feature_cpu_mode are incompatible\n"); | 78 "stub_out_mode and fixed_feature_cpu_mode are incompatible\n"); |
61 return LOAD_VALIDATION_FAILED; | 79 return LOAD_VALIDATION_FAILED; |
62 } | 80 } |
63 if (nap->validator_stub_out_mode) { | 81 if (nap->validator_stub_out_mode) { |
64 /* Validation caching is currently incompatible with stubout. */ | 82 /* Validation caching is currently incompatible with stubout. */ |
65 cache = NULL; | 83 cache = NULL; |
66 /* In stub out mode, we do two passes. The second pass acts as a | 84 /* In stub out mode, we do two passes. The second pass acts as a |
67 sanity check that bad instructions were indeed overwritten with | 85 sanity check that bad instructions were indeed overwritten with |
68 allowable HLTs. */ | 86 allowable HLTs. */ |
69 status = NACL_SUBARCH_NAME(ApplyValidator, | 87 status = validate_func(guest_addr, data, size, |
70 NACL_TARGET_ARCH, | 88 TRUE, /* stub out */ |
71 NACL_TARGET_SUBARCH)( | 89 FALSE, /* text is not read-only */ |
72 guest_addr, data, size, | 90 &nap->cpu_features, |
73 TRUE, /* stub out */ | 91 cache); |
74 FALSE, /* text is not read-only */ | |
75 &nap->cpu_features, | |
76 cache); | |
77 } | 92 } |
78 if (status == NaClValidationSucceeded) { | 93 if (status == NaClValidationSucceeded) { |
79 /* Fixed feature CPU mode implies read-only */ | 94 /* Fixed feature CPU mode implies read-only. */ |
80 int readonly_text = nap->fixed_feature_cpu_mode; | 95 int readonly_text = nap->fixed_feature_cpu_mode; |
81 status = NACL_SUBARCH_NAME(ApplyValidator, | 96 status = validate_func(guest_addr, data, size, |
82 NACL_TARGET_ARCH, | 97 FALSE, /* do not stub out */ |
83 NACL_TARGET_SUBARCH)( | 98 readonly_text, |
84 guest_addr, data, size, | 99 &nap->cpu_features, |
85 FALSE, /* do not stub out */ | 100 cache); |
86 readonly_text, | |
87 &nap->cpu_features, | |
88 cache); | |
89 } | 101 } |
90 return NaClValidateStatus(status); | 102 return NaClValidateStatus(status); |
91 } | 103 } |
92 | 104 |
93 int NaClValidateCodeReplacement(struct NaClApp *nap, uintptr_t guest_addr, | 105 int NaClValidateCodeReplacement(struct NaClApp *nap, uintptr_t guest_addr, |
94 uint8_t *data_old, uint8_t *data_new, | 106 uint8_t *data_old, uint8_t *data_new, |
95 size_t size) { | 107 size_t size) { |
96 if (nap->validator_stub_out_mode) return LOAD_BAD_FILE; | 108 if (nap->validator_stub_out_mode) return LOAD_BAD_FILE; |
97 if (nap->fixed_feature_cpu_mode) return LOAD_BAD_FILE; | 109 if (nap->fixed_feature_cpu_mode) return LOAD_BAD_FILE; |
98 | 110 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 NaClLog(LOG_ERROR, | 164 NaClLog(LOG_ERROR, |
153 "Run sel_ldr in debug mode to ignore validation failure.\n"); | 165 "Run sel_ldr in debug mode to ignore validation failure.\n"); |
154 NaClLog(LOG_ERROR, | 166 NaClLog(LOG_ERROR, |
155 "Run ncval <module-name> for validation error details.\n"); | 167 "Run ncval <module-name> for validation error details.\n"); |
156 rcode = LOAD_VALIDATION_FAILED; | 168 rcode = LOAD_VALIDATION_FAILED; |
157 } | 169 } |
158 } | 170 } |
159 } | 171 } |
160 return rcode; | 172 return rcode; |
161 } | 173 } |
OLD | NEW |