| OLD | NEW |
| (Empty) |
| 1 /* | |
| 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 | |
| 4 * found in the LICENSE file. | |
| 5 */ | |
| 6 | |
| 7 #ifndef NACL_TRUSTED_BUT_NOT_TCB | |
| 8 #error("This file is not meant for use in the TCB") | |
| 9 #endif | |
| 10 | |
| 11 #include "native_client/src/trusted/validator_x86/ncenuminsts.h" | |
| 12 | |
| 13 #include "native_client/src/shared/platform/nacl_log.h" | |
| 14 #include "native_client/src/trusted/validator/ncvalidate.h" | |
| 15 #include "native_client/src/trusted/validator/x86/decoder/ncop_exps.h" | |
| 16 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_iter.h" | |
| 17 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state.h" | |
| 18 #include "native_client/src/trusted/validator_x86/ncdis_decode_tables.h" | |
| 19 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_iter.
h" | |
| 20 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_iter_
internal.h" | |
| 21 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/nc_illegal.h" | |
| 22 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/nc_memory_protec
t.h" | |
| 23 #include "native_client/src/trusted/validator/x86/nc_segment.h" | |
| 24 | |
| 25 /* To turn on debugging of instruction decoding, change value of | |
| 26 * DEBUGGING to 1. | |
| 27 */ | |
| 28 #define DEBUGGING 0 | |
| 29 | |
| 30 #include "native_client/src/shared/utils/debugging.h" | |
| 31 | |
| 32 NaClInstStruct *NaClParseInst(uint8_t* ibytes, size_t isize, | |
| 33 const NaClPcAddress vbase) { | |
| 34 | |
| 35 /* WARNING: This version of the code uses a global to return the | |
| 36 * decoded instruction, forcing the use to be in a single thread. | |
| 37 * The following two (static) locals are used to hold the decoded | |
| 38 * instruction until the next call to the function. | |
| 39 */ | |
| 40 static NaClInstIter* ND_iterator = NULL; | |
| 41 static NaClSegment ND_segment; | |
| 42 | |
| 43 NaClSegmentInitialize(ibytes, vbase, isize, &ND_segment); | |
| 44 if (ND_iterator != NULL) { | |
| 45 NaClInstIterDestroy(ND_iterator); | |
| 46 } | |
| 47 ND_iterator = NaClInstIterCreate(kNaClDecoderTables, &ND_segment); | |
| 48 return NaClInstIterGetState(ND_iterator); | |
| 49 } | |
| 50 | |
| 51 uint8_t NaClInstLength(NaClInstStruct *inst) { | |
| 52 return NaClInstStateLength(inst); | |
| 53 } | |
| 54 | |
| 55 char *NaClInstToStr(NaClInstStruct *inst) { | |
| 56 return NaClInstStateInstructionToString(inst); | |
| 57 } | |
| 58 | |
| 59 const char *NaClOpcodeName(NaClInstStruct *inst) { | |
| 60 const struct NaClInst *nacl_opcode = NaClInstStateInst(inst); | |
| 61 return NaClMnemonicName(nacl_opcode->name); | |
| 62 } | |
| 63 | |
| 64 Bool NaClInstDecodesCorrectly(NaClInstStruct *inst) { | |
| 65 return NaClInstStateIsValid(inst); | |
| 66 } | |
| 67 | |
| 68 Bool NaClInstValidates(uint8_t* mbase, | |
| 69 uint8_t size, | |
| 70 NaClPcAddress vbase, | |
| 71 NaClInstStruct* inst) { | |
| 72 NaClSegment segment; | |
| 73 NaClValidatorState* state; | |
| 74 Bool validates = FALSE; | |
| 75 NaClCPUFeaturesX86 cpu_features; | |
| 76 | |
| 77 NaClGetCurrentCPUFeaturesX86((NaClCPUFeatures *) &cpu_features); | |
| 78 NACL_FLAGS_unsafe_single_inst_mode = TRUE; | |
| 79 state = NaClValidatorStateCreate(vbase, (NaClMemorySize) size, RegR15, FALSE, | |
| 80 &cpu_features); | |
| 81 do { | |
| 82 NaClSegmentInitialize(mbase, vbase, (NaClMemorySize) size, &segment); | |
| 83 NaClBaseRegisterMemoryInitialize(state); | |
| 84 state->cur_iter = NaClInstIterCreate(kNaClDecoderTables, &segment); | |
| 85 if (NULL == state->cur_iter) break; | |
| 86 state->cur_inst_state = NaClInstIterGetState(state->cur_iter); | |
| 87 state->cur_inst = NaClInstStateInst(state->cur_inst_state); | |
| 88 state->cur_inst_vector = NaClInstStateExpVector(state->cur_inst_state); | |
| 89 NaClValidateInstructionLegal(state); | |
| 90 NaClBaseRegisterValidator(state); | |
| 91 /* induce call to NaClMaybeReportPreviousBad() */ | |
| 92 NaClBaseRegisterSummarize(state); | |
| 93 NaClMemoryReferenceValidator(state); | |
| 94 NaClJumpValidator(state); | |
| 95 validates = NaClValidatesOk(state); | |
| 96 NaClInstIterDestroy(state->cur_iter); | |
| 97 state->cur_iter = NULL; | |
| 98 state->cur_inst_state = NULL; | |
| 99 state->cur_inst = NULL; | |
| 100 state->cur_inst_vector = NULL; | |
| 101 } while(0); | |
| 102 NaClValidatorStateDestroy(state); | |
| 103 /* Strictly speaking this shouldn't be necessary, as the mode */ | |
| 104 /* should only be used from tests. Disabling it here as a */ | |
| 105 /* defensive tactic. */ | |
| 106 NACL_FLAGS_unsafe_single_inst_mode = FALSE; | |
| 107 return validates; | |
| 108 } | |
| 109 | |
| 110 Bool NaClSegmentValidates(uint8_t* mbase, | |
| 111 size_t size, | |
| 112 NaClPcAddress vbase) { | |
| 113 NaClCPUFeaturesX86 cpu_features; | |
| 114 NaClValidationStatus status; | |
| 115 /* TODO(pasko): Validator initialization can be slow, make it run only once. | |
| 116 */ | |
| 117 const struct NaClValidatorInterface *validator = NaClCreateValidator(); | |
| 118 | |
| 119 /* check if NaCl thinks the given code segment is valid. */ | |
| 120 validator->SetAllCPUFeatures((NaClCPUFeatures *) &cpu_features); | |
| 121 status = validator->Validate( | |
| 122 vbase, mbase, size, | |
| 123 /* stubout_mode= */ FALSE, /* readonly_text= */ FALSE, | |
| 124 (NaClCPUFeatures *) &cpu_features, NULL, NULL); | |
| 125 switch (status) { | |
| 126 case NaClValidationSucceeded: | |
| 127 return TRUE; | |
| 128 default: | |
| 129 return FALSE; | |
| 130 } | |
| 131 } | |
| OLD | NEW |