コード例 #1
0
int NCValidateSegmentPair(uint8_t *mbase_old, uint8_t *mbase_new,
                          NaClPcAddress vbase, size_t sz,
                          const NaClCPUFeaturesX86 *features) {
  /* TODO(karl): Refactor to use inheritance from NCDecoderStatePair? */
  NCDecoderStatePair pair;
  NCValidatorState* new_vstate;
  NCValidatorState* old_vstate;

  int result = 0;

  /* Verify that we actually have a segment to walk. */
  if (sz == 0) {
    printf("VALIDATOR: %"NACL_PRIxNaClPcAddress
           ": Bad text segment (zero size)\n", vbase);
    return 0;
  }

  old_vstate = NCValidateInit(vbase, sz, FALSE, features);
  if (old_vstate != NULL) {
    NCValidateDStateInit(old_vstate, mbase_old, vbase, sz);
    new_vstate = NCValidateInit(vbase, sz, FALSE, features);
    if (new_vstate != NULL) {
      NCValidateDStateInit(new_vstate, mbase_new, vbase, sz);

      NCDecoderStatePairConstruct(&pair,
                                  &old_vstate->dstate,
                                  &new_vstate->dstate,
                                  NULL);  /* copy_func */
      pair.action_fn = ValidateInstReplacement;
      if (NCDecoderStatePairDecode(&pair)) {
        result = 1;
      } else {
        ValidatePrintOffsetError(0, "Replacement not applied!\n", new_vstate);
      }
      if (NCValidateFinish(new_vstate)) {
        /* Errors occurred during validation. */
        result = 0;
      }
      NCDecoderStatePairDestruct(&pair);
      NCDecoderStateDestruct(&new_vstate->dstate);
      NCValidateFreeState(&new_vstate);
    }
    NCDecoderStateDestruct(&old_vstate->dstate);
    NCValidateFreeState(&old_vstate);
  }
  return result;
}
コード例 #2
0
static void FixUpSection(uintptr_t load_address,
                         unsigned char *code,
                         size_t code_size) {
  struct NCValidatorState *vstate;
  int bundle_size = 32;
  vstate = NCValidateInit(load_address, load_address + code_size, bundle_size);
  CHECK(vstate != NULL);
  vstate->do_stub_out = 1;

  /*
   * We should not stub out any instructions based on the features
   * of the CPU we are executing on now.
   */
  memset(&vstate->cpufeatures, 0xff, sizeof(vstate->cpufeatures));

  NCDecodeSegment(code, load_address, code_size, vstate);
  /*
   * We do not need to call NCValidateFinish() because it is
   * normal for validation to fail.
   */
  NCValidateFreeState(&vstate);
}
コード例 #3
0
static NaClValidationStatus ApplyValidator_x86_32(
    uintptr_t guest_addr,
    uint8_t *data,
    size_t size,
    int stubout_mode,
    int readonly_text,
    const NaClCPUFeatures *f,
    const struct NaClValidationMetadata *metadata,
    struct NaClValidationCache *cache) {
  /* TODO(jfb) Use a safe cast here. */
  const NaClCPUFeaturesX86 *cpu_features = (NaClCPUFeaturesX86 *) f;
  struct NCValidatorState *vstate;
  int validator_result = 0;
  void *query = NULL;

  /* Check that the given parameter values are supported. */
  if (stubout_mode && readonly_text)
    return NaClValidationFailedNotImplemented;

  if (!NaClArchSupportedX86(cpu_features))
    return NaClValidationFailedCpuNotSupported;

  /* Don't cache in stubout mode. */
  if (stubout_mode)
    cache = NULL;

  /* If the validation caching interface is available, perform a query. */
  if (cache != NULL)
    query = cache->CreateQuery(cache->handle);
  if (query != NULL) {
    const char validator_id[] = "x86-32";
    cache->AddData(query, (uint8_t *) validator_id, sizeof(validator_id));
    cache->AddData(query, (uint8_t *) cpu_features, sizeof(*cpu_features));
    NaClAddCodeIdentity(data, size, metadata, cache, query);
    if (cache->QueryKnownToValidate(query)) {
      cache->DestroyQuery(query);
      return NaClValidationSucceeded;
    }
  }

  /* Init then validator state. */
  /* TODO(ncbray) make "detailed" a parameter. */
  if (stubout_mode) {
    vstate = NCValidateInitDetailed(guest_addr, size, cpu_features);
  } else {
    vstate = NCValidateInit(guest_addr, size, readonly_text, cpu_features);
  }
  if (vstate == NULL) {
    if (query != NULL)
      cache->DestroyQuery(query);
    return NaClValidationFailedOutOfMemory;
  }
  NCValidateSetStubOutMode(vstate, stubout_mode);

  /* Validate. */
  NCValidateSegment(data, guest_addr, size, vstate);
  validator_result = NCValidateFinish(vstate);

  /* Cache the result if validation succeeded and the code was not modified. */
  if (query != NULL) {
    if (validator_result == 0 && !NCValidatorDidStubOut(vstate))
      cache->SetKnownToValidate(query);
    cache->DestroyQuery(query);
  }

  NCValidateFreeState(&vstate);
  return (validator_result == 0 || stubout_mode)
      ? NaClValidationSucceeded : NaClValidationFailed;
}