From patchwork Wed Apr 10 20:56:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 1922230 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=HG8w+oWz; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VFFXQ6G6Yz1yYB for ; Thu, 11 Apr 2024 06:57:58 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E2D743849AFD for ; Wed, 10 Apr 2024 20:57:56 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 2B3793849AEA for ; Wed, 10 Apr 2024 20:56:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2B3793849AEA Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 2B3793849AEA Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1712782593; cv=none; b=EA702fXWaYSijyeg5LOPlC80omsSHBPSuWm4hcE2One7lzubeueCyQWY6kKjd7bsFjL7Q4j/yx0diFe3TZbiHo9VoJ5nwHV6RdPQ+heebQKHhvqvhCfNE5WYmfwA4w/HPUZJeMIE5JGGSdCCMLlOJfw/TrErtaZQ305rdKz/cxk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1712782593; c=relaxed/simple; bh=ZlPyG/5QXoJAdYePOREw3Owj0rt3wpDu7FCxWXRPMgE=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=q9o8l4pSpgOa/meXu96QabNlWzxHA/9NSpGlmg6J62A82hTUql1m6LkughEvPqjA2mmUYJMElB2ePxdkqZVcRmXgpmcLyjjkB2/RRCLOwHzJ23rJP76JpJipuy+vHqd6utjrpc7tq+j2XVWxTjdZ57n2D+0YbTvb91X8iqVL094= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1712782582; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=s7WvFWNtWBPeZ2keXsr1Io/PyoBeWUbEChkmCnLfzms=; b=HG8w+oWzc+EPM2upTZ6Tdz861aqZGR5SDJjKtoGFg0NSIaby5m22uhwpk0MUAAGgL/jHh2 +Vn/EtE32g2qrzv1MGEs1q0WnPyEeNeksztl/eHRrt/jRk5KHwT57/8KuT2+Rm8DwWS2yV Y8inISBpXh5EXqhxlH1wacia9zoQ1JE= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-457-3tflVYq_MoevEmbbIa0wlA-1; Wed, 10 Apr 2024 16:56:20 -0400 X-MC-Unique: 3tflVYq_MoevEmbbIa0wlA-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 91DEC800219 for ; Wed, 10 Apr 2024 20:56:20 +0000 (UTC) Received: from t14s.localdomain.com (unknown [10.22.33.30]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6A23C40B4983; Wed, 10 Apr 2024 20:56:20 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [pushed] analyzer: fix ICE on negative values for size_t [PR114472] Date: Wed, 10 Apr 2024 16:56:19 -0400 Message-Id: <20240410205619.335838-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.2 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org I made several attempts to fix this properly, but for now apply a band-aid to at least prevent crashing on such cases. Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. Successful run of analyzer integration tests on x86_64-pc-linux-gnu. Pushed to trunk as r14-9902-g4a94551d7eaaf7. gcc/analyzer/ChangeLog: PR analyzer/114472 * access-diagram.cc (bit_size_expr::maybe_get_formatted_str): Reject attempts to print sizes that are too large. * region.cc (region_offset::calc_symbolic_bit_offset): Use a typeless svalue for the bit offset. * store.cc (bit_range::intersects_p): Replace assertion with test. (bit_range::exceeds_p): Likewise. (bit_range::falls_short_of_p): Likewise. gcc/testsuite/ChangeLog: * c-c++-common/analyzer/out-of-bounds-pr114472.c: New test. Signed-off-by: David Malcolm --- gcc/analyzer/access-diagram.cc | 4 ++++ gcc/analyzer/region.cc | 2 +- gcc/analyzer/store.cc | 20 +++++++++++++++---- .../analyzer/out-of-bounds-pr114472.c | 17 ++++++++++++++++ 4 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/analyzer/out-of-bounds-pr114472.c diff --git a/gcc/analyzer/access-diagram.cc b/gcc/analyzer/access-diagram.cc index 4cb6570e90b9..873205c46499 100644 --- a/gcc/analyzer/access-diagram.cc +++ b/gcc/analyzer/access-diagram.cc @@ -373,6 +373,8 @@ bit_size_expr::maybe_get_formatted_str (text_art::style_manager &sm, if (tree cst = num_bytes->maybe_get_constant ()) { byte_size_t concrete_num_bytes = wi::to_offset (cst); + if (!wi::fits_uhwi_p (concrete_num_bytes)) + return nullptr; if (concrete_num_bytes == 1) return ::make_unique (fmt_styled_string (sm, concrete_single_byte_fmt, @@ -396,6 +398,8 @@ bit_size_expr::maybe_get_formatted_str (text_art::style_manager &sm, else if (tree cst = m_num_bits.maybe_get_constant ()) { bit_size_t concrete_num_bits = wi::to_offset (cst); + if (!wi::fits_uhwi_p (concrete_num_bits)) + return nullptr; if (concrete_num_bits == 1) return ::make_unique (fmt_styled_string (sm, concrete_single_bit_fmt, diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc index 705816b62454..7d79b45563fd 100644 --- a/gcc/analyzer/region.cc +++ b/gcc/analyzer/region.cc @@ -89,7 +89,7 @@ region_offset::calc_symbolic_bit_offset (region_model_manager *mgr) const m_sym_offset, bits_per_byte); } else - return *mgr->get_or_create_int_cst (size_type_node, m_offset); + return *mgr->get_or_create_int_cst (NULL_TREE, m_offset); } const svalue * diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc index e85a19647f7e..a36de13c1743 100644 --- a/gcc/analyzer/store.cc +++ b/gcc/analyzer/store.cc @@ -290,7 +290,10 @@ bit_range::intersects_p (const bit_range &other, bit_offset_t overlap_next = MIN (get_next_bit_offset (), other.get_next_bit_offset ()); - gcc_assert (overlap_next > overlap_start); + if (overlap_next <= overlap_start) + /* If this has happened, some kind of overflow has happened in + our arithmetic. For now, reject such cases. */ + return false; bit_range abs_overlap_bits (overlap_start, overlap_next - overlap_start); *out_this = abs_overlap_bits - get_start_bit_offset (); *out_other = abs_overlap_bits - other.get_start_bit_offset (); @@ -316,7 +319,10 @@ bit_range::intersects_p (const bit_range &other, other.get_start_bit_offset ()); bit_offset_t overlap_next = MIN (get_next_bit_offset (), other.get_next_bit_offset ()); - gcc_assert (overlap_next > overlap_start); + if (overlap_next <= overlap_start) + /* If this has happened, some kind of overflow has happened in + our arithmetic. For now, reject such cases. */ + return false; *out_num_overlap_bits = overlap_next - overlap_start; return true; } @@ -339,7 +345,10 @@ bit_range::exceeds_p (const bit_range &other, bit_offset_t start = MAX (get_start_bit_offset (), other.get_next_bit_offset ()); bit_offset_t size = get_next_bit_offset () - start; - gcc_assert (size > 0); + if (size <= 0) + /* If this has happened, some kind of overflow has happened in + our arithmetic. For now, reject such cases. */ + return false; out_overhanging_bit_range->m_start_bit_offset = start; out_overhanging_bit_range->m_size_in_bits = size; return true; @@ -362,7 +371,10 @@ bit_range::falls_short_of_p (bit_offset_t offset, /* THIS falls short of OFFSET. */ bit_offset_t start = get_start_bit_offset (); bit_offset_t size = MIN (offset, get_next_bit_offset ()) - start; - gcc_assert (size > 0); + if (size <= 0) + /* If this has happened, some kind of overflow has happened in + our arithmetic. For now, reject such cases. */ + return false; out_fall_short_bits->m_start_bit_offset = start; out_fall_short_bits->m_size_in_bits = size; return true; diff --git a/gcc/testsuite/c-c++-common/analyzer/out-of-bounds-pr114472.c b/gcc/testsuite/c-c++-common/analyzer/out-of-bounds-pr114472.c new file mode 100644 index 000000000000..ef9e7711a2e4 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/out-of-bounds-pr114472.c @@ -0,0 +1,17 @@ +/* Verify we don't ICE on cases involving very large values for size. */ + +char s, d; + +void +foo(void) +{ + __builtin_strncpy(&d, &s + 3, -1); /* { dg-warning "Wstringop-overflow" } */ + __builtin_strncpy(&d + 3, &s, -1); /* { dg-warning "Wstringop-overflow" } */ +} + +void +bar(void) +{ + __builtin_strncpy(&d, &s - 3, -1); /* { dg-warning "Wstringop-overflow" } */ + __builtin_strncpy(&d - 3, &s, -1); /* { dg-warning "Wstringop-overflow" } */ +}