Ejemplo n.º 1
0
// 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);
                    }
                }
            }
        }
    }
}
Ejemplo n.º 2
0
// label this virtual address.  might fail, so
// returns true iff byte was labeled
bool label_byte(CPUState *cpu, target_ulong virt_addr, uint32_t label_num) {
    hwaddr pa = panda_virt_to_phys(cpu, virt_addr);
    if (pa == (hwaddr) -1) {
        printf ("label_byte: virtual addr " TARGET_FMT_lx " not available\n", virt_addr);
        return false;
    }
    if (no_taint) {
        // don't print a message -- you'd have too many in this case
        return false;
    }
    if (positional_labels) {
        taint2_label_ram(pa, label_num);
    }
    else {
        taint2_label_ram(pa, 1);
    }
    if (pandalog) {
        Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT;
        ple.has_taint_label_virtual_addr = 1;
        ple.has_taint_label_physical_addr = 1;
        ple.has_taint_label_number = 1;
        ple.taint_label_virtual_addr = virt_addr;
        ple.taint_label_physical_addr = pa;
        if (positional_labels) {
            ple.taint_label_number = label_num;
        }
        else {
            ple.taint_label_number = 1;
        }
        pandalog_write_entry(&ple);
    }
    return true;
}
Ejemplo n.º 3
0
void label_byte(CPUState *env, target_ulong virt_addr, uint32_t label_num) {
    target_phys_addr_t pa = panda_virt_to_phys(env, virt_addr);
    if (pandalog) {
        Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT;
        ple.has_taint_label_virtual_addr = 1;
        ple.has_taint_label_physical_addr = 1;
        ple.has_taint_label_number = 1;
        ple.taint_label_virtual_addr = virt_addr;
        ple.taint_label_physical_addr = pa;
        if (positional_labels) {
            ple.taint_label_number = label_num;
        }
        else {
            ple.taint_label_number = 1;
        }
        pandalog_write_entry(&ple);           
    }
    if (!no_taint) {
        if (positional_labels) {
            taint2_label_ram(pa, label_num);
        }
        else {
            taint2_label_ram(pa, 1);
        }
    }
}
Ejemplo n.º 4
0
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();
    }
}
Ejemplo n.º 5
0
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();
}    
Ejemplo n.º 6
0
// queries taint on this addr and
// if anything is tainted returns 1, else returns 0
// if there is taint, we write an entry to the pandalog. 
uint8_t __taint2_query_pandalog (Addr a) {
    uint8_t saw_taint = 0;
    LabelSetP ls = tp_query(shadow, a);
    if (ls) {
        saw_taint = 1;
        if (ls_returned.count(ls) == 0) {
            // we only want to actually write a particular set contents to pandalog once
            // this ls hasn't yet been written to pandalog
            // write out mapping from ls pointer to labelset contents
            // as its own separate log entry
            ls_returned.insert(ls);
            Panda__TaintQueryUniqueLabelSet *tquls = (Panda__TaintQueryUniqueLabelSet *) malloc (sizeof (Panda__TaintQueryUniqueLabelSet));
            *tquls = PANDA__TAINT_QUERY_UNIQUE_LABEL_SET__INIT;
            tquls->ptr = (uint64_t) ls;
            tquls->n_label = ls_card(ls);
            tquls->label = (uint32_t *) malloc (sizeof(uint32_t) * tquls->n_label);
            el_arr_ind = 0;
            tp_ls_iter(ls, collect_query_labels_pandalog, (void *) tquls->label);
            Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT;
            ple.taint_query_unique_label_set = tquls;
            pandalog_write_entry(&ple);
            free (tquls->label);
            free (tquls);
        }
        // safe to refer to the set by the pointer in this next message
        Panda__TaintQuery *tq = (Panda__TaintQuery *) malloc(sizeof(Panda__TaintQuery));
        *tq = PANDA__TAINT_QUERY__INIT;
        tq->ptr = (uint64_t) ls;
        tq->tcn = taint2_query_tcn(a);
        //        tq->offset = offset;
        Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT;
        ple.taint_query = tq;
        pandalog_write_entry(&ple);
        free(tq);
    }    
    return saw_taint;
}
Ejemplo n.º 7
0
void lava_attack_point(PandaHypercallStruct phs) {
    if (pandalog) {
        Panda__AttackPoint *ap = (Panda__AttackPoint *) malloc (sizeof (Panda__AttackPoint));
        *ap = PANDA__ATTACK_POINT__INIT;
        ap->info = phs.info;
        Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT;
        ple.attack_point = ap;
        ple.attack_point->src_info = pandalog_src_info_create(phs);
        ple.attack_point->call_stack = pandalog_callstack_create();
        pandalog_write_entry(&ple);
        free(ple.attack_point->src_info);
        pandalog_callstack_free(ple.attack_point->call_stack);
        free(ap);
    }
}    
Ejemplo n.º 8
0
void dd_spit(){
    if (pandalog) {
        printf ("computing dead data and writing to pandalog\n");
    }
    else {
        printf ("computing dead data and writing to stdout\n");
    }

    uint32_t *al = taint2_labels_applied();
    uint32_t n = taint2_num_labels_applied();
    for (uint32_t i=0; i<n; i++) {
        uint32_t l = al[i];
        if (dead_data.count(l) == 0) {
            dead_data[l] = 0;
        }
    }
    free(al);

    /*
    for ( auto &kvp : dde ) {
        uint32_t l = kvp.first;
        for ( auto &ins : kvp.second ) {
            dead_data[l] += ((float)(last_tainted_branch - ins) / denom);
            //dead_data[l] ++;
        }
    }
    */


    if (pandalog) {
        Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT;
        ple.n_dead_data = n;
        ple.dead_data =  (float *) malloc(sizeof(float) * n);
        for (uint32_t i=0; i<n; i++) {
            ple.dead_data[i] = dead_data[i];
        }
        pandalog_write_entry(&ple);
    }
    else {
        printf ("\n\n-----------------------------------------\n");
        printf ("Dead Data Summary\n");
        for ( auto &kvp : dead_data ) {
            uint32_t el = kvp.first;
            float val = kvp.second;
            printf ("%6d %0.2f\n", el, val);
        }
    }
}
Ejemplo n.º 9
0
// 3 long sys_read(unsigned int fd, char __user *buf, size_t count);
// typedef void (*on_sys_read_return_t)(CPUState* env,target_ulong pc,uint32_t fd,target_ulong buf,uint32_t count);
void read_return(CPUState* env,target_ulong pc,uint32_t fd,target_ulong buf,uint32_t count) { 

    
    if (saw_read && panda_current_asid(env) == the_asid) {
        count = EAX;
        printf ("count=%d\n", count);
        
        printf ("returning from read of [%s] count=%d\n", taint_filename, count);    
        printf ("*** applying %s taint labels %d..%d to buffer\n",
                positional_labels ? "positional" : "uniform",
                taint_label_number_start, taint_label_number_start + count - 1);
        for (uint32_t i=0; i<count; i++ ) {
            target_phys_addr_t pa = panda_virt_to_phys(env, the_buf+i);
            if (pandalog) {
                Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT;
                ple.has_taint_label_virtual_addr = 1;
                ple.has_taint_label_physical_addr = 1;
                ple.has_taint_label_number = 1;
                ple.taint_label_virtual_addr = the_buf + i;
                ple.taint_label_physical_addr = pa;
                if (positional_labels) {
                    ple.taint_label_number = taint_label_number_start + i;
                }
                else {
                    ple.taint_label_number = 1;
                }
                pandalog_write_entry(&ple);           
            }
            if (!no_taint) {
                if (positional_labels) {
                    if (use_taint2) 
                        taint2_label_ram(pa, taint_label_number_start + i);
                    else 
                        taint_label_ram(pa, i);
                }
                else {
                    if (use_taint2) 
                        taint2_label_ram(pa, 1);
                    else 
                        taint_label_ram(pa, 1);
                }
            }
        }
        taint_label_number_start += count;
        printf (" ... done applying labels\n");
        saw_read = false;
    }
}
Ejemplo n.º 10
0
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();
        }
    }
}
Ejemplo n.º 11
0
void uninit_plugin(void *self) {
    if (summary) {
        Panda__TaintedBranchSummary *tbs = (Panda__TaintedBranchSummary *) malloc(sizeof(Panda__TaintedBranchSummary));
        for (auto kvp : tainted_branch) {
            uint64_t asid = kvp.first;
            for (auto pc : kvp.second) {
                *tbs = PANDA__TAINTED_BRANCH_SUMMARY__INIT;
                tbs->asid = asid;
                tbs->pc = pc;
                Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT;
                ple.tainted_branch_summary = tbs;
                pandalog_write_entry(&ple);
            }
        }
        free(tbs);
    }    
    
}
Ejemplo n.º 12
0
void tbranch_on_branch_taint2(Addr a, uint64_t size) {
    if (pandalog) {
        // a is an llvm reg
        assert (a.typ == LADDR);
        // count number of tainted bytes on this reg
        // NB: assuming 8 bytes
        uint32_t num_tainted = 0;
        for (uint32_t o=0; o<size; o++) {
            Addr ao =a;
            ao.off = o;
            num_tainted += (taint2_query(ao) != 0);
        }
        if (num_tainted > 0) {
            if (summary) {
                CPUState *cpu = first_cpu;
                target_ulong asid = panda_current_asid(cpu);
                tainted_branch[asid].insert(panda_current_pc(cpu));
            }
            else {
                Panda__TaintedBranch *tb = (Panda__TaintedBranch *) malloc(sizeof(Panda__TaintedBranch));
                *tb = PANDA__TAINTED_BRANCH__INIT;
                tb->call_stack = pandalog_callstack_create();
                tb->n_taint_query = num_tainted;
                tb->taint_query = (Panda__TaintQuery **) malloc (sizeof (Panda__TaintQuery *) * num_tainted);
                uint32_t i=0;
                for (uint32_t o=0; o<size; o++) {
                    Addr ao = a;
                    ao.off = o;
                    if (taint2_query(ao)) {
                        tb->taint_query[i++] = taint2_query_pandalog(ao, o);
                    }
                }
                Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT;
                ple.tainted_branch = tb;
                pandalog_write_entry(&ple);
                pandalog_callstack_free(tb->call_stack);
                for (uint32_t i=0; i<num_tainted; i++) {
                    pandalog_taint_query_free(tb->taint_query[i]);
                }
                free(tb);
            }
        }
    }
}
Ejemplo n.º 13
0
void taint_change(Addr a, uint64_t size) {
    for (unsigned i = 0; i < size; i++){
        a.off = i;
        if (taint2_query(a)) {
            
            Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT;
            /*
            ple.has_tainted_instr = true;
            ple.tainted_instr = true;
            pandalog_write_entry(&ple);
            */
            taint2_query_pandalog(a, i);
            ple = PANDA__LOG_ENTRY__INIT;
            ple.call_stack = pandalog_callstack_create();
            pandalog_write_entry(&ple);            
            pandalog_callstack_free(ple.call_stack);
        }
    }
}
Ejemplo n.º 14
0
void lava_src_info_pandalog(PandaHypercallStruct phs) {
    extern CPUState *cpu_single_env;
    CPUState *env = cpu_single_env;
    // write out src-level info    
    Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT;                    
    Panda__SrcInfo *si = (Panda__SrcInfo *) malloc(sizeof(Panda__SrcInfo));
    *si = PANDA__SRC_INFO__INIT;
    char filenameStr[500];
    char astNodeStr[500];
    panda_virtual_string_read(env, phs.src_filename, filenameStr);
    panda_virtual_string_read(env, phs.src_ast_node_name, astNodeStr);
    si->filename = filenameStr;
    si->astnodename = astNodeStr;
    si->linenum = phs.src_linenum;
    ple = PANDA__LOG_ENTRY__INIT;
    ple.src_info = si;
    pandalog_write_entry(&ple);
    free(si);
} 
Ejemplo n.º 15
0
// hypercall-initiated taint query of some src-level extent
void lava_taint_query (Panda__SrcInfoPri *si, target_ulong buf, target_ulong buf_len) {
    extern CPUState *cpu_single_env;
    CPUState *env = cpu_single_env;

    //if  (pandalog && taintEnabled && (taint2_num_labels_applied() > 0)){
    if  (pandalog && taint2_enabled() && (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;
        bool is_strnlen = false;
        //bool is_strnlen = ((int) phs.len == -1);
        uint32_t offset=0;
        while (true) {
        //        for (uint32_t offset=0; offset<phs.len; offset++) {
            uint32_t va = buf + offset;
            //uint32_t va = phs.buf + offset;
            uint32_t pa =  panda_virt_to_phys(env, va);
            if (is_strnlen) {
                uint8_t c;
                panda_virtual_memory_rw(env, pa, &c, 1, false);
                // null terminator
                if (c==0) break;
            }
            if ((int) pa != -1) {
                Addr a = make_maddr(pa);
                if (taint2_query(a)) {
                    num_tainted ++;
                }
            }
            offset ++;
            // end of query by length or max string length
            if (!is_strnlen && offset == buf_len) break;
            //if (!is_strnlen && offset == phs.len) break;
            if (is_strnlen && (offset == LAVA_TAINT_QUERY_MAX_LEN)) break;
        }
        uint32_t len = offset;
        if (num_tainted) {
            printf("logging lava query\n");
            // 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__TaintQueryPri *tqh = (Panda__TaintQueryPri *) malloc (sizeof (Panda__TaintQueryPri));
            *tqh = PANDA__TAINT_QUERY_PRI__INIT;
            tqh->buf = buf;
            //tqh->buf = phs.buf;
            tqh->len = len;
            tqh->num_tainted = num_tainted;
            // obtain the actual data out of memory
            // NOTE: first X bytes only!
            uint32_t data[LAVA_TAINT_QUERY_MAX_LEN];
            uint32_t n = len;
            // grab at most X bytes from memory to pandalog
            // this is just a snippet.  we dont want to write 1M buffer
            if (LAVA_TAINT_QUERY_MAX_LEN < len) n = LAVA_TAINT_QUERY_MAX_LEN;
            for (uint32_t i=0; i<n; i++) {
                data[i] = 0;
                uint8_t c;
                panda_virtual_memory_rw(env, buf+i, &c, 1, false);
                //panda_virtual_memory_rw(env, phs.buf+i, &c, 1, false);
                data[i] = c;
            }
            tqh->n_data = n;
            tqh->data = data;
            // 2. write out src-level info
            //Panda__SrcInfoPri *si = pandalog_src_info_create(phs);
            tqh->src_info = si;
            // 3. write out callstack info
            Panda__CallStack *cs = pandalog_callstack_create();
            tqh->call_stack = cs;
            // 4. iterate over the bytes in the extent and pandalog detailed info about taint
            std::vector<Panda__TaintQuery *> tq;
            for (uint32_t offset=0; offset<len; offset++) {
                uint32_t va = buf + 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)) {
                        tq.push_back(taint2_query_pandalog(a, offset));
                    }
                }
            }
            tqh->n_taint_query = tq.size();
            tqh->taint_query = (Panda__TaintQuery **) malloc(sizeof(Panda__TaintQuery *) * tqh->n_taint_query);
            for (uint32_t i=0; i<tqh->n_taint_query; i++) {
                tqh->taint_query[i] = tq[i];
            }
            Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT;
            ple.taint_query_pri = tqh;
            printf("about to write out taint query entry\n");
            pandalog_write_entry(&ple);
            free(tqh->src_info);
            pandalog_callstack_free(tqh->call_stack);
            for (uint32_t i=0; i<tqh->n_taint_query; i++) {
                pandalog_taint_query_free(tqh->taint_query[i]);
            }
            free(tqh);
        }
    }
}
Ejemplo n.º 16
0
/**
 * @brief Hypercall-initiated taint query of some src-level extent.
 */
void taint_query_hypercall(PandaHypercallStruct phs) {
    CPUState *cpu = first_cpu;
    if  (pandalog && 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;
        bool is_strnlen = ((int) phs.len == -1);
        uint32_t offset=0;
        while (true) {
            uint32_t va = phs.buf + offset;
            uint32_t pa =  panda_virt_to_phys(cpu, va);
            if (is_strnlen) {
                uint8_t c;
                panda_virtual_memory_rw(cpu, pa, &c, 1, false);
                // null terminator
                if (c==0) break;
            }
            if ((int) pa != -1) {
                Addr a = make_maddr(pa);
                if (taint2_query(a)) {
                    num_tainted ++;
                }
            }
            offset ++;
            // end of query by length or max string length
            if (!is_strnlen && offset == phs.len) break;
            if (is_strnlen && (offset == QUERY_HYPERCALL_MAX_LEN)) break;
        }
        uint32_t len = offset;
        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 = len;
            tqh->num_tainted = num_tainted;
            // obtain the actual data out of memory
            // NOTE: first X bytes only!
            uint32_t data[QUERY_HYPERCALL_MAX_LEN];
            uint32_t n = len;
            // grab at most X bytes from memory to pandalog
            // this is just a snippet.  we dont want to write 1M buffer
            if (QUERY_HYPERCALL_MAX_LEN < len) n = QUERY_HYPERCALL_MAX_LEN;
            for (uint32_t i=0; i<n; i++) {
                data[i] = 0;
                uint8_t c;
                panda_virtual_memory_rw(cpu, phs.buf+i, &c, 1, false);
                data[i] = c;
            }
            tqh->n_data = n;
            tqh->data = data;
            // 2. write out src-level info
            Panda__SrcInfo *si = pandalog_src_info_create(phs);
            tqh->src_info = si;
            // 3. write out callstack info
            Panda__CallStack *cs = pandalog_callstack_create();
            tqh->call_stack = cs;
            std::vector<Panda__TaintQuery *> tq;
            for (uint32_t offset=0; offset<len; offset++) {
                uint32_t va = phs.buf + offset;
                uint32_t pa =  panda_virt_to_phys(cpu, va);
                if ((int) pa != -1) {
                    Addr a = make_maddr(pa);
                    if (taint2_query(a)) {
                        tq.push_back(taint2_query_pandalog(a, offset));
                    }
                }
            }
            tqh->n_taint_query = tq.size();
            tqh->taint_query = (Panda__TaintQuery **) malloc(sizeof(Panda__TaintQuery *) * tqh->n_taint_query);
            for (uint32_t i=0; i<tqh->n_taint_query; i++) {
                tqh->taint_query[i] = tq[i];
            }
            Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT;
            ple.taint_query_hypercall = tqh;
            pandalog_write_entry(&ple);
            free(tqh->src_info);
            pandalog_callstack_free(tqh->call_stack);
            for (uint32_t i=0; i<tqh->n_taint_query; i++) {
                pandalog_taint_query_free(tqh->taint_query[i]);
            }
            free(tqh);
        }
    }
}
Ejemplo n.º 17
0
// 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  (pandalog && 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;
            // grab at most 32 bytes from memory to pandalog
            // this is just a snippet.  we dont want to write 1M buffer
            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;
            // 2. write out src-level info
            Panda__SrcInfo *si = pandalog_src_info_create(phs);
            tqh->src_info = si;          
            // 3. write out callstack info
            Panda__CallStack *cs = pandalog_callstack_create();
            tqh->call_stack = cs;
            // 4. iterate over the bytes in the extent and pandalog detailed info about taint
            std::vector<Panda__TaintQuery *> tq;
            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)) {
                        tq.push_back(__taint2_query_pandalog(a, offset));
                    }
                }
            }
            tqh->n_taint_query = tq.size();
            tqh->taint_query = (Panda__TaintQuery **) malloc(sizeof(Panda__TaintQuery *) * tqh->n_taint_query);
            for (uint32_t i=0; i<tqh->n_taint_query; i++) {
                tqh->taint_query[i] = tq[i];
            }
            Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT;
            ple.taint_query_hypercall = tqh;
            pandalog_write_entry(&ple);
            free(tqh->src_info);
            pandalog_callstack_free(tqh->call_stack);
            for (uint32_t i=0; i<tqh->n_taint_query; i++) {
                __pandalog_taint_query_free(tqh->taint_query[i]);
            }
            free(tqh);
        }
    }
}