// hypercall-initiated taint query of some src-level extent void lava_taint_query (PandaHypercallStruct phs) { extern CPUState *cpu_single_env; CPUState *env = cpu_single_env; if (taintEnabled && (taint2_num_labels_applied() > 0)){ // okay, taint is on and some labels have actually been applied // is there *any* taint on this extent uint32_t num_tainted = 0; for (uint32_t offset=0; offset<phs.len; offset++) { uint32_t va = phs.buf + offset; uint32_t pa = panda_virt_to_phys(env, va); if ((int) pa != -1) { Addr a = make_maddr(pa); if (taint2_query(a)) { num_tainted ++; } } } if (num_tainted) { // ok at least one byte in the extent is tainted // 1. write the pandalog entry that tells us something was tainted on this extent Panda__TaintQueryHypercall *tqh = (Panda__TaintQueryHypercall *) malloc (sizeof (Panda__TaintQueryHypercall)); *tqh = PANDA__TAINT_QUERY_HYPERCALL__INIT; tqh->buf = phs.buf; tqh->len = phs.len; tqh->num_tainted = num_tainted; // obtain the actual data out of memory // NOTE: first 32 bytes only! uint32_t data[32]; uint32_t n = phs.len; if (32 < phs.len) n = 32; for (uint32_t i=0; i<n; i++) { data[i] = 0; uint8_t c; panda_virtual_memory_rw(env, phs.buf+i, &c, 1, false); data[i] = c; } tqh->n_data = n; tqh->data = data; Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT; ple.taint_query_hypercall = tqh; pandalog_write_entry(&ple); free(tqh); // 2. write out src-level info lava_src_info_pandalog(phs); // 3. write out callstack info callstack_pandalog(); // 4. iterate over the bytes in the extent and pandalog detailed info about taint for (uint32_t offset=0; offset<phs.len; offset++) { uint32_t va = phs.buf + offset; uint32_t pa = panda_virt_to_phys(env, va); if ((int) pa != -1) { Addr a = make_maddr(pa); if (taint2_query(a)) { __taint2_query_pandalog(a); } } } } } }
void lava_attack_point(PandaHypercallStruct phs) { Panda__AttackPoint *ap = (Panda__AttackPoint *) malloc (sizeof (Panda__AttackPoint)); *ap = PANDA__ATTACK_POINT__INIT; ap->info = "memcpy"; Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT; ple.attack_point = ap; pandalog_write_entry(&ple); free(ap); // write out src-level info lava_src_info_pandalog(phs); // write out callstack info callstack_pandalog(); }
void tbranch_on_branch_taint2(Addr a) { // a is an llvm reg assert (a.typ == LADDR); // query every byte of this reg for (uint32_t o=0; o<8; o++) { Addr ao =a; ao.off = o; if (taint2_query(ao)) { // branch is tainted Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT; ple.has_tainted_branch = true; ple.tainted_branch = true; pandalog_write_entry(&ple); taint2_query_pandalog(a, o); callstack_pandalog(); } } }
void taint_change(Addr a) { if (taint2_query(a)) { extern CPUState *cpu_single_env; CPUState *env = cpu_single_env; target_ulong asid = panda_current_asid(env); if (asid != last_asid) { Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT; ple.has_asid = 1; ple.asid = asid; pandalog_write_entry(&ple); last_asid = asid; } Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT; ple.tainted_instr = true; pandalog_write_entry(&ple); taint2_query_pandalog(a,0); callstack_pandalog(); } }