Index: src/trusted/validator/x86/ncval_reg_sfi/nc_jumps.c |
diff --git a/src/trusted/validator/x86/ncval_reg_sfi/nc_jumps.c b/src/trusted/validator/x86/ncval_reg_sfi/nc_jumps.c |
deleted file mode 100644 |
index b39c867392057acbf8ed7b76c21f019c485b1602..0000000000000000000000000000000000000000 |
--- a/src/trusted/validator/x86/ncval_reg_sfi/nc_jumps.c |
+++ /dev/null |
@@ -1,597 +0,0 @@ |
-/* |
- * Copyright (c) 2012 The Native Client Authors. All rights reserved. |
- * Use of this source code is governed by a BSD-style license that can be |
- * found in the LICENSE file. |
- */ |
- |
-/* |
- * nc_jumps.c - Validate where valid jumps can occur. |
- */ |
- |
-#include <assert.h> |
-#include <stdlib.h> |
- |
-#include "native_client/src/trusted/validator/x86/ncval_reg_sfi/nc_jumps.h" |
- |
-#include "native_client/src/shared/platform/nacl_log.h" |
-#include "native_client/src/trusted/validator/x86/decoder/nc_inst_state_internal.h" |
-#include "native_client/src/trusted/validator/x86/decoder/nc_inst_trans.h" |
-#include "native_client/src/trusted/validator/x86/ncval_reg_sfi/address_sets.h" |
-#include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_iter.h" |
-#include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_iter_internal.h" |
- |
-/* To turn on debugging of instruction decoding, change value of |
- * DEBUGGING to 1. |
- */ |
-#define DEBUGGING 0 |
- |
-#include "native_client/src/shared/utils/debugging.h" |
- |
-#include "native_client/src/trusted/validator/x86/decoder/ncop_exps_inl.c" |
-#include "native_client/src/trusted/validator/x86/decoder/nc_inst_iter_inl.c" |
-#include "native_client/src/trusted/validator/x86/ncval_reg_sfi/address_sets_inl.c" |
- |
-Bool NACL_FLAGS_identity_mask = FALSE; |
- |
-static INLINE uint8_t NaClGetJumpMask(NaClValidatorState* vstate) { |
- return NACL_FLAGS_identity_mask |
- ? (uint8_t) 0xFF |
- : (uint8_t) (~vstate->bundle_mask); |
-} |
- |
-/* Generates a jump validator. */ |
-Bool NaClJumpValidatorInitialize(NaClValidatorState* vstate) { |
- NaClJumpSets* jump_sets = &vstate->jump_sets; |
- jump_sets->actual_targets = NaClAddressSetCreate(vstate->codesize); |
- jump_sets->possible_targets = NaClAddressSetCreate(vstate->codesize); |
- jump_sets->removed_targets = NaClAddressSetCreate(vstate->codesize); |
- if (jump_sets->actual_targets == NULL || |
- jump_sets->possible_targets == NULL || |
- jump_sets->removed_targets == NULL) { |
- NaClValidatorMessage(LOG_ERROR, vstate, "unable to allocate jump sets"); |
- NaClJumpValidatorCleanUp(vstate); |
- return FALSE; |
- } |
- jump_sets->set_array_size = NaClAddressSetArraySize(vstate->codesize); |
- return TRUE; |
-} |
- |
-/* Record that there is an explicit jump from the from_address to the |
- * to_address, for the validation defined by the validator state. |
- * Parameters: |
- * vstate - The state of the validator. |
- * inst - The instruction that does the jump. |
- * jump_offset - The jump offset, relative to the end of the instruction. |
- */ |
-static void NaClAddJumpToJumpSets(NaClValidatorState* vstate, |
- NaClInstState* inst, |
- NaClPcNumber jump_offset) { |
- NaClPcAddress to_address = inst->inst_addr + inst->bytes.length + jump_offset; |
- /* If the address is in the code segment, assume good (unless we later find it |
- * jumping into a pseudo instruction). Otherwise, only allow if 0 mod 32. |
- */ |
- DEBUG(NaClLog(LOG_INFO, "Add jump to jump sets: %" |
- NACL_PRIxNaClPcAddress" -> %"NACL_PRIxNaClPcAddress"\n", |
- inst->inst_addr, to_address)); |
- if (to_address < vstate->codesize) { |
- /* Remember address for checking later. */ |
- DEBUG(NaClLog(LOG_INFO, "Add jump to target: %"NACL_PRIxNaClPcAddress |
- " -> %"NACL_PRIxNaClPcAddress"\n", |
- inst->inst_addr, to_address)); |
- NaClAddressSetAddInline(vstate->jump_sets.actual_targets, |
- to_address, vstate); |
- } else if ((to_address & vstate->bundle_mask) == 0) { |
- /* Allow bundle-aligned jump. If the jump overflows or underflows the |
- * 4GB untrusted address space it will hit the guard regions. The largest |
- * potential jump offset is +/-2GB. We could allow direct jumps only within |
- * the 4GB untrusted address space, but there is no need for this |
- * restriction and it would make validation judgements position-dependent. |
- */ |
- } else if (inst->unchanged) { |
- /* If we are replacing this instruction during dynamic code modification |
- * and it has not changed, the jump target must be valid because the |
- * instruction has been previously validated. However, we may be only |
- * replacing a subsection of the code segment and therefore may not have |
- * information about instruction boundaries outside of the code being |
- * replaced. Therefore, we allow unaligned direct jumps outside of the code |
- * being validated if and only if the instruction is unchanged. |
- * If dynamic code replacement is not being performed, inst->unchanged |
- * should always be false. |
- */ |
- } else { |
- if (!NACL_FLAGS_unsafe_single_inst_mode) { |
- NaClValidatorInstMessage(LOG_ERROR, vstate, inst, |
- "Instruction jumps to bad address\n"); |
- } |
- } |
-} |
- |
-static Bool NaClExtractBinaryOperandIndices( |
- NaClInstState* inst, |
- int* op_1, |
- int* op_2) { |
- uint32_t index; |
- NaClExpVector* nodes = NaClInstStateExpVector(inst); |
- *op_1 = -1; |
- *op_2 = -1; |
- |
- for (index = 0; index < nodes->number_expr_nodes; ++index) { |
- if (OperandReference == nodes->node[index].kind) { |
- if (-1 == *op_1) { |
- *op_1 = index + 1; |
- } else { |
- *op_2 = index + 1; |
- return TRUE; |
- } |
- } |
- } |
- return FALSE; |
-} |
- |
-/* Returns the 32-bit register for instructions of the form |
- * |
- * and %reg32, MASK |
- * |
- * where MASK is all 1/s except for the alignment mask bits, which must be zero. |
- * |
- * It is assumed that opcode 0x83 is used for the AND operation, and hence, the |
- * mask is a single byte. |
- * |
- * Returns RegUnknown if the instruction doesn't match the form listed above. |
- */ |
-static NaClOpKind NaClGetAndMaskReg32(NaClValidatorState* vstate, |
- size_t distance) { |
- NaClInstState* state; |
- const NaClInst* inst; |
- int op_1, op_2; |
- NaClExpVector* nodes; |
- NaClExp* node; |
- uint8_t mask; |
- NaClOpKind reg32; |
- NaClInstIter* iter = vstate->cur_iter; |
- |
- /* Get the corresponding and instruction. */ |
- if (!NaClInstIterHasLookbackStateInline(iter, distance)) return RegUnknown; |
- state = NaClInstIterGetLookbackStateInline(iter, distance); |
- inst = NaClInstStateInst(state); |
- if ((InstAnd != inst->name) || |
- (state->num_opcode_bytes == 0) || |
- (0x83 != state->bytes.byte[state->num_prefix_bytes])) return RegUnknown; |
- DEBUG(NaClLog(LOG_INFO, "inst(%d): and mask: ", (int) distance); |
- NaClInstStateInstPrint(NaClLogGetGio(), state)); |
- |
- /* Extract the values of the two operands for the and. */ |
- if (!NaClExtractBinaryOperandIndices(state, &op_1, &op_2)) return RegUnknown; |
- |
- /* Extract the destination register of the and. */ |
- nodes = NaClInstStateExpVector(state); |
- node = &nodes->node[op_1]; |
- if (ExprRegister != node->kind) return RegUnknown; |
- |
- reg32 = NaClGetExpRegisterInline(node); |
- DEBUG(NaClLog(LOG_INFO, "and mask reg = %s\n", NaClOpKindName(reg32))); |
- |
- /* Check that the mask is ok. */ |
- mask = NaClGetJumpMask(vstate); |
- DEBUG(NaClLog(LOG_INFO, "mask = %"NACL_PRIx8"\n", mask)); |
- |
- assert(0xf0 == mask || 0xe0 == mask); /* alignment must be either 16 or 32. */ |
- node = &nodes->node[op_2]; |
- /* Technically the operand is a signed value, but "mask" has not been sign |
- * extended, so treat the value as an unsigned byte. |
- */ |
- if (ExprConstant != node->kind || mask != NaClGetExprUnsignedValue(node)) |
- return RegUnknown; |
- DEBUG(NaClLog(LOG_INFO, "is mask constant\n")); |
- |
- return reg32; |
-} |
- |
-/* Returns true if the 64-bit register reg64 set by an instruction of the form |
- * |
- * add %reg64 %RBASE |
- * |
- * The instruction checked is the "distance" instruction from the current |
- * instruction being looked at by the specified iterator. |
- */ |
-static Bool NaClIsAddRbaseToReg64(NaClValidatorState* vstate, |
- size_t distance, |
- NaClOpKind reg64) { |
- NaClInstState* state; |
- const NaClInst* inst; |
- int op_1, op_2; |
- NaClExpVector* nodes; |
- NaClExp* node; |
- NaClOpKind reg; |
- NaClInstIter* iter = vstate->cur_iter; |
- |
- /* Get the corresponding instruction. */ |
- if (!NaClInstIterHasLookbackStateInline(iter, distance)) return FALSE; |
- state = NaClInstIterGetLookbackStateInline(iter, distance); |
- inst = NaClInstStateInst(state); |
- if (InstAdd != inst->name) return FALSE; |
- DEBUG(NaClLog(LOG_INFO, "inst(%d): add rbase: ", (int) distance); |
- NaClInstStateInstPrint(NaClLogGetGio(), state)); |
- |
- /* Extract the values of the two operands for the and. */ |
- if (!NaClExtractBinaryOperandIndices(state, &op_1, &op_2)) return FALSE; |
- |
- /* Extract the destination register of the and. */ |
- nodes = NaClInstStateExpVector(state); |
- node = &nodes->node[op_1]; |
- if (ExprRegister != node->kind) return FALSE; |
- |
- /* Check that destination register matches wanted register. */ |
- reg = NaClGetExpRegisterInline(node); |
- if (reg != reg64) return FALSE; |
- |
- /* Check that source register is the base register. */ |
- return NaClGetExpVectorRegister(nodes, op_2) == vstate->base_register; |
-} |
- |
-/* Checks if an indirect jump (in 64-bit mode) is native client compliant. |
- * |
- * Expects pattern: |
- * |
- * and %REG32, MASK |
- * add %REG64, %RBASE |
- * jmp %REG64 |
- * |
- * where MASK is all 1/s except for the alignment mask bits, which must be zero. |
- * |
- * REG32 is the corresponding 32-bit register that whose value will get zero |
- * extended by the AND operation into the corresponding 64-bit register REG64. |
- * |
- * It is assumed that opcode 0x83 is used for the AND operation, and hence, the |
- * mask is a single byte. |
- * |
- * Note: applies to all kinds of jumps and calls. |
- * |
- * Parameters: |
- * vstate - The state of the validator. |
- * reg - The register used in the jump instruction. |
- */ |
-static void NaClAddRegisterJumpIndirect64(NaClValidatorState* vstate, |
- NaClExp* reg) { |
- NaClOpKind jump_reg, and_reg32, and_reg64; |
- |
- /* Do the following block exactly once. Use loop so that "break" can |
- * be used for premature exit of block. |
- */ |
- do { |
- /* Check that jump register is 64-bit. */ |
- if (!NaClHasBit(reg->flags, NACL_EFLAG(ExprSize64))) break; |
- jump_reg = NaClGetExpRegisterInline(reg); |
- if (RegUnknown == jump_reg) break; |
- DEBUG(NaClLog(LOG_INFO, "checking indirect jump: "); |
- NaClInstStateInstPrint(NaClLogGetGio(), vstate->cur_inst_state); |
- gprintf(NaClLogGetGio(), "jump_reg = %s\n", |
- NaClOpKindName(jump_reg))); |
- |
- /* Check that sequence begins with an appropriate and instruction. */ |
- and_reg32 = NaClGetAndMaskReg32(vstate, 2); |
- if (RegUnknown == and_reg32) break; |
- |
- /* Get corresponding 64-bit register for 32-bit result of 'and', |
- * and make sure it matches the jump register. |
- */ |
- and_reg64 = NaClGet64For32BitReg(and_reg32); |
- if (and_reg64 != jump_reg) break; |
- |
- /* Check that the middle instruction is an appropriate add instruction. */ |
- if (!NaClIsAddRbaseToReg64(vstate, 1, and_reg64)) break; |
- |
- /* If reached, indirect jump is properly masked. */ |
- DEBUG(NaClLog(LOG_INFO, "Protect indirect jump instructions\n")); |
- NaClMarkInstructionJumpIllegal( |
- vstate, NaClInstIterGetLookbackStateInline(vstate->cur_iter, 1)); |
- NaClMarkInstructionJumpIllegal(vstate, vstate->cur_inst_state); |
- return; |
- } while(0); |
- |
- /* If reached, mask was not found. */ |
- NaClValidatorInstMessage(LOG_ERROR, vstate, vstate->cur_inst_state, |
- "Invalid indirect jump\n"); |
-} |
- |
-/* Checks if an indirect jump (in 32-bit mode) is native client compliant. |
- * |
- * Expects pattern: |
- * and %REG, MASK |
- * jmp %REG |
- * |
- * where the MASK is all 1's except for the alignment mask bits, which must |
- * be zero. |
- * |
- * It is assumed that opcode 0x83 is used for the AND operation, and hence, the |
- * mask is a single byte. |
- * |
- * Note: applies to all kinds of jumps and calls. |
- * |
- * Parameters: |
- * state - The state of the validator. |
- * reg - The register used in the jump instruction. |
- */ |
-static void NaClAddRegisterJumpIndirect32(NaClValidatorState* vstate, |
- NaClExp* reg) { |
- NaClOpKind jump_reg, and_reg; |
- |
- /* Do the following block exactly once. Use loop so that "break" can |
- * be used for premature exit of block. |
- */ |
- do { |
- /* Check that jump register is 32-bit. */ |
- if (!NaClHasBit(reg->flags, NACL_EFLAG(ExprSize32))) break; |
- jump_reg = NaClGetExpRegisterInline(reg); |
- if (RegUnknown == jump_reg) break; |
- DEBUG(NaClLog(LOG_INFO, "checking indirect jump: "); |
- NaClInstStateInstPrint(NaClLogGetGio(), vstate->cur_inst_state); |
- gprintf(NaClLogGetGio(), "jump_reg = %s\n", |
- NaClOpKindName(jump_reg))); |
- |
- /* Check that sequence begins with an appropriate and instruction. */ |
- and_reg = NaClGetAndMaskReg32(vstate, 1); |
- if (jump_reg != and_reg) break; |
- |
- /* If reached, indirect jump is properly masked. */ |
- DEBUG(NaClLog(LOG_INFO, "Protect register jump indirect\n")); |
- NaClMarkInstructionJumpIllegal(vstate, vstate->cur_inst_state); |
- return; |
- } while(0); |
- |
- /* If reached, mask was not found. */ |
- NaClValidatorInstMessage(LOG_ERROR, vstate, vstate->cur_inst_state, |
- "Invalid indirect jump\n"); |
-} |
- |
-/* Given a jump statement, add the corresponding (explicit) jump value |
- * to the set of actual jump targets. |
- * Parameters: |
- * vstate - The state of the validator. |
- */ |
-static void NaClAddExprJumpTarget(NaClValidatorState* vstate) { |
- uint32_t i; |
- NaClInstState* inst_state = vstate->cur_inst_state; |
- NaClExpVector* vector = vstate->cur_inst_vector; |
- DEBUG(NaClLog(LOG_INFO, "jump checking: "); |
- NaClInstStateInstPrint(NaClLogGetGio(), inst_state)); |
- for (i = 0; i < vector->number_expr_nodes; ++i) { |
- NaClExp* node = &vector->node[i]; |
- if (!NaClHasBit(node->flags, NACL_EFLAG(ExprJumpTarget))) |
- continue; |
- switch (node->kind) { |
- case ExprRegister: |
- if (64 == NACL_TARGET_SUBARCH) { |
- NaClAddRegisterJumpIndirect64(vstate, node); |
- } else { |
- NaClAddRegisterJumpIndirect32(vstate, node); |
- } |
- break; |
- case ExprConstant: |
- /* Direct jump. */ |
- NaClAddJumpToJumpSets(vstate, inst_state, |
- (NaClPcNumber) NaClGetExprSignedValue(node)); |
- break; |
- default: |
- NaClValidatorInstMessage( |
- LOG_ERROR, vstate, inst_state, |
- "Jump not native client compliant\n"); |
- } |
- } |
-} |
- |
-/* Given an instruction corresponding to a call, validate that the generated |
- * return address is safe. |
- * Parameters: |
- * vstate - The state of the validator. |
- */ |
-static void NaClValidateCallAlignment(NaClValidatorState* vstate) { |
- /* The return is safe only if it begins at an aligned address (since |
- * return instructions are not explicit jumps). |
- */ |
- NaClPcAddress next_addr = vstate->cur_inst_state->inst_addr |
- + NaClInstStateLength(vstate->cur_inst_state); |
- if (next_addr & vstate->bundle_mask) { |
- NaClPcAddress printable_next_addr = |
- NaClInstStatePrintableAddress(vstate->cur_inst_state) + |
- NaClInstStateLength(vstate->cur_inst_state); |
- /* NOTE: Previously the validator recorded an error for call instructions |
- * that were not aligned against the end of a bundle, as these, while |
- * safe, are not correct with the current code generation idioms. |
- * This #if defined(ERROR_ON_CALL_BUNDLE_ALIGNMENT) was added to allow |
- * experimentation with different call/return idioms. |
- */ |
- if (!NACL_FLAGS_unsafe_single_inst_mode) { |
- NaClValidatorInstMessage( |
-#if defined(ERROR_ON_CALL_BUNDLE_ALIGNMENT) |
- LOG_ERROR, |
-#else |
- LOG_WARNING, |
-#endif |
- vstate, vstate->cur_inst_state, |
- "Bad call alignment, return pc = %"NACL_PRIxNaClPcAddress"\n", |
- printable_next_addr); |
- } |
- } |
-} |
- |
-/* TODO(ncbray) prove that all instructions the decoder generates are in the |
- * code segment and remove this check. |
- */ |
-static INLINE Bool NaClInstructionInCodeSegment(NaClValidatorState* vstate, |
- NaClInstState *inst) { |
- return inst->inst_addr < vstate->codesize; |
-} |
- |
-/* Record that the given address of the given instruction is the beginning of |
- * a disassembled instruction. |
- * Parameters: |
- * vstate - The state of the validator. |
- * inst - The instruction. |
- */ |
-static void NaClRememberInstructionBoundary(NaClValidatorState* vstate, |
- NaClInstState* inst) { |
- if (!NaClInstructionInCodeSegment(vstate, inst)) { |
- NaClValidatorInstMessage(LOG_ERROR, vstate, inst, |
- "Instruction pc out of range\n"); |
- } else { |
- DEBUG(NaClLog(LOG_INFO, |
- "Add possible jump address: %"NACL_PRIxNaClPcAddress"\n", |
- inst->inst_addr)); |
- NaClAddressSetAddInline(vstate->jump_sets.possible_targets, inst->inst_addr, |
- vstate); |
- } |
-} |
- |
-void NaClJumpValidatorRememberIpOnly(NaClValidatorState* vstate) { |
- NaClRememberInstructionBoundary(vstate, vstate->cur_inst_state); |
-} |
- |
-void NaClJumpValidator(NaClValidatorState* vstate) { |
- NaClRememberInstructionBoundary(vstate, vstate->cur_inst_state); |
- if (vstate->cur_inst->flags & |
- (NACL_IFLAG(JumpInstruction) | NACL_IFLAG(ConditionalJump))) { |
- NaClAddExprJumpTarget(vstate); |
- if (vstate->cur_inst->name == InstCall) { |
- NaClValidateCallAlignment(vstate); |
- } |
- } |
-} |
- |
-/* Returns true if the given address corresponds to the beginning |
- * of an atomic sequence of instructions, and hence can be branched to. |
- */ |
-static Bool IsNaClReachableAddress(NaClValidatorState* vstate, |
- NaClPcAddress addr) { |
- DEBUG(NaClLog(LOG_INFO, "possible contains: %d\n", |
- (int) NaClAddressSetContains(vstate->jump_sets.possible_targets, |
- addr, vstate))); |
- DEBUG(NaClLog(LOG_INFO, "removed contains: %d\n", |
- (int) NaClAddressSetContains(vstate->jump_sets.removed_targets, |
- addr, vstate))); |
- return NaClAddressSetContains(vstate->jump_sets.possible_targets, |
- addr, vstate) && |
- !NaClAddressSetContains(vstate->jump_sets.removed_targets, addr, vstate); |
-} |
- |
-void NaClJumpValidatorSummarize(NaClValidatorState* vstate) { |
- /* Check that any explicit jump is to a possible (atomic) sequence |
- * of disassembled instructions. |
- */ |
- NaClJumpSets* jump_sets; |
- NaClPcAddress addr; |
- size_t i; |
- if (vstate->quit) return; |
- jump_sets = &vstate->jump_sets; |
- NaClValidatorMessage( |
- LOG_INFO, vstate, |
- "Checking jump targets: %"NACL_PRIxNaClPcAddress |
- " to %"NACL_PRIxNaClPcAddress"\n", |
- vstate->vbase, vstate->vbase + vstate->codesize); |
- |
- /* (Low level) Walk the collected sets to find address that correspond |
- * to branches into an atomic sequence of instructions. |
- */ |
- for (i = 0; i < jump_sets->set_array_size; ++i) { |
- uint8_t problem = jump_sets->actual_targets[i] & |
- (~jump_sets->possible_targets[i] | |
- jump_sets->removed_targets[i]); |
- if (problem) { |
- /* Some bit in this range is a problem, so we will convert back |
- * to code like the above and test each bit separately. |
- */ |
- NaClPcAddress j; |
- NaClPcAddress base = (i << 3); |
- for (j = 0; j < 8; ++j) { |
- addr = base + j; |
- if (addr < vstate->codesize) { |
- if (NaClAddressSetContains(jump_sets->actual_targets, addr, vstate)) { |
- DEBUG(NaClLog(LOG_INFO, |
- "Checking jump address: %"NACL_PRIxNaClPcAddress"\n", |
- addr)); |
- if (!IsNaClReachableAddress(vstate, addr)) { |
- NaClValidatorPcAddressMessage(LOG_ERROR, vstate, addr, |
- "Bad jump target\n"); |
- } |
- } |
- } |
- } |
- } |
- } |
- |
- /* Check that all block boundaries are accessable at an aligned address. */ |
- NaClValidatorMessage( |
- LOG_INFO, vstate, "Checking that basic blocks are aligned\n"); |
- if (vstate->vbase & vstate->bundle_mask) { |
- NaClValidatorMessage(LOG_ERROR, vstate, |
- "Code segment starts at 0x%"NACL_PRIxNaClPcAddress", " |
- "which isn't aligned properly.\n", |
- vstate->vbase); |
- } else { |
- for (addr = 0; addr < vstate->codesize; addr += vstate->bundle_size) { |
- DEBUG(NaClLog(LOG_INFO, |
- "Checking block address: %"NACL_PRIxNaClPcAddress"\n", |
- addr)); |
- if (!IsNaClReachableAddress(vstate, addr)) { |
- NaClValidatorPcAddressMessage(LOG_ERROR, vstate, addr, |
- "Bad basic block alignment.\n"); |
- } |
- } |
- } |
-} |
- |
-void NaClJumpValidatorCleanUp(NaClValidatorState* vstate) { |
- if (NULL != vstate) { |
- NaClJumpSets* jump_sets = &vstate->jump_sets; |
- NaClAddressSetDestroy(jump_sets->actual_targets); |
- NaClAddressSetDestroy(jump_sets->possible_targets); |
- NaClAddressSetDestroy(jump_sets->removed_targets); |
- jump_sets->actual_targets = NULL; |
- jump_sets->possible_targets = NULL; |
- jump_sets->removed_targets = NULL; |
- } |
-} |
- |
-static INLINE void NaClMarkInstructionJumpIllegalInline( |
- struct NaClValidatorState* vstate, |
- struct NaClInstState* inst) { |
- if (!NaClInstructionInCodeSegment(vstate, inst)) { |
- /* ERROR instruction out of range. |
- * Note: Not reported here, because this will already be reported by |
- * the call to NaClRememberIp in JumpValidator. |
- */ |
- } else { |
- DEBUG(NaClLog(LOG_INFO, |
- "Mark instruction as jump illegal: %"NACL_PRIxNaClPcAddress |
- "\n", |
- inst->inst_addr)); |
- NaClAddressSetAddInline(vstate->jump_sets.removed_targets, inst->inst_addr, |
- vstate); |
- } |
-} |
- |
-void NaClMarkInstructionJumpIllegal(struct NaClValidatorState* vstate, |
- struct NaClInstState* inst) { |
- NaClMarkInstructionJumpIllegalInline(vstate, inst); |
-} |
- |
-void NaClMarkInstructionsJumpRangeIllegal(struct NaClValidatorState* vstate, |
- int distance) { |
- int i; |
- for (i = 0; i < distance; i++) { |
- struct NaClInstState* inst = |
- NaClInstIterGetLookbackStateInline(vstate->cur_iter, i); |
- NaClMarkInstructionJumpIllegalInline(vstate, inst); |
- } |
-} |
- |
-void NaClMarkInstructionJumpIllegalLookback( |
- struct NaClInstIter* iter, |
- struct NaClValidatorState* state, |
- size_t n) { |
- NaClMarkInstructionJumpIllegal( |
- state, |
- (n == 0) |
- ? state->cur_inst_state |
- : NaClInstIterGetLookbackStateInline(iter, n)); |
-} |