aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2022-07-20 21:34:17 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2022-07-20 21:34:17 -0400
commit742377ed0f09313503a1c5393c4f742d69249521 (patch)
tree94d83c15308fa9131d986baf58b5fb3757c19c8e
parenta6c192e80a87efbe6c0641f25a963c7bee9990fb (diff)
downloadgcc-742377ed0f09313503a1c5393c4f742d69249521.zip
gcc-742377ed0f09313503a1c5393c4f742d69249521.tar.gz
gcc-742377ed0f09313503a1c5393c4f742d69249521.tar.bz2
analyzer: bulletproof taint warnings against NULL m_arg
gcc/analyzer/ChangeLog: * sm-taint.cc (tainted_array_index::emit): Bulletproof against NULL m_arg. (tainted_array_index::describe_final_event): Likewise. (tainted_size::emit): Likewise. (tainted_size::describe_final_event): Likewise. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
-rw-r--r--gcc/analyzer/sm-taint.cc247
1 files changed, 164 insertions, 83 deletions
diff --git a/gcc/analyzer/sm-taint.cc b/gcc/analyzer/sm-taint.cc
index 0486c01..51bfe06 100644
--- a/gcc/analyzer/sm-taint.cc
+++ b/gcc/analyzer/sm-taint.cc
@@ -212,53 +212,96 @@ public:
diagnostic_metadata m;
/* CWE-129: "Improper Validation of Array Index". */
m.add_cwe (129);
- switch (m_has_bounds)
- {
- default:
- gcc_unreachable ();
- case BOUNDS_NONE:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value %qE"
- " in array lookup without bounds checking",
- m_arg);
- break;
- case BOUNDS_UPPER:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value %qE"
- " in array lookup without checking for negative",
- m_arg);
- break;
- case BOUNDS_LOWER:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value %qE"
- " in array lookup without upper-bounds checking",
- m_arg);
- break;
- }
+ if (m_arg)
+ switch (m_has_bounds)
+ {
+ default:
+ gcc_unreachable ();
+ case BOUNDS_NONE:
+ return warning_meta (rich_loc, m, get_controlling_option (),
+ "use of attacker-controlled value %qE"
+ " in array lookup without bounds checking",
+ m_arg);
+ break;
+ case BOUNDS_UPPER:
+ return warning_meta (rich_loc, m, get_controlling_option (),
+ "use of attacker-controlled value %qE"
+ " in array lookup without checking for negative",
+ m_arg);
+ break;
+ case BOUNDS_LOWER:
+ return warning_meta (rich_loc, m, get_controlling_option (),
+ "use of attacker-controlled value %qE"
+ " in array lookup without upper-bounds checking",
+ m_arg);
+ break;
+ }
+ else
+ switch (m_has_bounds)
+ {
+ default:
+ gcc_unreachable ();
+ case BOUNDS_NONE:
+ return warning_meta (rich_loc, m, get_controlling_option (),
+ "use of attacker-controlled value"
+ " in array lookup without bounds checking");
+ break;
+ case BOUNDS_UPPER:
+ return warning_meta (rich_loc, m, get_controlling_option (),
+ "use of attacker-controlled value"
+ " in array lookup without checking for"
+ " negative");
+ break;
+ case BOUNDS_LOWER:
+ return warning_meta (rich_loc, m, get_controlling_option (),
+ "use of attacker-controlled value"
+ " in array lookup without upper-bounds"
+ " checking");
+ break;
+ }
}
label_text describe_final_event (const evdesc::final_event &ev) final override
{
- switch (m_has_bounds)
- {
- default:
- gcc_unreachable ();
- case BOUNDS_NONE:
- return ev.formatted_print
- ("use of attacker-controlled value %qE in array lookup"
- " without bounds checking",
- m_arg);
- case BOUNDS_UPPER:
- return ev.formatted_print
- ("use of attacker-controlled value %qE"
- " in array lookup without checking for negative",
- m_arg);
- case BOUNDS_LOWER:
- return ev.formatted_print
- ("use of attacker-controlled value %qE"
- " in array lookup without upper-bounds checking",
- m_arg);
- }
+ if (m_arg)
+ switch (m_has_bounds)
+ {
+ default:
+ gcc_unreachable ();
+ case BOUNDS_NONE:
+ return ev.formatted_print
+ ("use of attacker-controlled value %qE in array lookup"
+ " without bounds checking",
+ m_arg);
+ case BOUNDS_UPPER:
+ return ev.formatted_print
+ ("use of attacker-controlled value %qE"
+ " in array lookup without checking for negative",
+ m_arg);
+ case BOUNDS_LOWER:
+ return ev.formatted_print
+ ("use of attacker-controlled value %qE"
+ " in array lookup without upper-bounds checking",
+ m_arg);
+ }
+ else
+ switch (m_has_bounds)
+ {
+ default:
+ gcc_unreachable ();
+ case BOUNDS_NONE:
+ return ev.formatted_print
+ ("use of attacker-controlled value in array lookup"
+ " without bounds checking");
+ case BOUNDS_UPPER:
+ return ev.formatted_print
+ ("use of attacker-controlled value"
+ " in array lookup without checking for negative");
+ case BOUNDS_LOWER:
+ return ev.formatted_print
+ ("use of attacker-controlled value"
+ " in array lookup without upper-bounds checking");
+ }
}
};
@@ -394,50 +437,88 @@ public:
{
diagnostic_metadata m;
m.add_cwe (129);
- switch (m_has_bounds)
- {
- default:
- gcc_unreachable ();
- case BOUNDS_NONE:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value %qE as size"
- " without bounds checking",
- m_arg);
- break;
- case BOUNDS_UPPER:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value %qE as size"
- " without lower-bounds checking",
- m_arg);
- break;
- case BOUNDS_LOWER:
- return warning_meta (rich_loc, m, get_controlling_option (),
- "use of attacker-controlled value %qE as size"
- " without upper-bounds checking",
- m_arg);
- break;
- }
+ if (m_arg)
+ switch (m_has_bounds)
+ {
+ default:
+ gcc_unreachable ();
+ case BOUNDS_NONE:
+ return warning_meta (rich_loc, m, get_controlling_option (),
+ "use of attacker-controlled value %qE as size"
+ " without bounds checking",
+ m_arg);
+ break;
+ case BOUNDS_UPPER:
+ return warning_meta (rich_loc, m, get_controlling_option (),
+ "use of attacker-controlled value %qE as size"
+ " without lower-bounds checking",
+ m_arg);
+ break;
+ case BOUNDS_LOWER:
+ return warning_meta (rich_loc, m, get_controlling_option (),
+ "use of attacker-controlled value %qE as size"
+ " without upper-bounds checking",
+ m_arg);
+ break;
+ }
+ else
+ switch (m_has_bounds)
+ {
+ default:
+ gcc_unreachable ();
+ case BOUNDS_NONE:
+ return warning_meta (rich_loc, m, get_controlling_option (),
+ "use of attacker-controlled value as size"
+ " without bounds checking");
+ break;
+ case BOUNDS_UPPER:
+ return warning_meta (rich_loc, m, get_controlling_option (),
+ "use of attacker-controlled value as size"
+ " without lower-bounds checking");
+ break;
+ case BOUNDS_LOWER:
+ return warning_meta (rich_loc, m, get_controlling_option (),
+ "use of attacker-controlled value as size"
+ " without upper-bounds checking");
+ break;
+ }
}
label_text describe_final_event (const evdesc::final_event &ev) final override
{
- switch (m_has_bounds)
- {
- default:
- gcc_unreachable ();
- case BOUNDS_NONE:
- return ev.formatted_print ("use of attacker-controlled value %qE"
- " as size without bounds checking",
- m_arg);
- case BOUNDS_UPPER:
- return ev.formatted_print ("use of attacker-controlled value %qE"
- " as size without lower-bounds checking",
- m_arg);
- case BOUNDS_LOWER:
- return ev.formatted_print ("use of attacker-controlled value %qE"
- " as size without upper-bounds checking",
- m_arg);
- }
+ if (m_arg)
+ switch (m_has_bounds)
+ {
+ default:
+ gcc_unreachable ();
+ case BOUNDS_NONE:
+ return ev.formatted_print ("use of attacker-controlled value %qE"
+ " as size without bounds checking",
+ m_arg);
+ case BOUNDS_UPPER:
+ return ev.formatted_print ("use of attacker-controlled value %qE"
+ " as size without lower-bounds checking",
+ m_arg);
+ case BOUNDS_LOWER:
+ return ev.formatted_print ("use of attacker-controlled value %qE"
+ " as size without upper-bounds checking",
+ m_arg);
+ }
+ else
+ switch (m_has_bounds)
+ {
+ default:
+ gcc_unreachable ();
+ case BOUNDS_NONE:
+ return ev.formatted_print ("use of attacker-controlled value"
+ " as size without bounds checking");
+ case BOUNDS_UPPER:
+ return ev.formatted_print ("use of attacker-controlled value"
+ " as size without lower-bounds checking");
+ case BOUNDS_LOWER:
+ return ev.formatted_print ("use of attacker-controlled value"
+ " as size without upper-bounds checking");
+ }
}
};