From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2209) id 11AAF3834E5B; Thu, 21 Jul 2022 01:39:26 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 11AAF3834E5B MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: David Malcolm To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-1774] analyzer: bulletproof taint warnings against NULL m_arg X-Act-Checkin: gcc X-Git-Author: David Malcolm X-Git-Refname: refs/heads/master X-Git-Oldrev: a6c192e80a87efbe6c0641f25a963c7bee9990fb X-Git-Newrev: 742377ed0f09313503a1c5393c4f742d69249521 Message-Id: <20220721013926.11AAF3834E5B@sourceware.org> Date: Thu, 21 Jul 2022 01:39:26 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 21 Jul 2022 01:39:26 -0000 https://gcc.gnu.org/g:742377ed0f09313503a1c5393c4f742d69249521 commit r13-1774-g742377ed0f09313503a1c5393c4f742d69249521 Author: David Malcolm Date: Wed Jul 20 21:34:17 2022 -0400 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 Diff: --- gcc/analyzer/sm-taint.cc | 247 +++++++++++++++++++++++++++++++---------------- 1 file changed, 164 insertions(+), 83 deletions(-) diff --git a/gcc/analyzer/sm-taint.cc b/gcc/analyzer/sm-taint.cc index 0486c01aaca..51bfe06835d 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"); + } } };