uint8_t NaClAddressSetContains(NaClAddressSet set, NaClPcAddress address, NaClValidatorState* state) { if (NaClCheckAddressRange(address, state)) { return set[NaClPcAddressToOffset(address)] & NaClPcAddressToMask(address); } else { return FALSE; } }
static INLINE void NaClAddressSetAddInline(NaClAddressSet set, NaClPcAddress address, NaClValidatorState* state) { if (NaClCheckAddressRange(address, state)) { DEBUG(NaClLog(LOG_INFO, "Address set add: %"NACL_PRIxNaClPcAddress"\n", address)); set[NaClPcAddressToOffset(address)] |= NaClPcAddressToMask(address); } }
static void NaClInstLayoutCheck(NaClValidatorState* vstate) { NaClPcAddress start; NaClPcAddress end; NaClPcAddress i; if (NULL == vstate->cur_inst_state) return; DEBUG(NaClLog(LOG_INFO, "Jump layout check: "); NaClInstStateInstPrint(NaClLogGetGio(), vstate->cur_inst_state)); /* Check basic block boundaries. */ start = vstate->cur_inst_state->inst_addr; /* Check that if first instruction in a basic block, it isn't in the * middle of a pattern. */ if ((0 == (start & vstate->bundle_mask)) && NaClAddressSetContains(vstate->jump_sets.removed_targets, start, vstate)) { NaClValidatorInstMessage( LOG_ERROR, vstate, vstate->cur_inst_state, "Instruction begins basic block, but in middle of nacl pattern\n"); } /* Check that instruction doesn't cross block boundaries. */ end = (NaClPcAddress) (start + vstate->cur_inst_state->bytes.length); for (i = start + 1; i < end; ++i) { if (0 == (i & vstate->bundle_mask)) { NaClValidatorInstMessage( LOG_ERROR, vstate, vstate->cur_inst_state, "Instruction crosses basic block alignment\n"); } } /* Check jump targets. */ if (NaClHasBit(vstate->cur_inst_state->inst->flags, NACL_IFLAG(JumpInstruction) | NACL_IFLAG(ConditionalJump))) { uint32_t i; NaClExpVector* vector = NaClInstStateExpVector(vstate->cur_inst_state); for (i = 0; i < vector->number_expr_nodes; ++i) { NaClExp* node = &vector->node[i]; if (NaClHasBit(node->flags, NACL_EFLAG(ExprJumpTarget)) && node->kind == ExprConstant) { /* Explicit jump value. Check if legal! */ NaClPcAddress target = end + (NaClPcNumber) NaClGetExprSignedValue(node); /* Don't report targets that are out of range. They should have * been reported in the first pass! */ if (NaClCheckAddressRange(target, vstate)) { if (NaClAddressSetContains(vstate->jump_sets.possible_targets, target, vstate)) { if (NaClAddressSetContains(vstate->jump_sets.removed_targets, target, vstate)) { NaClValidatorInstMessage( LOG_ERROR, vstate, vstate->cur_inst_state, "Jumps into middle of nacl pattern\n"); } } else { NaClValidatorInstMessage( LOG_ERROR, vstate, vstate->cur_inst_state, "Doesn't jump to instruction address\n"); } } } } } }