| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2010 The Native Client Authors. All rights reserved. | 2 * Copyright 2010 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can | 3 * Use of this source code is governed by a BSD-style license that can |
| 4 * be found in the LICENSE file. | 4 * be 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 | 9 |
| 10 | 10 |
| 11 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 | 11 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 |
| 12 | 12 |
| 13 # include "native_client/src/trusted/validator_x86/nccopycode.h" |
| 14 |
| 13 # if NACL_TARGET_SUBARCH == 32 | 15 # if NACL_TARGET_SUBARCH == 32 |
| 14 | 16 |
| 15 # include "native_client/src/trusted/validator_x86/ncvalidate.h" | 17 # include "native_client/src/trusted/validator_x86/ncvalidate.h" |
| 16 # include "native_client/src/trusted/validator_x86/nccopycode.h" | |
| 17 | 18 |
| 18 int NaClValidateCode(struct NaClApp *nap, uintptr_t guest_addr, | 19 int NaClValidateCode(struct NaClApp *nap, uintptr_t guest_addr, |
| 19 uint8_t *data, size_t size) { | 20 uint8_t *data, size_t size) { |
| 20 struct NCValidatorState *vstate; | 21 struct NCValidatorState *vstate; |
| 21 int validator_result; | 22 int validator_result; |
| 22 | 23 |
| 23 if (nap->validator_stub_out_mode) { | 24 if (nap->validator_stub_out_mode) { |
| 24 /* In stub out mode, we do two passes. The second pass acts as a | 25 /* In stub out mode, we do two passes. The second pass acts as a |
| 25 sanity check that bad instructions were indeed overwritten with | 26 sanity check that bad instructions were indeed overwritten with |
| 26 allowable HLTs. */ | 27 allowable HLTs. */ |
| (...skipping 25 matching lines...) Expand all Loading... |
| 52 size_t size) { | 53 size_t size) { |
| 53 struct NCValidatorState *vstate; | 54 struct NCValidatorState *vstate; |
| 54 int validator_result; | 55 int validator_result; |
| 55 | 56 |
| 56 if (nap->validator_stub_out_mode) { | 57 if (nap->validator_stub_out_mode) { |
| 57 NaClLog(1, "NaClValidateCodeReplacement: " | 58 NaClLog(1, "NaClValidateCodeReplacement: " |
| 58 "stub_out_mode not supported for code replacement\n"); | 59 "stub_out_mode not supported for code replacement\n"); |
| 59 return LOAD_BAD_FILE; | 60 return LOAD_BAD_FILE; |
| 60 } | 61 } |
| 61 | 62 |
| 63 if ((guest_addr % nap->bundle_size) != 0 || |
| 64 (size % nap->bundle_size) != 0) { |
| 65 NaClLog(1, "NaClValidateCodeReplacement: " |
| 66 "code replacement is not properly bundle-aligned\n"); |
| 67 return LOAD_BAD_FILE; |
| 68 } |
| 69 |
| 62 vstate = NCValidateInit(guest_addr, guest_addr + size, nap->bundle_size); | 70 vstate = NCValidateInit(guest_addr, guest_addr + size, nap->bundle_size); |
| 63 if (vstate == NULL) { | 71 if (vstate == NULL) { |
| 64 return LOAD_BAD_FILE; | 72 return LOAD_BAD_FILE; |
| 65 } | 73 } |
| 66 NCValidateSegmentPair(data_old, data_new, guest_addr, size, vstate); | 74 NCValidateSegmentPair(data_old, data_new, guest_addr, size, vstate); |
| 67 validator_result = NCValidateFinish(vstate); | 75 validator_result = NCValidateFinish(vstate); |
| 68 NCValidateFreeState(&vstate); | 76 NCValidateFreeState(&vstate); |
| 69 if (validator_result != 0) { | 77 if (validator_result != 0) { |
| 70 return LOAD_VALIDATION_FAILED; | 78 return LOAD_VALIDATION_FAILED; |
| 71 } | 79 } |
| 72 return LOAD_OK; | 80 return LOAD_OK; |
| 73 } | 81 } |
| 74 | 82 |
| 75 int NaClCopyCode(struct NaClApp *nap, uintptr_t guest_addr, | 83 int NaClCopyCode(struct NaClApp *nap, uintptr_t guest_addr, |
| 76 uint8_t *data_old, uint8_t *data_new, | 84 uint8_t *data_old, uint8_t *data_new, |
| 77 size_t size) { | 85 size_t size) { |
| 78 int result; | 86 int result; |
| 79 result = NCCopyCode(data_old, data_new, guest_addr, size, nap->bundle_size); | 87 result = NCCopyCode(data_old, data_new, guest_addr, size, nap->bundle_size); |
| 80 if (result != 0) { | 88 if (0 == result) { |
| 81 return LOAD_UNLOADABLE; | 89 return LOAD_UNLOADABLE; |
| 82 } | 90 } |
| 83 return LOAD_OK; | 91 return LOAD_OK; |
| 84 } | 92 } |
| 85 | 93 |
| 86 # else | 94 # else |
| 87 | 95 |
| 88 # include "native_client/src/trusted/validator_x86/ncvalidate_iter.h" | 96 # include "native_client/src/trusted/validator_x86/ncvalidate_iter.h" |
| 89 | 97 |
| 90 int NaClValidateCode(struct NaClApp *nap, uintptr_t guest_addr, | 98 int NaClValidateCode(struct NaClApp *nap, uintptr_t guest_addr, |
| 91 uint8_t *data, size_t size) { | 99 uint8_t *data, size_t size) { |
| 92 struct NaClValidatorState *vstate; | 100 struct NaClValidatorState *vstate; |
| 93 int is_ok; | 101 int is_ok; |
| 94 | 102 |
| 95 vstate = NaClValidatorStateCreate(guest_addr, size, nap->bundle_size, | 103 vstate = NaClValidatorStateCreate(guest_addr, size, nap->bundle_size, |
| 96 RegR15); | 104 RegR15); |
| 97 if (vstate == NULL) { | 105 if (vstate == NULL) { |
| 98 return LOAD_BAD_FILE; | 106 return LOAD_BAD_FILE; |
| 99 } | 107 } |
| 108 |
| 100 NaClValidatorStateSetLogVerbosity(vstate, LOG_ERROR); | 109 NaClValidatorStateSetLogVerbosity(vstate, LOG_ERROR); |
| 101 | 110 |
| 102 if (nap->validator_stub_out_mode) { | 111 if (nap->validator_stub_out_mode) { |
| 103 /* In stub out mode, we do two passes. The second pass acts as a sanity | 112 /* In stub out mode, we do two passes. The second pass acts as a sanity |
| 104 * check, after illegal instructions have been stubbed out with allowable | 113 * check, after illegal instructions have been stubbed out with allowable |
| 105 * HLTs. | 114 * HLTs. |
| 106 * Start pass one to find errors, and stub out illegal instructions. | 115 * Start pass one to find errors, and stub out illegal instructions. |
| 107 */ | 116 */ |
| 108 NaClValidatorStateSetDoStubOut(vstate, TRUE); | 117 NaClValidatorStateSetDoStubOut(vstate, TRUE); |
| 109 NaClValidateSegment(data, guest_addr, size, vstate); | 118 NaClValidateSegment(data, guest_addr, size, vstate); |
| 110 NaClValidatorStateDestroy(vstate); | 119 NaClValidatorStateDestroy(vstate); |
| 111 vstate = NaClValidatorStateCreate(guest_addr, size, nap->bundle_size, | 120 vstate = NaClValidatorStateCreate(guest_addr, size, nap->bundle_size, |
| 112 RegR15); | 121 RegR15); |
| 113 NaClValidatorStateSetLogVerbosity(vstate, LOG_ERROR); | 122 NaClValidatorStateSetLogVerbosity(vstate, LOG_ERROR); |
| 114 } | 123 } |
| 115 NaClValidateSegment(data, guest_addr, size, vstate); | 124 NaClValidateSegment(data, guest_addr, size, vstate); |
| 116 is_ok = NaClValidatesOk(vstate); | 125 is_ok = NaClValidatesOk(vstate); |
| 117 NaClValidatorStateDestroy(vstate); | 126 NaClValidatorStateDestroy(vstate); |
| 118 if (!is_ok) { | 127 if (!is_ok) { |
| 119 return LOAD_VALIDATION_FAILED; | 128 return LOAD_VALIDATION_FAILED; |
| 120 } | 129 } |
| 121 return LOAD_OK; | 130 return LOAD_OK; |
| 122 } | 131 } |
| 123 | 132 |
| 124 int NaClValidateCodeReplacement(struct NaClApp *nap, uintptr_t guest_addr, | 133 int NaClValidateCodeReplacement(struct NaClApp *nap, uintptr_t guest_addr, |
| 125 uint8_t *data_old, uint8_t *data_new, | 134 uint8_t *data_old, uint8_t *data_new, |
| 126 size_t size) { | 135 size_t size) { |
| 127 UNREFERENCED_PARAMETER(nap); | 136 struct NaClValidatorState *vstate; |
| 128 UNREFERENCED_PARAMETER(guest_addr); | 137 int is_ok; |
| 129 UNREFERENCED_PARAMETER(data_old); | 138 |
| 130 UNREFERENCED_PARAMETER(data_new); | 139 if (nap->validator_stub_out_mode) { |
| 131 UNREFERENCED_PARAMETER(size); | 140 NaClLog(1, "NaClValidateCodeReplacement: " |
| 132 NaClLog(1, "NaClValidateCodeReplacement: " | 141 "stub_out_mode not supported for code replacement\n"); |
| 133 "code replacement not yet supported on x86_64\n"); | 142 return LOAD_BAD_FILE; |
| 134 return LOAD_UNIMPLEMENTED; | 143 } |
| 144 |
| 145 if ((guest_addr % nap->bundle_size) != 0 || |
| 146 (size % nap->bundle_size) != 0) { |
| 147 NaClLog(1, "NaClValidateCodeReplacement: " |
| 148 "code replacement is not properly bundle-aligned\n"); |
| 149 return LOAD_BAD_FILE; |
| 150 } |
| 151 |
| 152 vstate = NaClValidatorStateCreate(guest_addr, size, nap->bundle_size, |
| 153 RegR15); |
| 154 if (NULL == vstate) { |
| 155 return LOAD_BAD_FILE; |
| 156 } |
| 157 NaClValidatorStateSetLogVerbosity(vstate, LOG_ERROR); |
| 158 |
| 159 NaClValidateSegmentPair(data_old, data_new, guest_addr, size, vstate); |
| 160 is_ok = NaClValidatesOk(vstate); |
| 161 NaClValidatorStateDestroy(vstate); |
| 162 if (!is_ok) { |
| 163 return LOAD_VALIDATION_FAILED; |
| 164 } |
| 165 return LOAD_OK; |
| 135 } | 166 } |
| 136 | 167 |
| 137 | |
| 138 int NaClCopyCode(struct NaClApp *nap, uintptr_t guest_addr, | 168 int NaClCopyCode(struct NaClApp *nap, uintptr_t guest_addr, |
| 139 uint8_t *data_old, uint8_t *data_new, | 169 uint8_t *data_old, uint8_t *data_new, |
| 140 size_t size) { | 170 size_t size) { |
| 171 int result; |
| 141 UNREFERENCED_PARAMETER(nap); | 172 UNREFERENCED_PARAMETER(nap); |
| 142 UNREFERENCED_PARAMETER(guest_addr); | 173 |
| 143 UNREFERENCED_PARAMETER(data_old); | 174 result = NaClCopyCodeIter(data_old, data_new, guest_addr, size); |
| 144 UNREFERENCED_PARAMETER(data_new); | 175 if (0 == result) { |
| 145 UNREFERENCED_PARAMETER(size); | 176 return LOAD_UNLOADABLE; |
| 146 NaClLog(1, "NaClCopyCode: " | 177 } |
| 147 "code replacement not yet supported on x86_64\n"); | 178 return LOAD_OK; |
| 148 return LOAD_UNIMPLEMENTED; | |
| 149 } | 179 } |
| 150 | 180 |
| 151 # endif | 181 # endif |
| 152 | 182 |
| 153 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm | 183 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm |
| 154 | 184 |
| 155 # include "native_client/src/trusted/validator_arm/ncvalidate.h" | 185 # include "native_client/src/trusted/validator_arm/ncvalidate.h" |
| 156 | 186 |
| 157 int NaClValidateCode(struct NaClApp *nap, uintptr_t guest_addr, | 187 int NaClValidateCode(struct NaClApp *nap, uintptr_t guest_addr, |
| 158 uint8_t *data, size_t size) { | 188 uint8_t *data, size_t size) { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 NaClLog(LOG_ERROR, "VALIDATION FAILED.\n"); | 247 NaClLog(LOG_ERROR, "VALIDATION FAILED.\n"); |
| 218 NaClLog(LOG_ERROR, | 248 NaClLog(LOG_ERROR, |
| 219 "Run sel_ldr in debug mode to ignore validation failure.\n"); | 249 "Run sel_ldr in debug mode to ignore validation failure.\n"); |
| 220 NaClLog(LOG_ERROR, | 250 NaClLog(LOG_ERROR, |
| 221 "Run ncval <module-name> for validation error details.\n"); | 251 "Run ncval <module-name> for validation error details.\n"); |
| 222 rcode = LOAD_VALIDATION_FAILED; | 252 rcode = LOAD_VALIDATION_FAILED; |
| 223 } | 253 } |
| 224 } | 254 } |
| 225 return rcode; | 255 return rcode; |
| 226 } | 256 } |
| OLD | NEW |