| 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 |