void NCValidateSegment(uint8_t *mbase, NaClPcAddress vbase, NaClMemorySize sz, struct NCValidatorState *vstate) { /* Sanity checks */ /* TODO(ncbray): remove redundant vbase/size args. */ if ((vbase & vstate->bundle_mask) != 0) { ValidatePrintOffsetError(0, "Bad vbase alignment", vstate); NCStatsSegFault(vstate); return; } if (vbase != vstate->iadrbase) { ValidatePrintOffsetError(0, "Mismatched vbase addresses", vstate); NCStatsSegFault(vstate); return; } if (sz != vstate->codesize) { ValidatePrintOffsetError(0, "Mismatched code size", vstate); NCStatsSegFault(vstate); return; } sz = NCHaltTrimSize(mbase, sz, vstate->bundle_size); vstate->codesize = sz; if (sz == 0) { ValidatePrintOffsetError(0, "Bad text segment (zero size)", vstate); NCStatsSegFault(vstate); return; } NCValidateDStateInit(vstate, mbase, vbase, sz); NCDecoderStateDecode(&vstate->dstate); NCDecoderStateDestruct(&vstate->dstate); }
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; }
/* Copies code from src to dest in a thread safe way, returns 1 on success, * returns 0 on error. This will likely assert on error to avoid partially * copied code or undefined state. */ static int NCCopyCode(uint8_t *dst, uint8_t *src, NaClPcAddress vbase, size_t sz, NaClCopyInstructionFunc copy_func) { NCDecoderState dst_dstate; NCDecoderInst dst_inst; NCDecoderState src_dstate; NCDecoderInst src_inst; NCDecoderStatePair pair; int result = 0; NCDecoderStateConstruct(&dst_dstate, dst, vbase, sz, &dst_inst, 1); NCDecoderStateConstruct(&src_dstate, src, vbase, sz, &src_inst, 1); NCDecoderStatePairConstruct(&pair, &dst_dstate, &src_dstate, copy_func); pair.action_fn = CopyInstruction; if (NCDecoderStatePairDecode(&pair)) result = 1; NCDecoderStatePairDestruct(&pair); NCDecoderStateDestruct(&src_dstate); NCDecoderStateDestruct(&dst_dstate); return result; }
void NCDecodeSegment(uint8_t* mbase, NaClPcAddress vbase, NaClMemorySize size) { NCDecoderInst inst; NCDecoderState dstate; NCDecoderStateConstruct(&dstate, mbase, vbase, size, &inst, 1); NCDecoderStateSetErrorReporter(&dstate, &kNCVerboseErrorReporter); /* TODO(karl): Fix this so that we don't need to override the * action function. */ dstate.action_fn = PrintInstLogGio; NCDecoderStateDecode(&dstate); NCDecoderStateDestruct(&dstate); }