예제 #1
0
/* 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);
  }
}
예제 #2
0
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);
  }
}
예제 #3
0
/* 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");
    }
  }
}
예제 #4
0
void NaClAddressSetAdd(NaClAddressSet set, NaClPcAddress address,
                       NaClValidatorState* state) {
  NaClAddressSetAddInline(set, address, state);
}