Skip to content

Commit 62ea2d9

Browse files
authored
Merge pull request diffblue#397 from diffblue/more_reduced_domain_size_and_improved_accuracy_for_undefined_functions
SEC-368: Improved accuracy when undefined functions are present and more reduced size of taint analysis domain
2 parents 46da5ec + b5c0951 commit 62ea2d9

File tree

2 files changed

+31
-67
lines changed

2 files changed

+31
-67
lines changed

src/taint-analysis/taint_summary.cpp

+29-66
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,8 @@ bool taint_algorithm_computing_summary_of_functiont::
429429
const exprt &expr,
430430
const instruction_iteratort &it,
431431
local_value_set_analysist &lvsa,
432-
lvalue_numbers_sett &result)
432+
lvalue_numbers_sett &result,
433+
const bool generate_fresh_evs)
433434
{
434435
TMPROF_BLOCK();
435436

@@ -444,7 +445,7 @@ bool taint_algorithm_computing_summary_of_functiont::
444445
*numbering,
445446
raw_result,
446447
singular);
447-
if(raw_result.empty())
448+
if(generate_fresh_evs && raw_result.empty())
448449
{
449450
external_value_set_exprt new_lhs(
450451
query_expr.type(),
@@ -472,7 +473,7 @@ bool taint_algorithm_computing_summary_of_functiont::
472473
{
473474
if(
474475
!collect_lvsa_access_paths_extended(
475-
member_expr->compound(), it, lvsa, result))
476+
member_expr->compound(), it, lvsa, result, generate_fresh_evs))
476477
{
477478
singular = false;
478479
}
@@ -775,32 +776,21 @@ void taint_algorithm_computing_summary_of_functiont::initialise_domain(
775776
if(it->type==ASSIGN)
776777
{
777778
const code_assignt &asgn = to_code_assign(it->code);
778-
collect_lvsa_access_paths_extended(asgn.lhs(), it, lvsa, environment);
779-
collect_lvsa_access_paths_extended(asgn.lhs(), it, lvsa, written);
780-
if(asgn.rhs().id()==ID_side_effect)
779+
collect_lvsa_access_paths_extended(
780+
asgn.lhs(), it, lvsa, environment, false);
781+
collect_lvsa_access_paths_extended(
782+
asgn.lhs(), it, lvsa, written, false);
783+
if(asgn.rhs().id() != ID_side_effect)
781784
{
782-
const side_effect_exprt see=to_side_effect_expr(asgn.rhs());
783-
if(see.get_statement()==ID_nondet)
784-
{
785-
const auto replace_it=
786-
program->get_NONDET_retvals_replacements().find(it);
787-
if(replace_it != program->get_NONDET_retvals_replacements().cend())
788-
{
789-
collect_lvsa_access_paths_extended(
790-
replace_it->second, it, lvsa, environment);
791-
}
792-
else
793-
{
794-
// This must be a NONDET assignment not relating to a stub function,
795-
// for example initialising an input parameter in __CPROVER_start.
796-
}
797-
}
785+
collect_lvsa_access_paths_extended(
786+
asgn.rhs(), it, lvsa, environment, false);
798787
}
799-
else
800-
collect_lvsa_access_paths_extended(asgn.rhs(), it, lvsa, environment);
801788
}
802789
else if(it->type == ASSERT)
803-
collect_lvsa_access_paths_extended(it->guard, it, lvsa, environment);
790+
{
791+
collect_lvsa_access_paths_extended(
792+
it->guard, it, lvsa, environment, false);
793+
}
804794
else if(it->type==FUNCTION_CALL)
805795
{
806796
const code_function_callt &fn_call = to_code_function_call(it->code);
@@ -809,8 +799,6 @@ void taint_algorithm_computing_summary_of_functiont::initialise_domain(
809799
// Can't handle call by pointer, etc
810800
continue;
811801
irep_idt callee_id = to_symbol_expr(callee_expr).get_identifier();
812-
const auto &fn_type=
813-
program->get_functions().function_map.at(callee_id).type;
814802

815803
if(!database.contains(callee_id) || transition_rules->has_rule(callee_id))
816804
{
@@ -824,50 +812,15 @@ void taint_algorithm_computing_summary_of_functiont::initialise_domain(
824812
// In the future we could be more precise about exactly which arguments
825813
// are used in the rule.
826814
for(const auto &arg : fn_call.arguments())
827-
collect_lvsa_access_paths_extended(arg, it, lvsa, environment);
815+
{
816+
collect_lvsa_access_paths_extended(
817+
arg, it, lvsa, environment, false);
818+
}
828819
if(!database.contains(callee_id))
829820
continue;
830821
}
831822

832823
const std::shared_ptr<taint_summaryt> summary = database.at(callee_id);
833-
for(const std::pair<taint_lvalue_numbert, taint_variablet>& input
834-
: summary->input)
835-
{
836-
if(symbol_utilst(program->get_namespace())
837-
.is_parameter(numbering->at(input.first)))
838-
{
839-
// Collect access paths for the corresponding actual argument:
840-
parameter_matches_id match(
841-
to_symbol_expr(numbering->at(input.first))
842-
.get_identifier());
843-
auto findit=std::find_if(
844-
fn_type.parameters().begin(),
845-
fn_type.parameters().end(),
846-
match);
847-
assert(findit!=fn_type.parameters().end() &&
848-
"Parameter symbol doesn't match?");
849-
const auto paramidx=
850-
std::distance(fn_type.parameters().begin(), findit);
851-
collect_lvsa_access_paths_extended(
852-
fn_call.arguments()[paramidx], it, lvsa, environment);
853-
}
854-
else if(!symbol_utilst(program->get_namespace()).is_parameter(
855-
numbering->at(input.first)) &&
856-
!symbol_utilst(program->get_namespace())
857-
.is_return_value_auxiliary(numbering->at(input.first)))
858-
{
859-
environment.insert(input.first);
860-
}
861-
if(numbering->at(input.first).id()==ID_external_value_set)
862-
{
863-
const auto& evse=to_external_value_set(
864-
numbering->at(input.first));
865-
if(evse.access_path_entries().size()==1)
866-
numbering_map
867-
->get_object_numbers_by_field()[as_string(function_id)]
868-
.insert({ evse.access_path_entries().back().label(), {} });
869-
}
870-
}
871824
for(const std::pair<taint_lvalue_numbert, taint_sett> &lvalue_taint:
872825
summary->output)
873826
written.insert(lvalue_taint.first);
@@ -1599,6 +1552,16 @@ void taint_algorithm_computing_summary_of_functiont::
15991552
}
16001553
summary.input = std::move(pruned_input);
16011554

1555+
#ifndef NDEBUG // Ignore the check below in a non-debug build.
1556+
{
1557+
taint_variable_sett input_vars;
1558+
for(const auto &input_var : summary.input)
1559+
input_vars.insert(input_var.second);
1560+
for(const auto &end_var : end_values_taint.get_vars())
1561+
INVARIANT(input_vars.count(end_var), "Out var must be present in input.");
1562+
}
1563+
#endif
1564+
16021565
const goto_functiont &func_ref =
16031566
program->get_functions().function_map.at(fn_id);
16041567
const code_typet &fn_type = to_code_type(func_ref.type);

src/taint-analysis/taint_summary.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,8 @@ class taint_algorithm_computing_summary_of_functiont
210210
const exprt &expr,
211211
const instruction_iteratort &it,
212212
local_value_set_analysist &lvsa,
213-
lvalue_numbers_sett &result);
213+
lvalue_numbers_sett &result,
214+
const bool generate_fresh_evs = true);
214215

215216
numbered_lvalue_to_taint_mapt join(
216217
const numbered_lvalue_to_taint_mapt &a,

0 commit comments

Comments
 (0)