From e45388413f91afb4885b192249f05de213d2e19f Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 26 Sep 2019 16:55:17 -0400 Subject: [PATCH 55/61] FIXME: cover-letter.txt --- cover-letter.txt | 269 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 cover-letter.txt diff --git a/cover-letter.txt b/cover-letter.txt new file mode 100644 index 0000000..080e27f --- /dev/null +++ b/cover-letter.txt @@ -0,0 +1,269 @@ +Add a static analysis framework to GCC + +This patch kit introduces a static analysis pass for GCC that can diagnose +various kinds of problems in C code at compile-time (e.g. double-free, +use-after-free, etc). + +The analyzer finds "interesting" interprocedural paths through the user's +code, and compares them against simple API descriptions based on pattern +matching and state machines (so it ought to be relatively easy to add +new warnings). + +For example: + +(TODO) + +The patch kit also expands GCC's diagnostic subsystem in various ways: + +(a) adding the ability to associate a "diagnostic path" with a diagnostic, +describing a sequence of events predicted by the compiler that +lead to the problem occurring, with their locations in the user's source, +and text descriptions. + +For example, the following (hypothetical) error has a 3-event path: + + test.c: In function 'make_a_list_of_random_ints_badly': + test.c:29:5: error: passing NULL as argument 1 to 'PyList_Append' which + requires a non-NULL parameter + 29 | PyList_Append(list, item); + | ^~~~~~~~~~~~~~~~~~~~~~~~~ + 'make_a_list_of_random_ints_badly': events 1-3 + | + | 25 | list = PyList_New(0); + | | ^~~~~~~~~~~~~ + | | | + | | (1) when 'PyList_New' fails, returning NULL + | 26 | + | 27 | for (i = 0; i < count; i++) { + | | ~~~ + | | | + | | (2) when 'i < count' + | 28 | item = PyLong_FromLong(random()); + | 29 | PyList_Append(list, item); + | | ~~~~~~~~~~~~~~~~~~~~~~~~~ + | | | + | | (3) when calling 'PyList_Append', passing NULL as argument 1 + | + +The diagnostic-printing code has consolidated the path into a single +run of events, since all the events are near each other and within the same +function; more complicated examples (such as interprocedural paths) +might be printed as multiple runs of events. + +(b) adding the ability to associate additional metadata with a diagnostic. +The only such metadata added by the patch kit are CWE classifications (for +the new warnings), so that we can emit e.g.: + +malloc-1.c: In function ‘test_42a’: +malloc-1.c:466:1: warning: leak of ‘p’ [CWE-401] [-Wanalyzer-malloc-leak] + 466 | } + | ^ + ‘test_42a’: events 1-2 + | + | 463 | void *p = malloc (1024); + | | ^~~~~~~~~~~~~ + | | | + | | (1) allocated here + |...... + | 466 | } + | | ~ + | | | + | | (2) ‘p’ leaks here; was allocated at (1) + | + +(c) adding support for embedding URL information in our textual output +in a form understood by recent versions of terminals + https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda +so that in the above, the CWE-401 is a clickable link to + https://cwe.mitre.org/data/definitions/401.html + +More broadly, the options become clickable links to GCC's online +documentation. + + +Rationale +========= + +There's benefit in integrating the checks directly into the compiler, so +that the programmer can see the diagnostics as he or she works on the code, +rather than at some later point. + + +User interface +============== + +--analyzer turns on all the warnings + + +Internals +========= + + +Performance +=========== + + +Future work +=========== + + +Overview of patch kit +===================== + + + +I plan to demonstrate the analyzer, give an overview of the internal +implementation, its current strengths and limitations, and discuss what +it would take to get this code into the GCC project (perhaps as an +optional in-tree plugin). + + + +diff --git a/gcc/common.opt b/gcc/common.opt +index 1b9e0f3..6dde0c2 100644 +--- a/gcc/common.opt ++++ b/gcc/common.opt +@@ -993,6 +1060,30 @@ Align the start of loops. + falign-loops= + Common RejectNegative Joined Var(str_align_loops) Optimization + ++fanalyzer-checker= ++Common Joined RejectNegative Var(flag_analyzer_checker) ++Restrict the analyzer to run just the named checker (TODO: docs) ++ ++fanalyzer-fine-grained ++Common Var(flag_analyzer_fine_grained) Init(0) ++FIXME ++ ++fanalyzer-impl= ++Common Joined RejectNegative UInteger Var(flag_analyzer_impl) ++FIXME: for selecting older implementations of the analyzer, to be removed ++ ++fanalyzer-state-purge ++Common Var(flag_analyzer_state_purge) Init(1) ++Purge unneeded state during analysis (TODO: docs) ++ ++fanalyzer-state-merge ++Common Var(flag_analyzer_state_merge) Init(1) ++FIXME: merge similar-enough states during analysis (TODO: docs) ++ ++fanalyzer-call-summaries ++Common Var(flag_analyzer_call_summaries) Init(0) ++FIXME: approximate the effect of function calls to simplify analysis (TODO: docs) ++ + +TODO in invoke.texi (perhaps in a different patch): + fargument-alias + Common Ignore + Does nothing. Preserved for backward compatibility. +@@ -1257,6 +1348,10 @@ fdiagnostics-show-line-numbers + Common Var(flag_diagnostics_show_line_numbers) Init(1) + Show line numbers in the left margin when showing source. + ++fdiagnostics-nn-line-numbers ++Common Var(flag_diagnostics_nn_line_numbers) Init(0) ++FIXME ++ + fdiagnostics-color + Common Alias(fdiagnostics-color=,always,never) + ; +@@ -1281,8 +1376,16 @@ Enum(diagnostic_color_rule) String(always) Value(DIAGNOSTICS_COLOR_YES) + EnumValue + Enum(diagnostic_color_rule) String(auto) Value(DIAGNOSTICS_COLOR_AUTO) + ++fdiagnostics-urls ++Common Alias(fdiagnostics-urls=,always,never) ++; ++ ++fdiagnostics-urls= ++Driver Common Joined RejectNegative Var(flag_diagnostics_show_urls) Enum(diagnostic_color_rule) Init(DIAGNOSTICS_COLOR_NO) ++-fdiagnostics-urls=[never|always|auto] Embed URLs in diagnostics. ++ + fdiagnostics-format= +-Common Joined RejectNegative Enum(diagnostics_output_format) ++Driver Common Joined RejectNegative Enum(diagnostics_output_format) + -fdiagnostics-format=[text|json] Select output format. + + ; Required for these enum values. +@@ -1310,6 +1413,30 @@ fdiagnostics-show-option + Common Var(flag_diagnostics_show_option) Init(1) + Amend appropriate diagnostic messages with the command line option that controls them. + ++fdiagnostics-show-metadata ++Common Var(flag_diagnostics_show_metadata) Init(1) ++FIXME; TODO: add to docs ++ ++fdiagnostics-path-format= ++Common Joined RejectNegative Var(flag_diagnostics_path_format) Enum(diagnostic_path_format) Init(DPF_INLINE_EVENTS) ++FIXME; TODO: docs ++ ++Enum ++Name(diagnostic_path_format) Type(int) ++ ++EnumValue ++Enum(diagnostic_path_format) String(none) Value(DPF_NONE) ++ ++EnumValue ++Enum(diagnostic_path_format) String(separate-events) Value(DPF_SEPARATE_EVENTS) ++ ++EnumValue ++Enum(diagnostic_path_format) String(inline-events) Value(DPF_INLINE_EVENTS) ++ ++fdiagnostics-show-path-depths ++Common Var(flag_diagnostics_show_path_depths) Init(0) ++Show stack depths of events in paths. (TODO: add to docs) ++ + fdiagnostics-minimum-margin-width= + Common Joined UInteger Var(diagnostics_minimum_margin_width) Init(6) + Set minimum width of left margin of source code when showing source. +@@ -1326,6 +1453,50 @@ fdump- + Common Joined RejectNegative Var(common_deferred_options) Defer + -fdump- Dump various compiler internals to a file. + ++fdump-analyzer ++Common RejectNegative Var(flag_dump_analyzer) ++FIXME ++ ++fdump-analyzer-summaries ++Common RejectNegative Var(flag_dump_analyzer_summaries) ++FIXME ++ ++fdump-analyzer-supergraph ++Common RejectNegative Var(flag_dump_analyzer_supergraph) ++FIXME ++ ++fdump-analyzer-callgraph ++Common RejectNegative Var(flag_dump_analyzer_callgraph) ++FIXME ++ ++fdump-analyzer-exploded-graph ++Common RejectNegative Var(flag_dump_analyzer_exploded_graph) ++FIXME ++ ++fdump-analyzer-exploded-nodes ++Common RejectNegative Var(flag_dump_analyzer_exploded_nodes) ++FIXME ++ ++fdump-analyzer-exploded-nodes-2 ++Common RejectNegative Var(flag_dump_analyzer_exploded_nodes_2) ++FIXME ++ ++fdump-analyzer-exploded-nodes-3 ++Common RejectNegative Var(flag_dump_analyzer_exploded_nodes_3) ++FIXME ++ ++fanalyzer-verbosity= ++Common Joined UInteger Var(analyzer_verbosity) Init(2) ++FIXME ++ ++fanalyzer-verbose-edges ++Common Var(flag_analyzer_verbose_edges) Init(0) ++FIXME ++ ++fanalyzer-verbose-state-changes ++Common Var(flag_analyzer_verbose_state_changes) Init(0) ++FIXME ++ + fdump-final-insns + Driver RejectNegative + -- 1.8.5.3