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) (enum NaClSBKind, | |
Nick Bray
2012/04/19 23:11:08
FYI, removing SBKind is next on my hit list - but
pasko-google - do not use
2012/04/20 14:30:38
not a problem
| |
31 uintptr_t, uint8_t*, size_t, int, int, const NaClCPUFeatures*, | |
32 struct NaClValidationCache*); | |
33 | |
30 int NaClValidateCode(struct NaClApp *nap, uintptr_t guest_addr, | 34 int NaClValidateCode(struct NaClApp *nap, uintptr_t guest_addr, |
31 uint8_t *data, size_t size) { | 35 uint8_t *data, size_t size) { |
32 NaClValidationStatus status = NaClValidationSucceeded; | 36 NaClValidationStatus status = NaClValidationSucceeded; |
33 enum NaClSBKind sb_kind = NACL_SB_DEFAULT; | 37 enum NaClSBKind sb_kind = NACL_SB_DEFAULT; |
34 | 38 const ValidateFunc cur_validate_func = NACL_SUBARCH_NAME(ApplyValidator, |
39 NACL_TARGET_ARCH, | |
40 NACL_TARGET_SUBARCH); | |
41 const ValidateFunc dfa_validate_func = NACL_SUBARCH_NAME(ApplyDfaValidator, | |
Nick Bray
2012/04/19 23:11:08
Don't stub this out on ARM, just ifdef out the ref
pasko-google - do not use
2012/04/20 14:30:38
across all trusted code I do not see a single #ifd
| |
42 NACL_TARGET_ARCH, | |
43 NACL_TARGET_SUBARCH); | |
44 ValidateFunc validate_func = cur_validate_func; | |
35 struct NaClValidationCache *cache = nap->validation_cache; | 45 struct NaClValidationCache *cache = nap->validation_cache; |
36 | 46 |
37 if (size < kMinimumCachedCodeSize) { | 47 if (size < kMinimumCachedCodeSize) { |
38 /* | 48 /* |
39 * Don't cache the validation of small code chunks for three reasons: | 49 * Don't cache the validation of small code chunks for three reasons: |
40 * 1) The size of the validation cache will be bounded. Cache entries are | 50 * 1) The size of the validation cache will be bounded. Cache entries are |
41 * better used for bigger code. | 51 * better used for bigger code. |
42 * 2) The per-transaction overhead of validation caching is more noticeable | 52 * 2) The per-transaction overhead of validation caching is more noticeable |
43 * for small code. | 53 * for small code. |
44 * 3) JITs tend to generate a lot of small code chunks, and JITed code may | 54 * 3) JITs tend to generate a lot of small code chunks, and JITed code may |
45 * never be seen again. Currently code size is the best mechanism we | 55 * never be seen again. Currently code size is the best mechanism we |
46 * have for heuristically distinguishing between JIT and static code. | 56 * have for heuristically distinguishing between JIT and static code. |
47 * (In practice most Mono JIT blocks are less than 1k, and a quick look | 57 * (In practice most Mono JIT blocks are less than 1k, and a quick look |
48 * didn't show any above 35k.) | 58 * didn't show any above 35k.) |
49 * The choice of what constitutes "small" is arbitrary, and should be | 59 * The choice of what constitutes "small" is arbitrary, and should be |
50 * empirically tuned. | 60 * empirically tuned. |
51 * TODO(ncbray) let the syscall specify if the code is cached or not. | 61 * TODO(ncbray) let the syscall specify if the code is cached or not. |
52 */ | 62 */ |
53 cache = NULL; | 63 cache = NULL; |
54 } | 64 } |
55 | 65 |
56 /* As fixed feature mode implies the text should be readonly, and | 66 /* As fixed feature mode implies the text should be readonly, and |
57 * stubout mode implies updating the text, disallow their use together. | 67 * stubout mode implies updating the text, disallow their use together. |
58 */ | 68 */ |
59 if (nap->validator_stub_out_mode && nap->fixed_feature_cpu_mode) { | 69 if (nap->validator_stub_out_mode && nap->fixed_feature_cpu_mode) { |
60 NaClLog(LOG_FATAL, | 70 NaClLog(LOG_FATAL, |
61 "stub_out_mode and fixed_feature_cpu_mode are incompatible\n"); | 71 "stub_out_mode and fixed_feature_cpu_mode are incompatible\n"); |
62 return LOAD_VALIDATION_FAILED; | 72 return LOAD_VALIDATION_FAILED; |
63 } | 73 } |
74 | |
75 if (nap->enable_dfa_validator) { | |
Nick Bray
2012/04/19 23:11:08
Move this up to keep the validate_func selection g
pasko-google - do not use
2012/04/20 14:30:38
For the grouping I'd better move the validate_func
| |
76 validate_func = dfa_validate_func; | |
77 } | |
78 | |
64 if (nap->validator_stub_out_mode) { | 79 if (nap->validator_stub_out_mode) { |
65 /* Validation caching is currently incompatible with stubout. */ | 80 /* Validation caching is currently incompatible with stubout. */ |
66 cache = NULL; | 81 cache = NULL; |
67 /* In stub out mode, we do two passes. The second pass acts as a | 82 /* In stub out mode, we do two passes. The second pass acts as a |
68 sanity check that bad instructions were indeed overwritten with | 83 sanity check that bad instructions were indeed overwritten with |
69 allowable HLTs. */ | 84 allowable HLTs. */ |
70 status = NACL_SUBARCH_NAME(ApplyValidator, | 85 status = validate_func(sb_kind, |
71 NACL_TARGET_ARCH, | 86 guest_addr, data, size, |
72 NACL_TARGET_SUBARCH)( | 87 TRUE, /* stub out */ |
73 sb_kind, | 88 FALSE, /* text is not read-only */ |
74 guest_addr, data, size, | 89 &nap->cpu_features, |
75 TRUE, /* stub out */ | 90 cache); |
76 FALSE, /* text is not read-only */ | |
77 &nap->cpu_features, | |
78 cache); | |
79 } | 91 } |
80 if (status == NaClValidationSucceeded) { | 92 if (status == NaClValidationSucceeded) { |
81 /* Fixed feature CPU mode implies read-only */ | 93 /* Fixed feature CPU mode implies read-only. */ |
82 int readonly_text = nap->fixed_feature_cpu_mode; | 94 int readonly_text = nap->fixed_feature_cpu_mode; |
83 status = NACL_SUBARCH_NAME(ApplyValidator, | 95 status = validate_func(sb_kind, |
84 NACL_TARGET_ARCH, | 96 guest_addr, data, size, |
85 NACL_TARGET_SUBARCH)( | 97 FALSE, /* do not stub out */ |
86 sb_kind, | 98 readonly_text, |
87 guest_addr, data, size, | 99 &nap->cpu_features, |
88 FALSE, /* do not stub out */ | 100 cache); |
89 readonly_text, | |
90 &nap->cpu_features, | |
91 cache); | |
92 } | 101 } |
93 return NaClValidateStatus(status); | 102 return NaClValidateStatus(status); |
94 } | 103 } |
95 | 104 |
96 int NaClValidateCodeReplacement(struct NaClApp *nap, uintptr_t guest_addr, | 105 int NaClValidateCodeReplacement(struct NaClApp *nap, uintptr_t guest_addr, |
97 uint8_t *data_old, uint8_t *data_new, | 106 uint8_t *data_old, uint8_t *data_new, |
98 size_t size) { | 107 size_t size) { |
99 enum NaClSBKind sb_kind = NACL_SB_DEFAULT; | 108 enum NaClSBKind sb_kind = NACL_SB_DEFAULT; |
100 if (nap->validator_stub_out_mode) return LOAD_BAD_FILE; | 109 if (nap->validator_stub_out_mode) return LOAD_BAD_FILE; |
101 if (nap->fixed_feature_cpu_mode) return LOAD_BAD_FILE; | 110 if (nap->fixed_feature_cpu_mode) return LOAD_BAD_FILE; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
157 NaClLog(LOG_ERROR, | 166 NaClLog(LOG_ERROR, |
158 "Run sel_ldr in debug mode to ignore validation failure.\n"); | 167 "Run sel_ldr in debug mode to ignore validation failure.\n"); |
159 NaClLog(LOG_ERROR, | 168 NaClLog(LOG_ERROR, |
160 "Run ncval <module-name> for validation error details.\n"); | 169 "Run ncval <module-name> for validation error details.\n"); |
161 rcode = LOAD_VALIDATION_FAILED; | 170 rcode = LOAD_VALIDATION_FAILED; |
162 } | 171 } |
163 } | 172 } |
164 } | 173 } |
165 return rcode; | 174 return rcode; |
166 } | 175 } |
OLD | NEW |