예제 #1
0
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
예제 #2
0
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
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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
예제 #6
0
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
예제 #7
0
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"
예제 #8
0
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"
예제 #9
0
    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 = [
예제 #10
0
        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])