aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2023-12-06 19:25:26 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2023-12-06 19:25:26 -0500
commit08b7462d3ad8e5acd941b7c777c5b26b4064d686 (patch)
tree9d418e45863ed55b22f8fc4cb5422a1efe906ee2 /gcc
parentae9e48e5c0acaecf181117bdf3632b6eabf907ec (diff)
downloadgcc-08b7462d3ad8e5acd941b7c777c5b26b4064d686.zip
gcc-08b7462d3ad8e5acd941b7c777c5b26b4064d686.tar.gz
gcc-08b7462d3ad8e5acd941b7c777c5b26b4064d686.tar.bz2
analyzer: fix taint false positives with UNKNOWN [PR112850]
PR analyzer/112850 reports a false positive from -Wanalyzer-tainted-allocation-size on the Linux kernel [1] where -fanalyzer complains that an allocation size is attacker-controlled despite the value being correctly sanitized against upper and lower limits. The root cause is that the expression is sufficiently complex to exceed the -param=analyzer-max-svalue-depth= threshold, currently at 12, with depth 13, and so it is treated as UNKNOWN. Hence the sanitizations are seen as comparisons of an UNKNOWN symbolic value against constants, and these were being ignored by the taint state machine. The expression in question is relatively typical for those seen in Linux kernel ioctl handlers, and I was surprised that it had exceeded the analyzer's default expression complexity limit. This patch addresses this problem in three ways: (a) the default value of the threshold parameter is increased, from 12 to 18, so that such expressions are precisely handled (b) adding a new -Wanalyzer-symbol-too-complex to warn when the symbol complexity limit is reached. This is off by default for users, and on by default in the test suite. (c) the taint state machine handles comparisons against UNKNOWN svalues by dropping all taint information on that execution path, so that if the complexity limit has been exceeded we don't generate false positives As well as fixing the taint false positive (PR analyzer/112850), the patch also fixes a couple of leak false positives seen on flex-generated scanners (PR analyzer/103546). [1] specifically, in sound/core/rawmidi.c's handler for SNDRV_RAWMIDI_STREAM_OUTPUT. gcc/ChangeLog: PR analyzer/103546 PR analyzer/112850 * doc/invoke.texi: Add -Wanalyzer-symbol-too-complex. gcc/analyzer/ChangeLog: PR analyzer/103546 PR analyzer/112850 * analyzer.opt (-param=analyzer-max-svalue-depth=): Increase from 12 to 18. (Wanalyzer-symbol-too-complex): New. * diagnostic-manager.cc (null_assignment_sm_context::clear_all_per_svalue_state): New. * engine.cc (impl_sm_context::clear_all_per_svalue_state): New. * program-state.cc (sm_state_map::clear_all_per_svalue_state): New. * program-state.h (sm_state_map::clear_all_per_svalue_state): New decl. * region-model-manager.cc (region_model_manager::reject_if_too_complex): Add -Wanalyzer-symbol-too-complex. * sm-taint.cc (taint_state_machine::on_condition): Handle comparisons against UNKNOWN. * sm.h (sm_context::clear_all_per_svalue_state): New. gcc/testsuite/ChangeLog: PR analyzer/103546 PR analyzer/112850 * c-c++-common/analyzer/call-summaries-pr107158-2.c: Add -Wno-analyzer-symbol-too-complex. * c-c++-common/analyzer/call-summaries-pr107158.c: Likewise. * c-c++-common/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c: Likewise. * c-c++-common/analyzer/feasibility-3.c: Add -Wno-analyzer-too-complex and -Wno-analyzer-symbol-too-complex. * c-c++-common/analyzer/flex-with-call-summaries.c: Add -Wno-analyzer-symbol-too-complex. Remove fail for PR analyzer/103546 leak false positive. * c-c++-common/analyzer/flex-without-call-summaries.c: Remove xfail for PR analyzer/103546 leak false positive. * c-c++-common/analyzer/infinite-recursion-3.c: Add -Wno-analyzer-symbol-too-complex. * c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c: Likewise. * c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c: Likewise. * c-c++-common/analyzer/null-deref-pr108400-SoftEtherVPN-WebUi.c: Likewise. * c-c++-common/analyzer/null-deref-pr108806-qemu.c: Likewise. * c-c++-common/analyzer/null-deref-pr108830.c: Likewise. * c-c++-common/analyzer/pr94596.c: Likewise. * c-c++-common/analyzer/strtok-2.c: Likewise. * c-c++-common/analyzer/strtok-4.c: Add -Wno-analyzer-too-complex and -Wno-analyzer-symbol-too-complex. * c-c++-common/analyzer/strtok-cppreference.c: Likewise. * gcc.dg/analyzer/analyzer.exp: Add -Wanalyzer-symbol-too-complex to DEFAULT_CFLAGS. * gcc.dg/analyzer/attr-const-3.c: Add -Wno-analyzer-symbol-too-complex. * gcc.dg/analyzer/call-summaries-pr107072.c: Likewise. * gcc.dg/analyzer/doom-s_sound-pr108867.c: Likewise. * gcc.dg/analyzer/explode-4.c: Likewise. * gcc.dg/analyzer/null-deref-pr102671-1.c: Likewise. * gcc.dg/analyzer/null-deref-pr105755.c: Likewise. * gcc.dg/analyzer/out-of-bounds-curl.c: Likewise. * gcc.dg/analyzer/pr101503.c: Likewise. * gcc.dg/analyzer/pr103892.c: Add -Wno-analyzer-too-complex and -Wno-analyzer-symbol-too-complex. * gcc.dg/analyzer/pr94851-4.c: Add -Wno-analyzer-symbol-too-complex. * gcc.dg/analyzer/pr96860-1.c: Likewise. * gcc.dg/analyzer/pr96860-2.c: Likewise. * gcc.dg/analyzer/pr98918.c: Likewise. * gcc.dg/analyzer/pr99044-2.c: Likewise. * gcc.dg/analyzer/uninit-pr108806-qemu.c: Likewise. * gcc.dg/analyzer/use-after-free.c: Add -Wno-analyzer-too-complex and -Wno-analyzer-symbol-too-complex. * gcc.dg/plugin/plugin.exp: Add new tests for analyzer_kernel_plugin.c. * gcc.dg/plugin/taint-CVE-2011-0521-4.c: Update expected results. * gcc.dg/plugin/taint-CVE-2011-0521-5.c: Likewise. * gcc.dg/plugin/taint-CVE-2011-0521-6.c: Likewise. * gcc.dg/plugin/taint-CVE-2011-0521-5-fixed.c: Remove xfail. * gcc.dg/plugin/taint-pr112850-precise.c: New test. * gcc.dg/plugin/taint-pr112850-too-complex.c: New test. * gcc.dg/plugin/taint-pr112850-unsanitized.c: New test. * gcc.dg/plugin/taint-pr112850.c: New test. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/analyzer/analyzer.opt6
-rw-r--r--gcc/analyzer/diagnostic-manager.cc5
-rw-r--r--gcc/analyzer/engine.cc5
-rw-r--r--gcc/analyzer/program-state.cc8
-rw-r--r--gcc/analyzer/program-state.h1
-rw-r--r--gcc/analyzer/region-model-manager.cc10
-rw-r--r--gcc/analyzer/sm-taint.cc14
-rw-r--r--gcc/analyzer/sm.h2
-rw-r--r--gcc/doc/invoke.texi14
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/call-summaries-pr107158-2.c2
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/call-summaries-pr107158.c2
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c2
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/feasibility-3.c2
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/flex-with-call-summaries.c4
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/flex-without-call-summaries.c3
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/infinite-recursion-3.c2
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c2
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c1
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/null-deref-pr108400-SoftEtherVPN-WebUi.c2
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/null-deref-pr108806-qemu.c2
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/null-deref-pr108830.c2
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/pr94596.c3
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/strtok-2.c2
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/strtok-4.c2
-rw-r--r--gcc/testsuite/c-c++-common/analyzer/strtok-cppreference.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/analyzer.exp2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/attr-const-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107072.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/doom-s_sound-pr108867.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/explode-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/null-deref-pr102671-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/null-deref-pr105755.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/out-of-bounds-curl.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr101503.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr103892.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr94851-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96860-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96860-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr98918.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr99044-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/uninit-pr108806-qemu.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/use-after-free.c2
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugin.exp6
-rw-r--r--gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-4.c4
-rw-r--r--gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-5-fixed.c3
-rw-r--r--gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-5.c4
-rw-r--r--gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-6.c4
-rw-r--r--gcc/testsuite/gcc.dg/plugin/taint-pr112850-precise.c50
-rw-r--r--gcc/testsuite/gcc.dg/plugin/taint-pr112850-too-complex.c51
-rw-r--r--gcc/testsuite/gcc.dg/plugin/taint-pr112850-unsanitized.c50
-rw-r--r--gcc/testsuite/gcc.dg/plugin/taint-pr112850.c47
51 files changed, 321 insertions, 32 deletions
diff --git a/gcc/analyzer/analyzer.opt b/gcc/analyzer/analyzer.opt
index a3c30ca..d0fe5a4 100644
--- a/gcc/analyzer/analyzer.opt
+++ b/gcc/analyzer/analyzer.opt
@@ -43,7 +43,7 @@ Common Joined UInteger Var(param_analyzer_max_recursion_depth) Init(2) Param
The maximum number of times a callsite can appear in a call stack within the analyzer, before terminating analysis of a call that would recurse deeper.
-param=analyzer-max-svalue-depth=
-Common Joined UInteger Var(param_analyzer_max_svalue_depth) Init(12) Param
+Common Joined UInteger Var(param_analyzer_max_svalue_depth) Init(18) Param
The maximum depth of a symbolic value, before approximating the value as unknown.
-param=analyzer-min-snodes-for-call-summary=
@@ -262,6 +262,10 @@ Wanalyzer-use-of-uninitialized-value
Common Var(warn_analyzer_use_of_uninitialized_value) Init(1) Warning
Warn about code paths in which an uninitialized value is used.
+Wanalyzer-symbol-too-complex
+Common Var(warn_analyzer_symbol_too_complex) Init(0) Warning
+Warn if expressions are too complicated for the analyzer to fully track.
+
Wanalyzer-too-complex
Common Var(warn_analyzer_too_complex) Init(0) Warning
Warn if the code is too complicated for the analyzer to fully explore.
diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc
index ecd5737..38bd308 100644
--- a/gcc/analyzer/diagnostic-manager.cc
+++ b/gcc/analyzer/diagnostic-manager.cc
@@ -2043,6 +2043,11 @@ struct null_assignment_sm_context : public sm_context
/* No-op. */
}
+ void clear_all_per_svalue_state () final override
+ {
+ /* No-op. */
+ }
+
void on_custom_transition (custom_transition *) final override
{
}
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 825b3af..d2524e3 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -474,6 +474,11 @@ public:
m_new_state->m_checker_states[m_sm_idx]->set_global_state (state);
}
+ void clear_all_per_svalue_state () final override
+ {
+ m_new_state->m_checker_states[m_sm_idx]->clear_all_per_svalue_state ();
+ }
+
void on_custom_transition (custom_transition *transition) final override
{
transition->impl_transition (&m_eg,
diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc
index 9bb81e6..78f739e 100644
--- a/gcc/analyzer/program-state.cc
+++ b/gcc/analyzer/program-state.cc
@@ -526,6 +526,14 @@ sm_state_map::clear_any_state (const svalue *sval)
m_map.remove (sval);
}
+/* Clear all per-svalue state within this state map. */
+
+void
+sm_state_map::clear_all_per_svalue_state ()
+{
+ m_map.empty ();
+}
+
/* Set the "global" state within this state map to STATE. */
void
diff --git a/gcc/analyzer/program-state.h b/gcc/analyzer/program-state.h
index c9b3aa0..ef1a2ad 100644
--- a/gcc/analyzer/program-state.h
+++ b/gcc/analyzer/program-state.h
@@ -146,6 +146,7 @@ public:
const svalue *origin,
const extrinsic_state &ext_state);
void clear_any_state (const svalue *sval);
+ void clear_all_per_svalue_state ();
void set_global_state (state_machine::state_t state);
state_machine::state_t get_global_state () const;
diff --git a/gcc/analyzer/region-model-manager.cc b/gcc/analyzer/region-model-manager.cc
index 921edc5..b631bcb 100644
--- a/gcc/analyzer/region-model-manager.cc
+++ b/gcc/analyzer/region-model-manager.cc
@@ -185,6 +185,16 @@ region_model_manager::reject_if_too_complex (svalue *sval)
return false;
}
+ pretty_printer pp;
+ pp_format_decoder (&pp) = default_tree_printer;
+ sval->dump_to_pp (&pp, true);
+ if (warning_at (input_location, OPT_Wanalyzer_symbol_too_complex,
+ "symbol too complicated: %qs",
+ pp_formatted_text (&pp)))
+ inform (input_location,
+ "max_depth %i exceeds --param=analyzer-max-svalue-depth=%i",
+ c.m_max_depth, param_analyzer_max_svalue_depth);
+
delete sval;
return true;
}
diff --git a/gcc/analyzer/sm-taint.cc b/gcc/analyzer/sm-taint.cc
index d01e3f0..6b5d51c 100644
--- a/gcc/analyzer/sm-taint.cc
+++ b/gcc/analyzer/sm-taint.cc
@@ -1038,6 +1038,20 @@ taint_state_machine::on_condition (sm_context *sm_ctxt,
if (stmt == NULL)
return;
+ if (lhs->get_kind () == SK_UNKNOWN
+ || rhs->get_kind () == SK_UNKNOWN)
+ {
+ /* If we have a comparison against UNKNOWN, then
+ we've presumably hit the svalue complexity limit,
+ and we don't know what is being sanitized.
+ Give up on any taint already found on this execution path. */
+ // TODO: warn about this
+ if (get_logger ())
+ get_logger ()->log ("comparison against UNKNOWN; removing all taint");
+ sm_ctxt->clear_all_per_svalue_state ();
+ return;
+ }
+
// TODO
switch (op)
{
diff --git a/gcc/analyzer/sm.h b/gcc/analyzer/sm.h
index 3ff9c26..ef63d73 100644
--- a/gcc/analyzer/sm.h
+++ b/gcc/analyzer/sm.h
@@ -299,6 +299,8 @@ public:
virtual state_machine::state_t get_global_state () const = 0;
virtual void set_global_state (state_machine::state_t) = 0;
+ virtual void clear_all_per_svalue_state () = 0;
+
/* A vfunc for handling custom transitions, such as when registering
a signal handler. */
virtual void on_custom_transition (custom_transition *transition) = 0;
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index bff3645..f8d6f79 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -491,6 +491,7 @@ Objective-C and Objective-C++ Dialects}.
-Wno-analyzer-tainted-divisor
-Wno-analyzer-tainted-offset
-Wno-analyzer-tainted-size
+-Wanalyzer-symbol-too-complex
-Wanalyzer-too-complex
-Wno-analyzer-undefined-behavior-strtok
-Wno-analyzer-unsafe-call-within-signal-handler
@@ -10562,6 +10563,19 @@ Enabling this option effectively enables the following warnings:
This option is only available if GCC was configured with analyzer
support enabled.
+@opindex Wanalyzer-symbol-too-complex
+@opindex Wno-analyzer-symbol-too-complex
+@item -Wanalyzer-symbol-too-complex
+If @option{-fanalyzer} is enabled, the analyzer uses various heuristics
+to attempt to track the state of memory, but these can be defeated by
+sufficiently complicated code.
+
+By default, the analysis silently stops tracking values of expressions
+if they exceed the threshold defined by
+@option{--param analyzer-max-svalue-depth=@var{value}}, and falls back
+to an imprecise representation for such expressions.
+The @option{-Wanalyzer-symbol-too-complex} option warns if this occurs.
+
@opindex Wanalyzer-too-complex
@opindex Wno-analyzer-too-complex
@item -Wanalyzer-too-complex
diff --git a/gcc/testsuite/c-c++-common/analyzer/call-summaries-pr107158-2.c b/gcc/testsuite/c-c++-common/analyzer/call-summaries-pr107158-2.c
index 4561e10..b395623 100644
--- a/gcc/testsuite/c-c++-common/analyzer/call-summaries-pr107158-2.c
+++ b/gcc/testsuite/c-c++-common/analyzer/call-summaries-pr107158-2.c
@@ -1,4 +1,4 @@
-/* { dg-additional-options "-fanalyzer-call-summaries -Wno-analyzer-too-complex" } */
+/* { dg-additional-options "-fanalyzer-call-summaries -Wno-analyzer-too-complex -Wno-analyzer-symbol-too-complex" } */
/* { dg-skip-if "c++98 has no noreturn attribute" { c++98_only } } */
#ifdef __cplusplus
diff --git a/gcc/testsuite/c-c++-common/analyzer/call-summaries-pr107158.c b/gcc/testsuite/c-c++-common/analyzer/call-summaries-pr107158.c
index d4cf079..de70583 100644
--- a/gcc/testsuite/c-c++-common/analyzer/call-summaries-pr107158.c
+++ b/gcc/testsuite/c-c++-common/analyzer/call-summaries-pr107158.c
@@ -1,4 +1,4 @@
-/* { dg-additional-options "-fanalyzer-call-summaries" } */
+/* { dg-additional-options "-fanalyzer-call-summaries -Wno-analyzer-symbol-too-complex" } */
typedef __SIZE_TYPE__ size_t;
enum { _ISspace = ((5) < 8 ? ((1 << (5)) << 8) : ((1 << (5)) >> 8)) };
diff --git a/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c
index 1d28e10..c4561fc 100644
--- a/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c
+++ b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c
@@ -1,5 +1,7 @@
/* Reduced from haproxy-2.7.1's cfgparse.c. */
+/* { dg-additional-options "-Wno-analyzer-too-complex -Wno-analyzer-symbol-too-complex" } */
+
typedef __SIZE_TYPE__ size_t;
extern int
diff --git a/gcc/testsuite/c-c++-common/analyzer/feasibility-3.c b/gcc/testsuite/c-c++-common/analyzer/feasibility-3.c
index 2fcd064..06194f8 100644
--- a/gcc/testsuite/c-c++-common/analyzer/feasibility-3.c
+++ b/gcc/testsuite/c-c++-common/analyzer/feasibility-3.c
@@ -1,6 +1,8 @@
/* Reduced and adapted from Linux: fs/proc/inode.c: proc_reg_open
(GPL v2.0). */
+/* { dg-additional-options "-Wno-analyzer-too-complex -Wno-analyzer-symbol-too-complex" } */
+
/* Types. */
typedef unsigned char u8;
diff --git a/gcc/testsuite/c-c++-common/analyzer/flex-with-call-summaries.c b/gcc/testsuite/c-c++-common/analyzer/flex-with-call-summaries.c
index 45edacf..963a84b 100644
--- a/gcc/testsuite/c-c++-common/analyzer/flex-with-call-summaries.c
+++ b/gcc/testsuite/c-c++-common/analyzer/flex-with-call-summaries.c
@@ -5,6 +5,7 @@
/* { dg-skip-if "" { "avr-*-*" } } */
/* { dg-additional-options "-fanalyzer-call-summaries" } */
/* { dg-additional-options "-Wno-analyzer-too-complex" } */
+/* { dg-additional-options "-Wno-analyzer-symbol-too-complex" } */
/* A lexical scanner generated by flex */
@@ -885,8 +886,7 @@ static int yy_get_next_buffer (void)
}
else
/* Can't grow it, we don't own it. */
- b->yy_ch_buf = NULL; /* { dg-bogus "leak" "" { xfail *-*-* } } */
- /* TODO: leak false positive: PR analyzer/103546. */
+ b->yy_ch_buf = NULL; /* { dg-bogus "leak" "PR analyzer/103546" } */
if ( ! b->yy_ch_buf )
YY_FATAL_ERROR(
diff --git a/gcc/testsuite/c-c++-common/analyzer/flex-without-call-summaries.c b/gcc/testsuite/c-c++-common/analyzer/flex-without-call-summaries.c
index 5369f76..b1c2331 100644
--- a/gcc/testsuite/c-c++-common/analyzer/flex-without-call-summaries.c
+++ b/gcc/testsuite/c-c++-common/analyzer/flex-without-call-summaries.c
@@ -886,8 +886,7 @@ static int yy_get_next_buffer (void)
}
else
/* Can't grow it, we don't own it. */
- b->yy_ch_buf = NULL; /* { dg-bogus "leak" "" { xfail *-*-* } } */
- /* TODO: leak false positive: PR analyzer/103546. */
+ b->yy_ch_buf = NULL; /* { dg-bogus "leak" "PR analyzer/103546" */
if ( ! b->yy_ch_buf )
YY_FATAL_ERROR(
diff --git a/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-3.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-3.c
index 68c4fa3..2ae20a1 100644
--- a/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-3.c
+++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-3.c
@@ -1,4 +1,4 @@
-/* { dg-additional-options "-fno-analyzer-call-summaries -Wno-analyzer-too-complex" } */
+/* { dg-additional-options "-fno-analyzer-call-summaries -Wno-analyzer-too-complex -Wno-analyzer-symbol-too-complex" } */
struct node
{
diff --git a/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c
index c46ffe9..c1c8e6f 100644
--- a/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c
+++ b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c
@@ -1,7 +1,7 @@
/* Reduced from haproxy's src/ssl_sample.c */
/* { dg-require-effective-target ptr_eq_long } */
-/* { dg-additional-options "-O2" } */
+/* { dg-additional-options "-O2 -Wno-analyzer-symbol-too-complex" } */
union sample_value {
long long int sint;
diff --git a/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c
index ef34a76..c5f1fa4 100644
--- a/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c
+++ b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c
@@ -1,6 +1,7 @@
/* Reduced from haproxy's src/ssl_sample.c */
/* { dg-require-effective-target ptr_eq_long } */
+/* { dg-additional-options "-Wno-analyzer-symbol-too-complex" } */
union sample_value {
long long int sint;
diff --git a/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108400-SoftEtherVPN-WebUi.c b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108400-SoftEtherVPN-WebUi.c
index 1151d62..9dcf7aa 100644
--- a/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108400-SoftEtherVPN-WebUi.c
+++ b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108400-SoftEtherVPN-WebUi.c
@@ -1,4 +1,6 @@
/* Reduced from SoftEtherVPN's src/Cedar/WebUI.c. */
+/* { dg-additional-options "-Wno-analyzer-symbol-too-complex" } */
+
#include "../../gcc.dg/analyzer/analyzer-decls.h"
typedef int (COMPARE)(void *p1, void *p2);
typedef unsigned int UINT;
diff --git a/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108806-qemu.c b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108806-qemu.c
index f7f6923..16ef657 100644
--- a/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108806-qemu.c
+++ b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108806-qemu.c
@@ -1,5 +1,7 @@
/* Reduced from qemu-7.2.0's hw/intc/omap_intc.c */
+/* { dg-additional-options "-Wno-analyzer-symbol-too-complex" } */
+
#include "../../gcc.dg/analyzer/analyzer-decls.h"
typedef unsigned char __uint8_t;
diff --git a/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108830.c b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108830.c
index 0c95148..1cb1ebe 100644
--- a/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108830.c
+++ b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108830.c
@@ -1,6 +1,6 @@
/* Reduced from apr-1.7.0/tables/apr_hash.c: 'apr_hash_merge' */
-/* { dg-additional-options "-Wno-analyzer-too-complex" } */
+/* { dg-additional-options "-Wno-analyzer-too-complex -Wno-analyzer-symbol-too-complex" } */
#include "../../gcc.dg/analyzer/analyzer-decls.h"
diff --git a/gcc/testsuite/c-c++-common/analyzer/pr94596.c b/gcc/testsuite/c-c++-common/analyzer/pr94596.c
index 10ea549..0d62409 100644
--- a/gcc/testsuite/c-c++-common/analyzer/pr94596.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr94596.c
@@ -17,6 +17,9 @@
*/
#include "../../gcc.dg/analyzer/analyzer-decls.h"
+
+/* { dg-additional-options "-Wno-analyzer-symbol-too-complex" } */
+
typedef __SIZE_TYPE__ size_t;
#ifndef __cplusplus
diff --git a/gcc/testsuite/c-c++-common/analyzer/strtok-2.c b/gcc/testsuite/c-c++-common/analyzer/strtok-2.c
index 0336bf0..f34b4a7 100644
--- a/gcc/testsuite/c-c++-common/analyzer/strtok-2.c
+++ b/gcc/testsuite/c-c++-common/analyzer/strtok-2.c
@@ -1,3 +1,5 @@
+/* { dg-additional-options "-Wno-analyzer-symbol-too-complex" } */
+
#include "../../gcc.dg/analyzer/analyzer-decls.h"
extern char *strtok (char *str, const char *delim)
diff --git a/gcc/testsuite/c-c++-common/analyzer/strtok-4.c b/gcc/testsuite/c-c++-common/analyzer/strtok-4.c
index b6b7d49..793c7fc 100644
--- a/gcc/testsuite/c-c++-common/analyzer/strtok-4.c
+++ b/gcc/testsuite/c-c++-common/analyzer/strtok-4.c
@@ -1,3 +1,5 @@
+/* { dg-additional-options "-Wno-analyzer-too-complex -Wno-analyzer-symbol-too-complex" } */
+
#include "../../gcc.dg/analyzer/analyzer-decls.h"
extern char *strtok (char *str, const char *delim);
diff --git a/gcc/testsuite/c-c++-common/analyzer/strtok-cppreference.c b/gcc/testsuite/c-c++-common/analyzer/strtok-cppreference.c
index a2e9123..a396c64 100644
--- a/gcc/testsuite/c-c++-common/analyzer/strtok-cppreference.c
+++ b/gcc/testsuite/c-c++-common/analyzer/strtok-cppreference.c
@@ -11,6 +11,8 @@
should be released under an equivalent license so that everyone could
benefit from the modified versions. " */
+/* { dg-additional-options " -Wno-analyzer-too-complex -Wno-analyzer-symbol-too-complex" } */
+
#define __STDC_WANT_LIB_EXT1__ 0
#include <string.h>
#include <stdio.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/analyzer.exp b/gcc/testsuite/gcc.dg/analyzer/analyzer.exp
index cedf3c0..ba5aa68 100644
--- a/gcc/testsuite/gcc.dg/analyzer/analyzer.exp
+++ b/gcc/testsuite/gcc.dg/analyzer/analyzer.exp
@@ -30,7 +30,7 @@ if [info exists DEFAULT_CFLAGS] then {
}
# If a testcase doesn't have special options, use these.
-set DEFAULT_CFLAGS "-fanalyzer -Wanalyzer-too-complex -fanalyzer-call-summaries"
+set DEFAULT_CFLAGS "-fanalyzer -Wanalyzer-too-complex -Wanalyzer-symbol-too-complex -fanalyzer-call-summaries"
if { [istarget "*-*-darwin*" ] } {
# On macOS, system headers redefine by default some macros (memcpy,
diff --git a/gcc/testsuite/gcc.dg/analyzer/attr-const-3.c b/gcc/testsuite/gcc.dg/analyzer/attr-const-3.c
index fc8527a..11238a7 100644
--- a/gcc/testsuite/gcc.dg/analyzer/attr-const-3.c
+++ b/gcc/testsuite/gcc.dg/analyzer/attr-const-3.c
@@ -1,7 +1,7 @@
/* Verify that we handle unknown values passed to __attribute__ ((const))
(by imposing a complexity limit). */
-/* { dg-additional-options "--param analyzer-max-svalue-depth=4" } */
+/* { dg-additional-options "--param analyzer-max-svalue-depth=4 -Wno-analyzer-symbol-too-complex" } */
#include "analyzer-decls.h"
diff --git a/gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107072.c b/gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107072.c
index 6e583d0..f59318b 100644
--- a/gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107072.c
+++ b/gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107072.c
@@ -1,5 +1,5 @@
/* { dg-require-effective-target int32plus } */
-/* { dg-additional-options "-fanalyzer-call-summaries --param analyzer-min-snodes-for-call-summary=0" } */
+/* { dg-additional-options "-fanalyzer-call-summaries --param analyzer-min-snodes-for-call-summary=0 -Wno-analyzer-symbol-too-complex" } */
/* There need to be at least two calls to a function for the
call-summarization code to be used.
diff --git a/gcc/testsuite/gcc.dg/analyzer/doom-s_sound-pr108867.c b/gcc/testsuite/gcc.dg/analyzer/doom-s_sound-pr108867.c
index ae58f03..fdc21a2 100644
--- a/gcc/testsuite/gcc.dg/analyzer/doom-s_sound-pr108867.c
+++ b/gcc/testsuite/gcc.dg/analyzer/doom-s_sound-pr108867.c
@@ -1,6 +1,6 @@
/* Reduced from Doom's linuxdoom-1.10/s_sound.c, which is GPLv2 or later. */
-/* { dg-additional-options "-fno-analyzer-call-summaries -Wno-analyzer-too-complex" } */
+/* { dg-additional-options "-fno-analyzer-call-summaries -Wno-analyzer-too-complex -Wno-analyzer-symbol-too-complex" } */
/* { dg-require-effective-target size32plus } */
typedef struct _IO_FILE FILE;
diff --git a/gcc/testsuite/gcc.dg/analyzer/explode-4.c b/gcc/testsuite/gcc.dg/analyzer/explode-4.c
index 874b1e9..a98dfb5 100644
--- a/gcc/testsuite/gcc.dg/analyzer/explode-4.c
+++ b/gcc/testsuite/gcc.dg/analyzer/explode-4.c
@@ -3,7 +3,7 @@
conjured_svalues whilst handling a long chain of external
function calls. */
-/* { dg-additional-options "-Wno-implicit-function-declaration -Wno-int-conversion -Wno-analyzer-too-complex" } */
+/* { dg-additional-options "-Wno-implicit-function-declaration -Wno-int-conversion -Wno-analyzer-too-complex -Wno-analyzer-symbol-too-complex" } */
#define NULL ((void *)0)
typedef unsigned char uint8_t;
diff --git a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr102671-1.c b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr102671-1.c
index 3fe061b..65c7bac 100644
--- a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr102671-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr102671-1.c
@@ -1,5 +1,5 @@
/* { dg-require-effective-target ptr_eq_long } */
-/* { dg-additional-options "-O2 -Wno-shift-count-overflow" } */
+/* { dg-additional-options "-O2 -Wno-shift-count-overflow -Wno-analyzer-symbol-too-complex" } */
struct lisp;
union vectorlike_header { long size; };
diff --git a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr105755.c b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr105755.c
index 2b0ba29..5375b4d 100644
--- a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr105755.c
+++ b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr105755.c
@@ -1,5 +1,5 @@
/* { dg-require-effective-target int32plus } */
-/* { dg-additional-options "-Wno-analyzer-too-complex -O2" } */
+/* { dg-additional-options "-Wno-analyzer-too-complex -Wno-analyzer-symbol-too-complex -O2" } */
typedef long int ptrdiff_t;
typedef long int EMACS_INT;
diff --git a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-curl.c b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-curl.c
index e34b572..d14661c 100644
--- a/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-curl.c
+++ b/gcc/testsuite/gcc.dg/analyzer/out-of-bounds-curl.c
@@ -1,4 +1,4 @@
-/* { dg-additional-options "-O2" } */
+/* { dg-additional-options "-O2 -Wno-analyzer-symbol-too-complex" } */
#include <string.h>
/* Reduced from curl lib/smb.c. */
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr101503.c b/gcc/testsuite/gcc.dg/analyzer/pr101503.c
index 16faf6e..cc4d801 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr101503.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pr101503.c
@@ -1,4 +1,4 @@
-/* { dg-additional-options "--param analyzer-max-svalue-depth=0" } */
+/* { dg-additional-options "--param analyzer-max-svalue-depth=0 -Wno-analyzer-symbol-too-complex" } */
int val;
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr103892.c b/gcc/testsuite/gcc.dg/analyzer/pr103892.c
index d16cd83..a17c3b7 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr103892.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pr103892.c
@@ -1,4 +1,4 @@
-/* { dg-additional-options "-O2" } */
+/* { dg-additional-options "-O2 -Wno-analyzer-too-complex -Wno-analyzer-symbol-too-complex" } */
/* C only: C++ FE optimizes argstr_get_word completely away
and therefore the number of SN diminishes compared to C,
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94851-4.c b/gcc/testsuite/gcc.dg/analyzer/pr94851-4.c
index 2a15a5d..a5130c5 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr94851-4.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pr94851-4.c
@@ -1,4 +1,4 @@
-/* { dg-additional-options "-O2" } */
+/* { dg-additional-options "-O2 -Wno-analyzer-symbol-too-complex" } */
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96860-1.c b/gcc/testsuite/gcc.dg/analyzer/pr96860-1.c
index 8f298ec..8be30b3 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr96860-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96860-1.c
@@ -1,5 +1,5 @@
/* { dg-require-effective-target int128 } */
-/* { dg-additional-options "--param analyzer-max-svalue-depth=0" } */
+/* { dg-additional-options "--param analyzer-max-svalue-depth=0 -Wno-analyzer-symbol-too-complex" } */
void x7 (void)
{
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96860-2.c b/gcc/testsuite/gcc.dg/analyzer/pr96860-2.c
index 90a818c..d12b9a1 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr96860-2.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96860-2.c
@@ -1,4 +1,4 @@
-/* { dg-additional-options "--param analyzer-max-svalue-depth=0" } */
+/* { dg-additional-options "--param analyzer-max-svalue-depth=0 -Wno-analyzer-symbol-too-complex" } */
void x7 (void)
{
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr98918.c b/gcc/testsuite/gcc.dg/analyzer/pr98918.c
index ac626ba..c3bbce3 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr98918.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pr98918.c
@@ -1,3 +1,5 @@
+/* { dg-additional-options "-Wno-analyzer-symbol-too-complex" } */
+
#include <stdlib.h>
struct marker {
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99044-2.c b/gcc/testsuite/gcc.dg/analyzer/pr99044-2.c
index fd71d35..f7badb9 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr99044-2.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pr99044-2.c
@@ -1,3 +1,5 @@
+/* { dg-additional-options "-Wno-analyzer-symbol-too-complex" } */
+
struct node
{
struct node *next;
diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-pr108806-qemu.c b/gcc/testsuite/gcc.dg/analyzer/uninit-pr108806-qemu.c
index 34fe802..0927201 100644
--- a/gcc/testsuite/gcc.dg/analyzer/uninit-pr108806-qemu.c
+++ b/gcc/testsuite/gcc.dg/analyzer/uninit-pr108806-qemu.c
@@ -5,6 +5,8 @@
struct omap_intr_handler_bank_s* bank;
*/
+/* { dg-additional-options "-Wno-analyzer-symbol-too-complex" } */
+
typedef unsigned char __uint8_t;
typedef unsigned int __uint32_t;
typedef unsigned long int __uint64_t;
diff --git a/gcc/testsuite/gcc.dg/analyzer/use-after-free.c b/gcc/testsuite/gcc.dg/analyzer/use-after-free.c
index d7e4bc2..76a85f5 100644
--- a/gcc/testsuite/gcc.dg/analyzer/use-after-free.c
+++ b/gcc/testsuite/gcc.dg/analyzer/use-after-free.c
@@ -1,3 +1,5 @@
+/* { dg-additional-options "-Wno-analyzer-too-complex -Wno-analyzer-symbol-too-complex" } */
+
#include <stdlib.h>
#include "analyzer-decls.h"
diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp
index f098a32..f0b4bb7 100644
--- a/gcc/testsuite/gcc.dg/plugin/plugin.exp
+++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp
@@ -162,7 +162,11 @@ set plugin_test_list [list \
taint-CVE-2011-0521-5.c \
taint-CVE-2011-0521-5-fixed.c \
taint-CVE-2011-0521-6.c \
- taint-antipatterns-1.c } \
+ taint-antipatterns-1.c \
+ taint-pr112850.c \
+ taint-pr112850-precise.c \
+ taint-pr112850-too-complex.c \
+ taint-pr112850-unsanitized.c } \
{ analyzer_cpython_plugin.c \
cpython-plugin-test-no-Python-h.c \
cpython-plugin-test-PyList_Append.c \
diff --git a/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-4.c b/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-4.c
index 06b3468..e268a8e 100644
--- a/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-4.c
+++ b/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-4.c
@@ -32,9 +32,9 @@ int test_1(struct file *file, unsigned int cmd, unsigned long arg)
if (info->num > 1)
return -EINVAL;
av7110->ci_slot[info->num].num = info->num; /* { dg-warning "attacker-controlled value" } */
- av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ? /* { dg-warning "attacker-controlled value" } */
+ av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ?
CA_CI_LINK : CA_CI;
- memcpy(info, &av7110->ci_slot[info->num], sizeof(ca_slot_info_t)); /* { dg-warning "attacker-controlled value" } */
+ memcpy(info, &av7110->ci_slot[info->num], sizeof(ca_slot_info_t));
}
copy_to_user((void __user *)arg, parg, sizeof(sbuf));
diff --git a/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-5-fixed.c b/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-5-fixed.c
index 076ada3..b39e693 100644
--- a/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-5-fixed.c
+++ b/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-5-fixed.c
@@ -39,8 +39,7 @@ int test_1(struct file *file, unsigned int cmd, unsigned long arg)
av7110->ci_slot[info->num].num = info->num;
av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ?
CA_CI_LINK : CA_CI;
- memcpy(info, &av7110->ci_slot[info->num], sizeof(ca_slot_info_t)); /* { dg-bogus "use of attacker-controlled value in array lookup without bounds checking" "" { xfail *-*-* } } */
- // FIXME: why the above false +ve?
+ memcpy(info, &av7110->ci_slot[info->num], sizeof(ca_slot_info_t)); /* { dg-bogus "use of attacker-controlled value in array lookup without bounds checking" } */
}
copy_to_user((void __user *)arg, &sbuf, sizeof(sbuf));
diff --git a/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-5.c b/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-5.c
index e27ee46..fe216c0 100644
--- a/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-5.c
+++ b/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-5.c
@@ -37,9 +37,9 @@ int test_1(struct file *file, unsigned int cmd, unsigned long arg)
__analyzer_dump_state ("taint", info->num); /* { dg-warning "has_ub" } */
av7110->ci_slot[info->num].num = info->num; /* { dg-warning "use of attacker-controlled value '\\*info\\.num' in array lookup without checking for negative" } */
- av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ? /* { dg-warning "use of attacker-controlled value '\\*info\\.num' in array lookup without checking for negative" } */
+ av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ?
CA_CI_LINK : CA_CI;
- memcpy(info, &av7110->ci_slot[info->num], sizeof(ca_slot_info_t)); /* { dg-warning "use of attacker-controlled value in array lookup without bounds checking" } */
+ memcpy(info, &av7110->ci_slot[info->num], sizeof(ca_slot_info_t));
}
copy_to_user((void __user *)arg, &sbuf, sizeof(sbuf));
diff --git a/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-6.c b/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-6.c
index fea70ee..5b68de3 100644
--- a/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-6.c
+++ b/gcc/testsuite/gcc.dg/plugin/taint-CVE-2011-0521-6.c
@@ -34,9 +34,9 @@ int test_1(struct file *file, unsigned int cmd, unsigned long arg)
//__analyzer_break ();
av7110->ci_slot[info->num].num = info->num; /* { dg-warning "use of attacker-controlled value '\\*info\\.num' in array lookup without bounds checking" } */
- av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ? /* { dg-warning "use of attacker-controlled value '\\*info\\.num' in array lookup without bounds checking" } */
+ av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ?
CA_CI_LINK : CA_CI;
- memcpy(info, &av7110->ci_slot[info->num], sizeof(ca_slot_info_t)); /* { dg-warning "use of attacker-controlled value in array lookup without bounds checking" } */
+ memcpy(info, &av7110->ci_slot[info->num], sizeof(ca_slot_info_t));
}
copy_to_user((void __user *)arg, &sbuf, sizeof(sbuf));
diff --git a/gcc/testsuite/gcc.dg/plugin/taint-pr112850-precise.c b/gcc/testsuite/gcc.dg/plugin/taint-pr112850-precise.c
new file mode 100644
index 0000000..558f0fb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/taint-pr112850-precise.c
@@ -0,0 +1,50 @@
+/* Reduced from false positive in Linux kernel in sound/core/rawmidi.c.
+
+ Use a value of --param=analyzer-max-svalue-depth= high enough to avoid
+ UNKNOWN svalues; make sure we don't get false positives with this case. */
+
+/* { dg-do compile } */
+/* { dg-options "-fanalyzer -O2 -Wanalyzer-symbol-too-complex --param=analyzer-max-svalue-depth=13" } */
+/* { dg-require-effective-target analyzer } */
+
+typedef unsigned long __kernel_ulong_t;
+typedef __kernel_ulong_t __kernel_size_t;
+typedef __kernel_size_t size_t;
+typedef unsigned int gfp_t;
+
+extern unsigned long copy_from_user(void* to, const void* from, unsigned long n);
+
+extern
+__attribute__((__alloc_size__(1)))
+__attribute__((__malloc__)) void*
+kvzalloc(size_t size, gfp_t flags);
+
+struct snd_rawmidi_params
+{
+ int stream;
+ size_t buffer_size;
+};
+
+char *newbuf;
+
+static int
+resize_runtime_buffer(struct snd_rawmidi_params* params)
+{
+ if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) /* { dg-bogus "symbol too complicated" } */
+ return -22;
+ newbuf = kvzalloc(params->buffer_size, /* { dg-bogus "use of attacker-controlled value '\\*params.buffer_size' as allocation size without upper-bounds checking" "PR analyzer/112850" } */
+ (((gfp_t)(0x400u | 0x800u)) | ((gfp_t)0x40u) | ((gfp_t)0x80u)));
+ if (!newbuf)
+ return -12;
+ return 0;
+}
+
+long
+snd_rawmidi_ioctl(unsigned long arg)
+{
+ void* argp = (void*)arg;
+ struct snd_rawmidi_params params;
+ if (copy_from_user(&params, argp, sizeof(struct snd_rawmidi_params)))
+ return -14;
+ return resize_runtime_buffer(&params);
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/taint-pr112850-too-complex.c b/gcc/testsuite/gcc.dg/plugin/taint-pr112850-too-complex.c
new file mode 100644
index 0000000..2a4ee81
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/taint-pr112850-too-complex.c
@@ -0,0 +1,51 @@
+/* Reduced from false positive in Linux kernel in sound/core/rawmidi.c.
+
+ With --param=analyzer-max-svalue-depth=12, the value being compared
+ at the sanitization is too complex and becomes UNKNOWN; make sure
+ this doesn't lead to a false positive. */
+
+/* { dg-do compile } */
+/* { dg-options "-fanalyzer -O2 -Wanalyzer-symbol-too-complex --param=analyzer-max-svalue-depth=12" } */
+/* { dg-require-effective-target analyzer } */
+
+typedef unsigned long __kernel_ulong_t;
+typedef __kernel_ulong_t __kernel_size_t;
+typedef __kernel_size_t size_t;
+typedef unsigned int gfp_t;
+
+extern unsigned long copy_from_user(void* to, const void* from, unsigned long n);
+
+extern
+__attribute__((__alloc_size__(1)))
+__attribute__((__malloc__)) void*
+kvzalloc(size_t size, gfp_t flags);
+
+struct snd_rawmidi_params
+{
+ int stream;
+ size_t buffer_size;
+};
+
+char *newbuf;
+
+static int
+resize_runtime_buffer(struct snd_rawmidi_params* params)
+{
+ if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) /* { dg-warning "symbol too complicated" } */
+ return -22;
+ newbuf = kvzalloc(params->buffer_size, /* { dg-bogus "use of attacker-controlled value '\\*params.buffer_size' as allocation size without upper-bounds checking" "PR analyzer/112850" } */
+ (((gfp_t)(0x400u | 0x800u)) | ((gfp_t)0x40u) | ((gfp_t)0x80u)));
+ if (!newbuf)
+ return -12;
+ return 0;
+}
+
+long
+snd_rawmidi_ioctl(unsigned long arg)
+{
+ void* argp = (void*)arg;
+ struct snd_rawmidi_params params;
+ if (copy_from_user(&params, argp, sizeof(struct snd_rawmidi_params)))
+ return -14;
+ return resize_runtime_buffer(&params);
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/taint-pr112850-unsanitized.c b/gcc/testsuite/gcc.dg/plugin/taint-pr112850-unsanitized.c
new file mode 100644
index 0000000..e46fcb6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/taint-pr112850-unsanitized.c
@@ -0,0 +1,50 @@
+/* Reduced from false positive in Linux kernel in sound/core/rawmidi.c,
+ with sanitization removed to make it a true positive.
+
+ Verify that we detect this (with default params). */
+
+/* { dg-do compile } */
+/* { dg-options "-fanalyzer -O2 -Wanalyzer-too-complex" } */
+/* { dg-require-effective-target analyzer } */
+
+typedef unsigned long __kernel_ulong_t;
+typedef __kernel_ulong_t __kernel_size_t;
+typedef __kernel_size_t size_t;
+typedef unsigned int gfp_t;
+
+extern unsigned long copy_from_user(void* to, const void* from, unsigned long n);
+
+extern
+__attribute__((__alloc_size__(1)))
+__attribute__((__malloc__)) void*
+kvzalloc(size_t size, gfp_t flags);
+
+struct snd_rawmidi_params
+{
+ int stream;
+ size_t buffer_size;
+};
+
+char *newbuf;
+
+static int
+resize_runtime_buffer(struct snd_rawmidi_params* params)
+{
+ /* No sanitization, so we should complain. */
+
+ newbuf = kvzalloc(params->buffer_size, /* { dg-warning "use of attacker-controlled value '\\*params.buffer_size' as allocation size without upper-bounds checking" "PR analyzer/112850" } */
+ (((gfp_t)(0x400u | 0x800u)) | ((gfp_t)0x40u) | ((gfp_t)0x80u)));
+ if (!newbuf)
+ return -12;
+ return 0;
+}
+
+long
+snd_rawmidi_ioctl(unsigned long arg)
+{
+ void* argp = (void*)arg;
+ struct snd_rawmidi_params params;
+ if (copy_from_user(&params, argp, sizeof(struct snd_rawmidi_params)))
+ return -14;
+ return resize_runtime_buffer(&params);
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/taint-pr112850.c b/gcc/testsuite/gcc.dg/plugin/taint-pr112850.c
new file mode 100644
index 0000000..6fa1d0f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/taint-pr112850.c
@@ -0,0 +1,47 @@
+/* Reduced from false positive in Linux kernel in sound/core/rawmidi.c. */
+
+/* { dg-do compile } */
+/* { dg-options "-fanalyzer -O2 -Wanalyzer-symbol-too-complex" } */
+/* { dg-require-effective-target analyzer } */
+
+typedef unsigned long __kernel_ulong_t;
+typedef __kernel_ulong_t __kernel_size_t;
+typedef __kernel_size_t size_t;
+typedef unsigned int gfp_t;
+
+extern unsigned long copy_from_user(void* to, const void* from, unsigned long n);
+
+extern
+__attribute__((__alloc_size__(1)))
+__attribute__((__malloc__)) void*
+kvzalloc(size_t size, gfp_t flags);
+
+struct snd_rawmidi_params
+{
+ int stream;
+ size_t buffer_size;
+};
+
+char *newbuf;
+
+static int
+resize_runtime_buffer(struct snd_rawmidi_params* params)
+{
+ if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) /* { dg-bogus "symbol too complicated" } */
+ return -22;
+ newbuf = kvzalloc(params->buffer_size, /* { dg-bogus "use of attacker-controlled value '\\*params.buffer_size' as allocation size without upper-bounds checking" "PR analyzer/112850" } */
+ (((gfp_t)(0x400u | 0x800u)) | ((gfp_t)0x40u) | ((gfp_t)0x80u)));
+ if (!newbuf)
+ return -12;
+ return 0;
+}
+
+long
+snd_rawmidi_ioctl(unsigned long arg)
+{
+ void* argp = (void*)arg;
+ struct snd_rawmidi_params params;
+ if (copy_from_user(&params, argp, sizeof(struct snd_rawmidi_params)))
+ return -14;
+ return resize_runtime_buffer(&params);
+}