Chromium Code Reviews| 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 |