aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer/program-state.cc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2019-12-13 19:48:06 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2020-01-14 18:47:22 -0500
commitef7827b0bd7cd980da625fcd12e6c56f51a166c2 (patch)
tree7b501f4af72a1259ff2454de2b4569a221c6bbc4 /gcc/analyzer/program-state.cc
parent14f9d7b9a708ebca57257059bda40986bb1e82a7 (diff)
downloadgcc-ef7827b0bd7cd980da625fcd12e6c56f51a166c2.zip
gcc-ef7827b0bd7cd980da625fcd12e6c56f51a166c2.tar.gz
gcc-ef7827b0bd7cd980da625fcd12e6c56f51a166c2.tar.bz2
analyzer: purge state for unknown function calls
Whilst analyzing the reproducer for detecting CVE-2005-1689 (krb5-1.4.1's src/lib/krb5/krb/recvauth.c), the analyzer reports a false double-free of the form: krb5_xfree(inbuf.data); krb5_read_message(..., &inbuf); krb5_xfree(inbuf.data); /* false diagnostic here. */ where the call to krb5_read_message overwrites inbuf.data with a freshly-malloced buffer. This patch fixes the issue by purging state more thorougly when handling a call with unknown behavior, by walking the graph of memory regions that are reachable from the call. gcc/analyzer/ChangeLog: * analyzer.h (fndecl_has_gimple_body_p): New decl. * engine.cc (impl_region_model_context::on_unknown_change): New function. (fndecl_has_gimple_body_p): Make non-static. (exploded_node::on_stmt): Treat __analyzer_dump_exploded_nodes as known. Track whether we have a call with unknown side-effects and pass it to on_call_post. * exploded-graph.h (impl_region_model_context::on_unknown_change): New decl. * program-state.cc (sm_state_map::on_unknown_change): New function. * program-state.h (sm_state_map::on_unknown_change): New decl. * region-model.cc: Include "bitmap.h". (region_model::on_call_pre): Return a bool, capturing whether the call has unknown side effects. (region_model::on_call_post): Add arg "bool unknown_side_effects" and if true, call handle_unrecognized_call. (class reachable_regions): New class. (region_model::handle_unrecognized_call): New function. * region-model.h (region_model::on_call_pre): Return a bool. (region_model::on_call_post): Add arg "bool unknown_side_effects". (region_model::handle_unrecognized_call): New decl. (region_model_context::on_unknown_change): New vfunc. (test_region_model_context::on_unknown_change): New function. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/data-model-1.c: Remove xfail. * gcc.dg/analyzer/data-model-5b.c: Likewise. * gcc.dg/analyzer/data-model-5c.c: Likewise. * gcc.dg/analyzer/setjmp-3.c: Mark "foo" as pure. * gcc.dg/analyzer/setjmp-4.c: Likewise. * gcc.dg/analyzer/setjmp-6.c: Likewise. * gcc.dg/analyzer/setjmp-7.c: Likewise. * gcc.dg/analyzer/setjmp-7a.c: Likewise. * gcc.dg/analyzer/setjmp-8.c: Likewise. * gcc.dg/analyzer/setjmp-9.c: Likewise. * gcc.dg/analyzer/unknown-fns.c: New test.
Diffstat (limited to 'gcc/analyzer/program-state.cc')
-rw-r--r--gcc/analyzer/program-state.cc8
1 files changed, 8 insertions, 0 deletions
diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc
index 04346ae..c9b595e 100644
--- a/gcc/analyzer/program-state.cc
+++ b/gcc/analyzer/program-state.cc
@@ -480,6 +480,14 @@ sm_state_map::on_cast (svalue_id src_sid,
impl_set_state (dst_sid, state, get_origin (src_sid));
}
+/* Purge state from SID (in response to a call to an unknown function). */
+
+void
+sm_state_map::on_unknown_change (svalue_id sid)
+{
+ impl_set_state (sid, (state_machine::state_t)0, svalue_id::null ());
+}
+
/* Assert that this object is sane. */
void