| 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/include/concurrency_ops.h" | 7 #include "native_client/src/include/concurrency_ops.h" |
| 8 #include "native_client/src/shared/platform/nacl_log.h" | 8 #include "native_client/src/shared/platform/nacl_log.h" |
| 9 #include "native_client/src/shared/utils/types.h" | 9 #include "native_client/src/shared/utils/types.h" |
| 10 #include "native_client/src/trusted/service_runtime/sel_ldr.h" | 10 #include "native_client/src/trusted/service_runtime/sel_ldr.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 case NaClValidationFailed: | 23 case NaClValidationFailed: |
| 24 case NaClValidationFailedNotImplemented: | 24 case NaClValidationFailedNotImplemented: |
| 25 case NaClValidationFailedCpuNotSupported: | 25 case NaClValidationFailedCpuNotSupported: |
| 26 case NaClValidationFailedSegmentationIssue: | 26 case NaClValidationFailedSegmentationIssue: |
| 27 default: | 27 default: |
| 28 return LOAD_VALIDATION_FAILED; | 28 return LOAD_VALIDATION_FAILED; |
| 29 } | 29 } |
| 30 } | 30 } |
| 31 | 31 |
| 32 int NaClValidateCode(struct NaClApp *nap, uintptr_t guest_addr, | 32 int NaClValidateCode(struct NaClApp *nap, uintptr_t guest_addr, |
| 33 uint8_t *data, size_t size) { | 33 uint8_t *data, size_t size, |
| 34 const struct NaClValidationMetadata *metadata) { |
| 34 NaClValidationStatus status = NaClValidationSucceeded; | 35 NaClValidationStatus status = NaClValidationSucceeded; |
| 35 struct NaClValidationCache *cache = nap->validation_cache; | 36 struct NaClValidationCache *cache = nap->validation_cache; |
| 36 const struct NaClValidatorInterface *validator = nap->validator; | 37 const struct NaClValidatorInterface *validator = nap->validator; |
| 37 | 38 |
| 38 if (size < kMinimumCachedCodeSize) { | 39 if (size < kMinimumCachedCodeSize) { |
| 39 /* | 40 /* |
| 40 * Don't cache the validation of small code chunks for three reasons: | 41 * Don't cache the validation of small code chunks for three reasons: |
| 41 * 1) The size of the validation cache will be bounded. Cache entries are | 42 * 1) The size of the validation cache will be bounded. Cache entries are |
| 42 * better used for bigger code. | 43 * better used for bigger code. |
| 43 * 2) The per-transaction overhead of validation caching is more noticeable | 44 * 2) The per-transaction overhead of validation caching is more noticeable |
| 44 * for small code. | 45 * for small code. |
| 45 * 3) JITs tend to generate a lot of small code chunks, and JITed code may | 46 * 3) JITs tend to generate a lot of small code chunks, and JITed code may |
| 46 * never be seen again. Currently code size is the best mechanism we | 47 * never be seen again. Currently code size is the best mechanism we |
| 47 * have for heuristically distinguishing between JIT and static code. | 48 * have for heuristically distinguishing between JIT and static code. |
| 48 * (In practice most Mono JIT blocks are less than 1k, and a quick look | 49 * (In practice most Mono JIT blocks are less than 1k, and a quick look |
| 49 * didn't show any above 35k.) | 50 * didn't show any above 35k.) |
| 50 * The choice of what constitutes "small" is arbitrary, and should be | 51 * The choice of what constitutes "small" is arbitrary, and should be |
| 51 * empirically tuned. | 52 * empirically tuned. |
| 52 * TODO(ncbray) let the syscall specify if the code is cached or not. | 53 * TODO(ncbray) let the syscall specify if the code is cached or not. |
| 53 */ | 54 */ |
| 55 metadata = NULL; |
| 54 cache = NULL; | 56 cache = NULL; |
| 55 } | 57 } |
| 56 | 58 |
| 57 /* As fixed feature mode implies the text should be readonly, and | 59 /* As fixed feature mode implies the text should be readonly, and |
| 58 * stubout mode implies updating the text, disallow their use together. | 60 * stubout mode implies updating the text, disallow their use together. |
| 59 */ | 61 */ |
| 60 if (nap->validator_stub_out_mode && nap->fixed_feature_cpu_mode) { | 62 if (nap->validator_stub_out_mode && nap->fixed_feature_cpu_mode) { |
| 61 NaClLog(LOG_FATAL, | 63 NaClLog(LOG_FATAL, |
| 62 "stub_out_mode and fixed_feature_cpu_mode are incompatible\n"); | 64 "stub_out_mode and fixed_feature_cpu_mode are incompatible\n"); |
| 63 return LOAD_VALIDATION_FAILED; | 65 return LOAD_VALIDATION_FAILED; |
| 64 } | 66 } |
| 65 if (nap->validator_stub_out_mode) { | 67 if (nap->validator_stub_out_mode) { |
| 66 /* Validation caching is currently incompatible with stubout. */ | 68 /* Validation caching is currently incompatible with stubout. */ |
| 69 metadata = NULL; |
| 67 cache = NULL; | 70 cache = NULL; |
| 68 /* In stub out mode, we do two passes. The second pass acts as a | 71 /* In stub out mode, we do two passes. The second pass acts as a |
| 69 sanity check that bad instructions were indeed overwritten with | 72 sanity check that bad instructions were indeed overwritten with |
| 70 allowable HLTs. */ | 73 allowable HLTs. */ |
| 71 status = validator->Validate(guest_addr, data, size, | 74 status = validator->Validate(guest_addr, data, size, |
| 72 TRUE, /* stub out */ | 75 TRUE, /* stub out */ |
| 73 FALSE, /* text is not read-only */ | 76 FALSE, /* text is not read-only */ |
| 74 nap->cpu_features, | 77 nap->cpu_features, |
| 78 metadata, |
| 75 cache); | 79 cache); |
| 76 } | 80 } |
| 77 if (status == NaClValidationSucceeded) { | 81 if (status == NaClValidationSucceeded) { |
| 78 /* Fixed feature CPU mode implies read-only. */ | 82 /* Fixed feature CPU mode implies read-only. */ |
| 79 int readonly_text = nap->fixed_feature_cpu_mode; | 83 int readonly_text = nap->fixed_feature_cpu_mode; |
| 80 status = validator->Validate(guest_addr, data, size, | 84 status = validator->Validate(guest_addr, data, size, |
| 81 FALSE, /* do not stub out */ | 85 FALSE, /* do not stub out */ |
| 82 readonly_text, | 86 readonly_text, |
| 83 nap->cpu_features, | 87 nap->cpu_features, |
| 88 metadata, |
| 84 cache); | 89 cache); |
| 85 } | 90 } |
| 86 return NaClValidateStatus(status); | 91 return NaClValidateStatus(status); |
| 87 } | 92 } |
| 88 | 93 |
| 89 int NaClValidateCodeReplacement(struct NaClApp *nap, uintptr_t guest_addr, | 94 int NaClValidateCodeReplacement(struct NaClApp *nap, uintptr_t guest_addr, |
| 90 uint8_t *data_old, uint8_t *data_new, | 95 uint8_t *data_old, uint8_t *data_new, |
| 91 size_t size) { | 96 size_t size) { |
| 92 if (nap->validator_stub_out_mode) return LOAD_BAD_FILE; | 97 if (nap->validator_stub_out_mode) return LOAD_BAD_FILE; |
| 93 if (nap->fixed_feature_cpu_mode) return LOAD_BAD_FILE; | 98 if (nap->fixed_feature_cpu_mode) return LOAD_BAD_FILE; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 endp = nap->mem_start + nap->static_text_end; | 145 endp = nap->mem_start + nap->static_text_end; |
| 141 regionsize = endp - memp; | 146 regionsize = endp - memp; |
| 142 if (endp < memp) { | 147 if (endp < memp) { |
| 143 return LOAD_NO_MEMORY; | 148 return LOAD_NO_MEMORY; |
| 144 } | 149 } |
| 145 | 150 |
| 146 if (nap->skip_validator) { | 151 if (nap->skip_validator) { |
| 147 NaClLog(LOG_ERROR, "VALIDATION SKIPPED.\n"); | 152 NaClLog(LOG_ERROR, "VALIDATION SKIPPED.\n"); |
| 148 return LOAD_OK; | 153 return LOAD_OK; |
| 149 } else { | 154 } else { |
| 155 /* TODO(ncbray) metadata for the main image. */ |
| 150 rcode = NaClValidateCode(nap, NACL_TRAMPOLINE_END, | 156 rcode = NaClValidateCode(nap, NACL_TRAMPOLINE_END, |
| 151 (uint8_t *) memp, regionsize); | 157 (uint8_t *) memp, regionsize, NULL); |
| 152 if (LOAD_OK != rcode) { | 158 if (LOAD_OK != rcode) { |
| 153 if (nap->ignore_validator_result) { | 159 if (nap->ignore_validator_result) { |
| 154 NaClLog(LOG_ERROR, "VALIDATION FAILED: continuing anyway...\n"); | 160 NaClLog(LOG_ERROR, "VALIDATION FAILED: continuing anyway...\n"); |
| 155 rcode = LOAD_OK; | 161 rcode = LOAD_OK; |
| 156 } else { | 162 } else { |
| 157 NaClLog(LOG_ERROR, "VALIDATION FAILED.\n"); | 163 NaClLog(LOG_ERROR, "VALIDATION FAILED.\n"); |
| 158 NaClLog(LOG_ERROR, | 164 NaClLog(LOG_ERROR, |
| 159 "Run sel_ldr in debug mode to ignore validation failure.\n"); | 165 "Run sel_ldr in debug mode to ignore validation failure.\n"); |
| 160 NaClLog(LOG_ERROR, | 166 NaClLog(LOG_ERROR, |
| 161 "Run ncval <module-name> for validation error details.\n"); | 167 "Run ncval <module-name> for validation error details.\n"); |
| 162 rcode = LOAD_VALIDATION_FAILED; | 168 rcode = LOAD_VALIDATION_FAILED; |
| 163 } | 169 } |
| 164 } | 170 } |
| 165 } | 171 } |
| 166 return rcode; | 172 return rcode; |
| 167 } | 173 } |
| OLD | NEW |