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/shared/utils/types.h" | |
| 8 #include "native_client/src/trusted/service_runtime/sel_ldr.h" | 9 #include "native_client/src/trusted/service_runtime/sel_ldr.h" |
| 9 #include "native_client/src/trusted/validator/ncvalidate.h" | 10 #include "native_client/src/trusted/validator/ncvalidate.h" |
| 11 #include "native_client/src/trusted/validator_x86/nccopycode.h" | |
| 10 | 12 |
| 11 const size_t kMinimumCachedCodeSize = 40000; | 13 const size_t kMinimumCachedCodeSize = 40000; |
| 12 | 14 |
| 13 /* Translate validation status to values wanted by sel_ldr. */ | 15 /* Translate validation status to values wanted by sel_ldr. */ |
| 14 static int NaClValidateStatus(NaClValidationStatus status) { | 16 static int NaClValidateStatus(NaClValidationStatus status) { |
| 15 switch (status) { | 17 switch (status) { |
| 16 case NaClValidationSucceeded: | 18 case NaClValidationSucceeded: |
| 17 return LOAD_OK; | 19 return LOAD_OK; |
| 18 case NaClValidationFailedOutOfMemory: | 20 case NaClValidationFailedOutOfMemory: |
| 19 /* Note: this is confusing, but is what sel_ldr is expecting. */ | 21 /* Note: this is confusing, but is what sel_ldr is expecting. */ |
| 20 return LOAD_BAD_FILE; | 22 return LOAD_BAD_FILE; |
| 21 case NaClValidationFailed: | 23 case NaClValidationFailed: |
| 22 case NaClValidationFailedNotImplemented: | 24 case NaClValidationFailedNotImplemented: |
| 23 case NaClValidationFailedCpuNotSupported: | 25 case NaClValidationFailedCpuNotSupported: |
| 24 case NaClValidationFailedSegmentationIssue: | 26 case NaClValidationFailedSegmentationIssue: |
| 25 default: | 27 default: |
| 26 return LOAD_VALIDATION_FAILED; | 28 return LOAD_VALIDATION_FAILED; |
| 27 } | 29 } |
| 28 } | 30 } |
| 29 | 31 |
| 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 /* Avoid linking two validators into Chromium to keep download size small. */ | |
| 38 #if defined(__arm__) || !defined(NACL_STANDALONE) | |
| 39 UNREFERENCED_PARAMETER(nap); | |
| 40 #else | |
| 41 if (nap->enable_dfa_validator) { | |
| 42 ret = NACL_SUBARCH_NAME(ApplyDfaValidator, | |
| 43 NACL_TARGET_ARCH, NACL_TARGET_SUBARCH); | |
| 44 } | |
| 45 #endif | |
| 46 return ret; | |
| 47 } | |
| 48 | |
| 49 int NaClValidateCode(struct NaClApp *nap, uintptr_t guest_addr, | 32 int NaClValidateCode(struct NaClApp *nap, uintptr_t guest_addr, |
| 50 uint8_t *data, size_t size) { | 33 uint8_t *data, size_t size) { |
| 51 NaClValidationStatus status = NaClValidationSucceeded; | 34 NaClValidationStatus status = NaClValidationSucceeded; |
| 52 struct NaClValidationCache *cache = nap->validation_cache; | 35 struct NaClValidationCache *cache = nap->validation_cache; |
| 53 ValidateFunc validate_func = NaClSelectValidator(nap); | 36 const struct NaClValidatorInterface *validator = nap->validator; |
| 54 | 37 |
| 55 if (size < kMinimumCachedCodeSize) { | 38 if (size < kMinimumCachedCodeSize) { |
| 56 /* | 39 /* |
| 57 * Don't cache the validation of small code chunks for three reasons: | 40 * Don't cache the validation of small code chunks for three reasons: |
| 58 * 1) The size of the validation cache will be bounded. Cache entries are | 41 * 1) The size of the validation cache will be bounded. Cache entries are |
| 59 * better used for bigger code. | 42 * better used for bigger code. |
| 60 * 2) The per-transaction overhead of validation caching is more noticeable | 43 * 2) The per-transaction overhead of validation caching is more noticeable |
| 61 * for small code. | 44 * for small code. |
| 62 * 3) JITs tend to generate a lot of small code chunks, and JITed code may | 45 * 3) JITs tend to generate a lot of small code chunks, and JITed code may |
| 63 * never be seen again. Currently code size is the best mechanism we | 46 * never be seen again. Currently code size is the best mechanism we |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 78 NaClLog(LOG_FATAL, | 61 NaClLog(LOG_FATAL, |
| 79 "stub_out_mode and fixed_feature_cpu_mode are incompatible\n"); | 62 "stub_out_mode and fixed_feature_cpu_mode are incompatible\n"); |
| 80 return LOAD_VALIDATION_FAILED; | 63 return LOAD_VALIDATION_FAILED; |
| 81 } | 64 } |
| 82 if (nap->validator_stub_out_mode) { | 65 if (nap->validator_stub_out_mode) { |
| 83 /* Validation caching is currently incompatible with stubout. */ | 66 /* Validation caching is currently incompatible with stubout. */ |
| 84 cache = NULL; | 67 cache = NULL; |
| 85 /* In stub out mode, we do two passes. The second pass acts as a | 68 /* In stub out mode, we do two passes. The second pass acts as a |
| 86 sanity check that bad instructions were indeed overwritten with | 69 sanity check that bad instructions were indeed overwritten with |
| 87 allowable HLTs. */ | 70 allowable HLTs. */ |
| 88 status = validate_func(guest_addr, data, size, | 71 status = validator->Validate(guest_addr, data, size, |
| 89 TRUE, /* stub out */ | 72 TRUE, /* stub out */ |
| 90 FALSE, /* text is not read-only */ | 73 FALSE, /* text is not read-only */ |
| 91 &nap->cpu_features, | 74 &nap->cpu_features, |
| 92 cache); | 75 cache); |
| 93 } | 76 } |
| 94 if (status == NaClValidationSucceeded) { | 77 if (status == NaClValidationSucceeded) { |
| 95 /* Fixed feature CPU mode implies read-only. */ | 78 /* Fixed feature CPU mode implies read-only. */ |
| 96 int readonly_text = nap->fixed_feature_cpu_mode; | 79 int readonly_text = nap->fixed_feature_cpu_mode; |
| 97 status = validate_func(guest_addr, data, size, | 80 status = validator->Validate(guest_addr, data, size, |
| 98 FALSE, /* do not stub out */ | 81 FALSE, /* do not stub out */ |
| 99 readonly_text, | 82 readonly_text, |
| 100 &nap->cpu_features, | 83 &nap->cpu_features, |
| 101 cache); | 84 cache); |
| 102 } | 85 } |
| 103 return NaClValidateStatus(status); | 86 return NaClValidateStatus(status); |
| 104 } | 87 } |
| 105 | 88 |
| 106 int NaClValidateCodeReplacement(struct NaClApp *nap, uintptr_t guest_addr, | 89 int NaClValidateCodeReplacement(struct NaClApp *nap, uintptr_t guest_addr, |
| 107 uint8_t *data_old, uint8_t *data_new, | 90 uint8_t *data_old, uint8_t *data_new, |
| 108 size_t size) { | 91 size_t size) { |
| 109 if (nap->validator_stub_out_mode) return LOAD_BAD_FILE; | 92 if (nap->validator_stub_out_mode) return LOAD_BAD_FILE; |
| 110 if (nap->fixed_feature_cpu_mode) return LOAD_BAD_FILE; | 93 if (nap->fixed_feature_cpu_mode) return LOAD_BAD_FILE; |
| 111 | 94 |
| 112 if ((guest_addr % nap->bundle_size) != 0 || | 95 if ((guest_addr % nap->bundle_size) != 0 || |
| 113 (size % nap->bundle_size) != 0) { | 96 (size % nap->bundle_size) != 0) { |
| 114 return LOAD_BAD_FILE; | 97 return LOAD_BAD_FILE; |
| 115 } | 98 } |
| 116 | 99 |
| 117 return NaClValidateStatus( | 100 return NaClValidateStatus(nap->validator->ValidateCodeReplacement( |
| 118 NACL_SUBARCH_NAME(ApplyValidatorCodeReplacement, | 101 guest_addr, data_old, data_new, size, &nap->cpu_features)); |
| 119 NACL_TARGET_ARCH, | |
| 120 NACL_TARGET_SUBARCH) | |
| 121 (guest_addr, data_old, data_new, size, &nap->cpu_features)); | |
| 122 } | 102 } |
| 123 | 103 |
| 124 int NaClCopyCode(struct NaClApp *nap, uintptr_t guest_addr, | 104 int NaClCopyCode(struct NaClApp *nap, uintptr_t guest_addr, |
| 125 uint8_t *data_old, uint8_t *data_new, | 105 uint8_t *data_old, uint8_t *data_new, |
| 126 size_t size) { | 106 size_t size) { |
| 107 #ifdef __arm__ | |
|
Nick Bray
2012/05/25 06:41:21
Add TODO for library refactoring, file issue, cc o
| |
| 108 NaClCopyInstructionFunc copy_func = NULL; | |
| 109 #else | |
| 110 NaClCopyInstructionFunc copy_func = NaClCopyInstruction_x86; | |
| 111 #endif | |
| 127 /* Fixed-feature mode disables any code copying for now. Currently | 112 /* Fixed-feature mode disables any code copying for now. Currently |
| 128 * the only use of NaClCodeCopy() seems to be for dynamic code | 113 * the only use of NaClCodeCopy() seems to be for dynamic code |
| 129 * modification, which should fail in NaClValidateCodeReplacement() | 114 * modification, which should fail in NaClValidateCodeReplacement() |
| 130 * before reaching this. | 115 * before reaching this. |
| 131 */ | 116 */ |
| 132 if (nap->fixed_feature_cpu_mode) return LOAD_BAD_FILE; | 117 if (nap->fixed_feature_cpu_mode) return LOAD_BAD_FILE; |
| 133 return NaClValidateStatus( | 118 return NaClValidateStatus(nap->validator->CopyCode( |
| 134 NACL_SUBARCH_NAME(ApplyValidatorCopy, | 119 guest_addr, data_old, data_new, size, &nap->cpu_features, copy_func)); |
| 135 NACL_TARGET_ARCH, | |
| 136 NACL_TARGET_SUBARCH) | |
| 137 (guest_addr, data_old, data_new, size, &nap->cpu_features)); | |
| 138 } | 120 } |
| 139 | 121 |
| 140 NaClErrorCode NaClValidateImage(struct NaClApp *nap) { | 122 NaClErrorCode NaClValidateImage(struct NaClApp *nap) { |
| 141 uintptr_t memp; | 123 uintptr_t memp; |
| 142 uintptr_t endp; | 124 uintptr_t endp; |
| 143 size_t regionsize; | 125 size_t regionsize; |
| 144 NaClErrorCode rcode; | 126 NaClErrorCode rcode; |
| 145 | 127 |
| 146 memp = nap->mem_start + NACL_TRAMPOLINE_END; | 128 memp = nap->mem_start + NACL_TRAMPOLINE_END; |
| 147 endp = nap->mem_start + nap->static_text_end; | 129 endp = nap->mem_start + nap->static_text_end; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 165 NaClLog(LOG_ERROR, | 147 NaClLog(LOG_ERROR, |
| 166 "Run sel_ldr in debug mode to ignore validation failure.\n"); | 148 "Run sel_ldr in debug mode to ignore validation failure.\n"); |
| 167 NaClLog(LOG_ERROR, | 149 NaClLog(LOG_ERROR, |
| 168 "Run ncval <module-name> for validation error details.\n"); | 150 "Run ncval <module-name> for validation error details.\n"); |
| 169 rcode = LOAD_VALIDATION_FAILED; | 151 rcode = LOAD_VALIDATION_FAILED; |
| 170 } | 152 } |
| 171 } | 153 } |
| 172 } | 154 } |
| 173 return rcode; | 155 return rcode; |
| 174 } | 156 } |
| OLD | NEW |