diff --git a/src/experiments/l4-sys/UDIS86.cc b/src/experiments/l4-sys/UDIS86.cc index 368ffafd..317f5997 100644 --- a/src/experiments/l4-sys/UDIS86.cc +++ b/src/experiments/l4-sys/UDIS86.cc @@ -10,7 +10,6 @@ Udis86::Udis86(unsigned char const *instr, size_t size, address_t ip) { memcpy(udis_instr, instr, udis_instr_size); // initialise the internal data structure - memset(&ud_obj, 0, sizeof(ud_t)); ud_init(&ud_obj); ud_set_mode(&ud_obj, 32); ud_set_syntax(&ud_obj, UD_SYN_ATT); diff --git a/src/experiments/l4-sys/campaign.cc b/src/experiments/l4-sys/campaign.cc index 639deaa9..9576b533 100644 --- a/src/experiments/l4-sys/campaign.cc +++ b/src/experiments/l4-sys/campaign.cc @@ -60,13 +60,12 @@ std::string L4SysCampaign::output_register(L4SysProtoMsg_RegisterType res) { bool L4SysCampaign::run() { Logger log("L4SysCampaign"); -#if 0 ifstream test(results_csv); if (test.is_open()) { log << results_csv << " already exists" << endl; return false; } -#endif + ofstream results(results_csv); if (!results.is_open()) { log << "failed to open " << results_csv << endl; @@ -78,7 +77,7 @@ bool L4SysCampaign::run() { int count = 0; srand(time(NULL)); - for (int i = 0; i < 1000; ++i) { + for (int i = 0; i < 20000; ++i) { L4SysExperimentData *d = new L4SysExperimentData; d->msg.set_exp_type(d->msg.GPRFLIP); // affect a random register @@ -95,7 +94,7 @@ bool L4SysCampaign::run() { campaignmanager.addParam(d); ++count; } - for (int i = 0; i < 1000; ++i) { + for (int i = 0; i < 20000; ++i) { L4SysExperimentData *d = new L4SysExperimentData; d->msg.set_exp_type(d->msg.ALUINSTR); // modify for a random instruction @@ -107,7 +106,7 @@ bool L4SysCampaign::run() { campaignmanager.addParam(d); ++count; } - for (int i = 0; i < 1000; ++i) { + for (int i = 0; i < 20000; ++i) { L4SysExperimentData *d = new L4SysExperimentData; d->msg.set_exp_type(d->msg.IDCFLIP); // modify for a random instruction @@ -120,7 +119,7 @@ bool L4SysCampaign::run() { campaignmanager.addParam(d); ++count; } - for (int i = 0; i < 1000; ++i) { + for (int i = 0; i < 20000; ++i) { L4SysExperimentData *d = new L4SysExperimentData; d->msg.set_exp_type(d->msg.RATFLIP); // modify for a random instruction diff --git a/src/experiments/l4-sys/experiment.cc b/src/experiments/l4-sys/experiment.cc index 2583c538..e1824eef 100644 --- a/src/experiments/l4-sys/experiment.cc +++ b/src/experiments/l4-sys/experiment.cc @@ -434,9 +434,23 @@ bool L4SysExperiment::run() { // do the logging logInjection(log, param); } else if (exp_type == param.msg.RATFLIP) { - bxInstruction_c *currInstr = simulator.getCurrentInstruction(); - Udis86 udis(calculateInstructionAddress(), currInstr->ilen(), injection_ip); - if (udis.fetchNextInstruction()) { + ud_type_t which = UD_NONE; + unsigned rnd = 0; + do { + bxInstruction_c *currInstr = simulator.getCurrentInstruction(); + Udis86 udis(calculateInstructionAddress(), currInstr->ilen(), injection_ip); + if (!udis.fetchNextInstruction()) { + param.msg.set_resulttype(param.msg.UNKNOWN); + param.msg.set_resultdata( + simulator.getRegisterManager().getInstructionPointer()); + param.msg.set_output(sanitised(output.c_str())); + + stringstream ss; + ss << "Could not decode instruction using UDIS86" << endl; + param.msg.set_details(ss.str()); + m_jc.sendResult(param); + simulator.terminate(32); + } ud_t _ud = udis.getCurrentState(); /* start Bjoern Doebel's code (slightly modified) */ @@ -468,74 +482,77 @@ bool L4SysExperiment::run() { } } - ud_type_t which; - unsigned rnd; - if (opcount == 0) - rnd = 0; - else + if (opcount == 0) { + // try the next instruction + singleStep(); + } else { + // assign the necessary variables rnd = rand() % opcount; - if (operands[rnd] > RAT_IDX_OFFSET) { - which = _ud.operand[operands[rnd] - RAT_IDX_OFFSET].index; - } else { - which = _ud.operand[operands[rnd]].base; + if (operands[rnd] > RAT_IDX_OFFSET) { + which = _ud.operand[operands[rnd] - RAT_IDX_OFFSET].index; + } else { + which = _ud.operand[operands[rnd]].base; + } } /* ============================================ */ /* end Bjoern Doebel's code (slightly modified) */ - if (which != UD_NONE) { - // so we are able to flip the associated registers - // for details on the algorithm, see Bjoern Doebel's SWIFI/RATFlip class + } while (which == UD_NONE); - // some declarations - GPRegisterId bochs_reg = Udis86::udisGPRToFailBochsGPR(which); - int exchg_reg = -1; - RegisterManager &rm = simulator.getRegisterManager(); + // so we are able to flip the associated registers + // for details on the algorithm, see Bjoern Doebel's SWIFI/RATFlip class - // first, decide if the fault hits a register bound to this thread - // (ten percent chance) - if (rand() % 10) { - // assure exchange of registers - exchg_reg = rand() % 7; - if (exchg_reg == bochs_reg) - exchg_reg++; + // some declarations + GPRegisterId bochs_reg = Udis86::udisGPRToFailBochsGPR(which); + int exchg_reg = -1; + RegisterManager &rm = simulator.getRegisterManager(); - } - - // prepare the fault - regdata_t data = rm.getRegister(bochs_reg)->getData(); - if (rnd > 0) { - //input register - do the fault injection here - regdata_t newdata = 0; - if (exchg_reg >= 0) { - newdata = rm.getRegister(exchg_reg)->getData(); - } else { - newdata = rand(); - } - rm.getRegister(bochs_reg)->setData(newdata); - } - - // execute the instruction - singleStep(); - - // restore - if (rnd == 0) { - // output register - do the fault injection here - if (exchg_reg >= 0) { - // write the result into the wrong local register - regdata_t newdata = rm.getRegister(bochs_reg)->getData(); - rm.getRegister(exchg_reg)->setData(newdata); - } - } - // restore the actual value of the register - // in reality, it would never have been overwritten - rm.getRegister(bochs_reg)->setData(data); - - // and log the injection - logInjection(log, param); - } + // first, decide if the fault hits a register bound to this thread + // (ten percent chance) + if (rand() % 10 == 0) { + // assure exchange of registers + exchg_reg = rand() % 7; + if (exchg_reg == bochs_reg) + exchg_reg++; } + + // prepare the fault + regdata_t data = rm.getRegister(bochs_reg)->getData(); + if (rnd > 0) { + //input register - do the fault injection here + regdata_t newdata = 0; + if (exchg_reg >= 0) { + // the data is taken from a process register chosen before + newdata = rm.getRegister(exchg_reg)->getData(); + } else { + // the data comes from an uninitialised register + newdata = rand(); + } + rm.getRegister(bochs_reg)->setData(newdata); + } + + // execute the instruction + singleStep(); + + // restore + if (rnd == 0) { + // output register - do the fault injection here + if (exchg_reg >= 0) { + // write the result into the wrong local register + regdata_t newdata = rm.getRegister(bochs_reg)->getData(); + rm.getRegister(exchg_reg)->setData(newdata); + } + // otherwise, just assume it is stored in an unused register + } + // restore the actual value of the register + // in reality, it would never have been overwritten + rm.getRegister(bochs_reg)->setData(data); + + // and log the injection + logInjection(log, param); + } else if (exp_type == param.msg.ALUINSTR) { static BochsALUInstructions aluInstrObject(aluInstructions, aluInstructionsSize); // find the closest ALU instruction after the current IP