예제 #1
0
void NCValidateSegment(uint8_t *mbase, NaClPcAddress vbase, size_t sz,
                       struct NCValidatorState *vstate) {
  if (sz == 0) {
    ValidatePrintError(0, "Bad text segment (zero size)", vstate);
    Stats_SegFault(vstate);
    return;
  }
  GetCPUFeatures(&(vstate->cpufeatures));
  /* The name of the flag is misleading; f_386 requires not just    */
  /* 386 instructions but also the CPUID instruction is supported.  */
  if (!vstate->cpufeatures.f_386) {
    ValidatePrintError(0, "CPU does not support CPUID", vstate);
    Stats_BadCPU(vstate);
    return;
  }
#if (0)
  /* TODO(bradchen): enable this check */
  if (!vstate->cpufeatures.f_whitelisted) {
    ValidatePrintError(0, "CPU does not support CPUID", vstate);
    Stats_BadCPU(vstate);
    return;
  }
#endif
  NCDecodeSegment(mbase, vbase, sz, vstate);
}
예제 #2
0
static void BadInstructionError(const struct NCDecoderState *mstate,
                                const char *msg) {
  ValidatePrintError(mstate->inst.vaddr, msg, mstate->vstate);
  if (mstate->vstate->do_stub_out) {
    memset(mstate->inst.maddr, kNaClFullStop, mstate->inst.length);
  }
}
예제 #3
0
static void ValidateCallAlignment(const struct NCDecoderState *mstate) {
  NaClPcAddress fallthru = mstate->inst.vaddr + mstate->inst.length;
  if (fallthru & mstate->vstate->alignmask) {
    ValidatePrintError(mstate->inst.vaddr, "Bad call alignment",
                       mstate->vstate);
    /* This makes bad call alignment a fatal error. */
    Stats_BadAlignment(mstate->vstate);
  }
}
예제 #4
0
static void ForgetIP(const NaClPcAddress ip,
                     struct NCValidatorState *vstate) {
  NaClMemorySize ioffset =  ip - vstate->iadrbase;
  if (ip < vstate->iadrbase || ip >= vstate->iadrlimit) {
    ValidatePrintError(ip, "JUMP TARGET out of range in ForgetIP", vstate);
    Stats_BadTarget(vstate);
    return;
  }
  ClearAdrTable(ioffset, vstate->vttable);
}
예제 #5
0
int NCValidateFinish(struct NCValidatorState *vstate) {
  uint32_t offset;
  if (vstate == NULL) {
    vprint(("validator not initialized. Did you call ncvalidate_init()?\n"));
    /* non-zero indicates failure */
    return 1;
  }
  dprint(("CheckTargets: %x-%x\n", vstate->iadrbase, vstate->iadrlimit));
  for (offset = 0;
       offset < vstate->iadrlimit - vstate->iadrbase;
       offset += 1) {
    if (GetAdrTable(offset, vstate->kttable)) {
      /* printf("CheckTarget %x\n", offset + iadrbase); */
      Stats_CheckTarget(vstate);
      if (!GetAdrTable(offset, vstate->vttable)) {
        ValidatePrintError(vstate->iadrbase + offset,
                           "Bad jump target", vstate);
        Stats_BadTarget(vstate);
      }
    }
  }
  /* check basic block boundaries */
  if (vstate->iadrbase & vstate->alignmask) {
    /* This should never happen because the alignment of iadrbase is */
    /* checked in NCValidateInit(). */
    ValidatePrintError(vstate->iadrbase, "Bad base address alignment", vstate);
    Stats_BadAlignment(vstate);
  }
  for (offset = 0; offset < vstate->iadrlimit - vstate->iadrbase;
       offset += vstate->alignment) {
    if (!GetAdrTable(offset, vstate->vttable)) {
      ValidatePrintError(vstate->iadrbase + offset,
                         "Bad basic block alignment", vstate);
      Stats_BadAlignment(vstate);
    }
  }
  fflush(stdout);

  /* Now that all the work is done, generate return code. */
  /* Return zero if there are no problems.                */
  return (vstate->stats.sawfailure);
}
예제 #6
0
/*
 * (Same as NCValidateSegment, but operates on a pair of instructions.)
 * Validates that instructions at mbase_new may replace mbase_old.
 */
void NCValidateSegmentPair(uint8_t *mbase_old, uint8_t *mbase_new,
                           NaClPcAddress vbase, size_t sz,
                           struct NCValidatorState *vstate) {
  if (sz == 0) {
    ValidatePrintError(0, "Bad text segment (zero size)", vstate);
    Stats_SegFault(vstate);
    return;
  }
  GetCPUFeatures(&(vstate->cpufeatures));
  /* The name of the flag is misleading; f_386 requires not just    */
  /* 386 instructions but also the CPUID instruction is supported.  */
  if (!vstate->cpufeatures.f_386) {
    ValidatePrintError(0, "CPU does not support CPUID", vstate);
    Stats_BadCPU(vstate);
    return;
  }

  NCDecodeSegmentPair(mbase_old, mbase_new, vbase, sz,
                      vstate, ValidateInstReplacement);
}
예제 #7
0
static void RememberTP(const NaClPcAddress src, NaClPcAddress target,
                       struct NCValidatorState *vstate) {
  const NaClMemorySize ioffset =  target - vstate->iadrbase;

  if (vstate->iadrbase <= target && target < vstate->iadrlimit) {
    /* Remember address for checking later. */
    SetAdrTable(ioffset, vstate->kttable);
  }
  else if ((target & vstate->alignmask) == 0) {
    /* Allow bundle-aligned jumps. */
  }
  else {
    ValidatePrintError(src, "JUMP TARGET out of range", vstate);
    Stats_BadTarget(vstate);
  }
}
예제 #8
0
static void RememberIP(const NaClPcAddress ip,
                       struct NCValidatorState *vstate) {
  const NaClMemorySize ioffset =  ip - vstate->iadrbase;
  if (ip < vstate->iadrbase || ip >= vstate->iadrlimit) {
    ValidatePrintError(ip, "JUMP TARGET out of range in RememberIP", vstate);
    Stats_BadTarget(vstate);
    return;
  }
  if (GetAdrTable(ioffset, vstate->vttable)) {
    vprint(("RememberIP: Saw inst at %"NACL_PRIxNaClPcAddressAll
            " twice\n", ip));
    Stats_InternalError(vstate);
    return;
  }
  Stats_Inst(vstate);
  SetAdrTable(ioffset, vstate->vttable);
}
예제 #9
0
static void ValidatePrintOffsetError(const NaClPcAddress addr,
                                     const char *msg,
                                     struct NCValidatorState *vstate) {
  ValidatePrintError(vstate->iadrbase + addr, msg, vstate);
}
예제 #10
0
static void ValidatePrintInstructionError(const struct NCDecoderInst *dinst,
                                          const char *msg,
                                          struct NCValidatorState *vstate) {
  ValidatePrintError(NCPrintableInstructionAddress(dinst), msg, vstate);
}