def trace_suspicious_mem(rep, m, tag="C"): cs = trace_mem(rep, tag, m) data = [ (addr, search.eval_model_expr(m, rep.solv, rep.to_smt_expr(addr, (n, vc))), (n, vc)) for (kind, addr, v, mem, n, vc) in cs ] addr_sets = {} for (addr, addr_v, _) in data: addr_sets.setdefault(addr_v, set()) addr_sets[addr_v].add(addr) dup_addrs = set([addr_v for addr_v in addr_sets if len(addr_sets[addr_v]) > 1]) data = [ (addr, addr_v, guess_pv(rep.p, n, addr), (n, vc)) for (addr, addr_v, (n, vc)) in data if addr_v in dup_addrs ] data = [ (addr, addr_v, eval_pv_type(rep, (n, vc), m, get_pv_type(pv)), rep.to_smt_expr(pv, (n, vc)), n) for (addr, addr_v, pv, (n, vc)) in data ] dup_addr_types = set( [addr_v for addr_v in dup_addrs if len(set([t for (_, addr_v2, t, _, _) in data if addr_v2 == addr_v])) > 1] ) res = [(addr_v, [(t, pv, n) for (_, addr_v2, t, pv, n) in data if addr_v2 == addr_v]) for addr_v in dup_addr_types] for (addr_v, insts) in res: print "Address %s" % addr_v for (t, pv, n) in insts: print " -- accessed with type %s at %s" % (t, n) print " (covered by %s)" % pv return res
def trace_suspicious_mem(rep, m, tag='C'): cs = trace_mem(rep, tag, m) data = [(addr, search.eval_model_expr(m, rep.solv, rep.to_smt_expr(addr, (n, vc))), (n, vc)) for (kind, addr, v, mem, n, vc) in cs] addr_sets = {} for (addr, addr_v, _) in data: addr_sets.setdefault(addr_v, set()) addr_sets[addr_v].add(addr) dup_addrs = set( [addr_v for addr_v in addr_sets if len(addr_sets[addr_v]) > 1]) data = [(addr, addr_v, guess_pv(rep.p, n, addr), (n, vc)) for (addr, addr_v, (n, vc)) in data if addr_v in dup_addrs] data = [(addr, addr_v, eval_pv_type(rep, (n, vc), m, get_pv_type(pv)), rep.to_smt_expr(pv, (n, vc)), n) for (addr, addr_v, pv, (n, vc)) in data] dup_addr_types = set([ addr_v for addr_v in dup_addrs if len(set([t for (_, addr_v2, t, _, _) in data if addr_v2 == addr_v])) > 1 ]) res = [(addr_v, [(t, pv, n) for (_, addr_v2, t, pv, n) in data if addr_v2 == addr_v]) for addr_v in dup_addr_types] for (addr_v, insts) in res: print 'Address %s' % addr_v for (t, pv, n) in insts: print ' -- accessed with type %s at %s' % (t, n) print ' (covered by %s)' % pv return res
def walk_model(rep, tag, m): n_vcs = [(n, vc) for (tag2, n, vc) in rep.node_pc_env_order if tag2 == tag if search.eval_model_expr(m, rep.solv, rep.get_pc(( n, vc), tag)) == syntax.true_term] n_vcs = era_sort(rep, n_vcs) return n_vcs
def eval_str(expr, env, solv, m): expr = solver.to_smt_expr(expr, env, solv) v = search.eval_model_expr(m, solv, expr) if v.typ == syntax.boolT: assert v in [syntax.true_term, syntax.false_term] return v.name elif v.typ.kind == "Word": return solver.smt_num(v.val, v.typ.num) else: assert not "type printable", v
def eval_str(expr, env, solv, m): expr = solver.to_smt_expr(expr, env, solv) v = search.eval_model_expr(m, solv, expr) if v.typ == syntax.boolT: assert v in [syntax.true_term, syntax.false_term] return v.name elif v.typ.kind == 'Word': return solver.smt_num_t(v.val, v.typ) else: assert not 'type printable', v
def walk_model(rep, tag, m): n_vcs = [ (n, vc) for (tag2, n, vc) in rep.node_pc_env_order if tag2 == tag if search.eval_model_expr(m, rep.solv, rep.get_pc((n, vc), tag)) == syntax.true_term ] era_sort(rep, n_vcs) return n_vcs
def add_recursion_ident(f, group, idents, extra_unfolds): from syntax import mk_eq, mk_implies, mk_var p = problem.Problem(None, name='Recursion Test') chain = [] tag = 'fun0' p.add_entry_function(functions[f], tag) p.do_analysis() assns = [] recursion_last_assns[0] = assns while True: res = find_unknown_recursion(p, group, idents, tag, assns, extra_unfolds) if res == None: break if p.nodes[res].fname not in group: problem.inline_at_point(p, res) continue fname = p.nodes[res].fname chain.append(fname) tag = 'fun%d' % len(chain) (args, _, entry) = p.add_entry_function(functions[fname], tag) p.do_analysis() assns += function_link_assns(p, res, tag) if chain == []: return None recursion_trace.append(' created fun chain %s' % chain) word_args = [(i, mk_var(s, typ)) for (i, (s, typ)) in enumerate(args) if typ.kind == 'Word'] rep = rep_graph.mk_graph_slice(p, fast=True) (_, env) = rep.get_node_pc_env((entry, ())) m = {} res = rep.test_hyp_whyps(syntax.false_term, assns, model=m) assert m if find_unknown_recursion(p, group, idents, tag, [], []) == None: idents.setdefault(fname, []) idents[fname].append(syntax.true_term) recursion_trace.append(' found final ident for %s' % fname) return syntax.true_term assert word_args recursion_trace.append(' scanning for ident for %s' % fname) for (i, arg) in word_args: (nm, typ) = functions[fname].inputs[i] arg_smt = solver.to_smt_expr(arg, env, rep.solv) val = search.eval_model_expr(m, rep.solv, arg_smt) if not rep.test_hyp_whyps(mk_eq(arg_smt, val), assns): recursion_trace.append(' discarded %s = 0x%x, not stable' % (nm, val.val)) continue entry_vis = ((entry, ()), tag) ass = rep_graph.eq_hyp((arg, entry_vis), (val, entry_vis)) res = find_unknown_recursion(p, group, idents, tag, assns + [ass], []) if res: fname2 = p.nodes[res].fname recursion_trace.append( ' discarded %s, allows recursion to %s' % (nm, fname2)) continue eq = syntax.mk_eq(mk_var(nm, typ), val) idents.setdefault(fname, []) idents[fname].append(eq) recursion_trace.append(' found ident for %s: %s' % (fname, eq)) return eq assert not "identifying assertion found"
def add_recursion_ident (f, group, idents, extra_unfolds): from syntax import mk_eq, mk_implies, mk_var p = problem.Problem (None, name = 'Recursion Test') chain = [] tag = 'fun0' p.add_entry_function (functions[f], tag) p.do_analysis () assns = [] recursion_last_assns[0] = assns while True: res = find_unknown_recursion (p, group, idents, tag, assns, extra_unfolds) if res == None: break if p.nodes[res].fname not in group: problem.inline_at_point (p, res) continue fname = p.nodes[res].fname chain.append (fname) tag = 'fun%d' % len (chain) (args, _, entry) = p.add_entry_function (functions[fname], tag) p.do_analysis () assns += function_link_assns (p, res, tag) if chain == []: return None recursion_trace.append (' created fun chain %s' % chain) word_args = [(i, mk_var (s, typ)) for (i, (s, typ)) in enumerate (args) if typ.kind == 'Word'] rep = rep_graph.mk_graph_slice (p, fast = True) (_, env) = rep.get_node_pc_env ((entry, ())) m = {} res = rep.test_hyp_whyps (syntax.false_term, assns, model = m) assert m if find_unknown_recursion (p, group, idents, tag, [], []) == None: idents.setdefault (fname, []) idents[fname].append (syntax.true_term) recursion_trace.append (' found final ident for %s' % fname) return syntax.true_term assert word_args recursion_trace.append (' scanning for ident for %s' % fname) for (i, arg) in word_args: (nm, typ) = functions[fname].inputs[i] arg_smt = solver.to_smt_expr (arg, env, rep.solv) val = search.eval_model_expr (m, rep.solv, arg_smt) if not rep.test_hyp_whyps (mk_eq (arg_smt, val), assns): recursion_trace.append (' discarded %s = 0x%x, not stable' % (nm, val.val)) continue entry_vis = ((entry, ()), tag) ass = rep_graph.eq_hyp ((arg, entry_vis), (val, entry_vis)) res = find_unknown_recursion (p, group, idents, tag, assns + [ass], []) if res: fname2 = p.nodes[res].fname recursion_trace.append (' discarded %s, allows recursion to %s' % (nm, fname2)) continue eq = syntax.mk_eq (mk_var (nm, typ), val) idents.setdefault (fname, []) idents[fname].append (eq) recursion_trace.append (' found ident for %s: %s' % (fname, eq)) return eq assert not "identifying assertion found"
p.nodes[pred].cond.visit(vis) match_pvs = [pv for pv in pvs if set.union(*[syntax.get_expr_var_set(v) for v in pv.vals[2:]]) == vs] if len(match_pvs) > 1: match_pvs = [pv for pv in match_pvs if pv.is_op("PArrayValid")] pv = match_pvs[0] return pv def eval_pv_type(rep, (n, vc), m, data): if data[0] == "PValid": return data else: (nm, typ, offs) = data offs = rep.to_smt_expr(offs, (n, vc)) offs = search.eval_model_expr(m, rep.solv, offs) return (nm, typ, offs) def trace_suspicious_mem(rep, m, tag="C"): cs = trace_mem(rep, tag, m) data = [ (addr, search.eval_model_expr(m, rep.solv, rep.to_smt_expr(addr, (n, vc))), (n, vc)) for (kind, addr, v, mem, n, vc) in cs ] addr_sets = {} for (addr, addr_v, _) in data: addr_sets.setdefault(addr_v, set()) addr_sets[addr_v].add(addr) dup_addrs = set([addr_v for addr_v in addr_sets if len(addr_sets[addr_v]) > 1]) data = [
pv for pv in pvs if set.union(*[syntax.get_expr_var_set(v) for v in pv.vals[2:]]) == vs ] if len(match_pvs) > 1: match_pvs = [pv for pv in match_pvs if pv.is_op('PArrayValid')] pv = match_pvs[0] return pv def eval_pv_type(rep, (n, vc), m, data): if data[0] == 'PValid': return data else: (nm, typ, offs) = data offs = rep.to_smt_expr(offs, (n, vc)) offs = search.eval_model_expr(m, rep.solv, offs) return (nm, typ, offs) def trace_suspicious_mem(rep, m, tag='C'): cs = trace_mem(rep, tag, m) data = [(addr, search.eval_model_expr(m, rep.solv, rep.to_smt_expr(addr, (n, vc))), (n, vc)) for (kind, addr, v, mem, n, vc) in cs] addr_sets = {} for (addr, addr_v, _) in data: addr_sets.setdefault(addr_v, set()) addr_sets[addr_v].add(addr) dup_addrs = set( [addr_v for addr_v in addr_sets if len(addr_sets[addr_v]) > 1])