From patchwork Thu Aug 11 17:24:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tim Lange X-Patchwork-Id: 474 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:6a10:38f:b0:2d5:3c95:9e21 with SMTP id 15csp357554pxh; Thu, 11 Aug 2022 10:26:24 -0700 (PDT) X-Google-Smtp-Source: AA6agR7/8FR6TjTQT9jhVm/pctDOec0HsiK7llaOML27s1aOUsx23Z23j+WDwFMk++bIGhV9L+Ft X-Received: by 2002:a05:6402:304c:b0:440:d482:2fa6 with SMTP id bs12-20020a056402304c00b00440d4822fa6mr144483edb.344.1660238784474; Thu, 11 Aug 2022 10:26:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1660238784; cv=none; d=google.com; s=arc-20160816; b=qNKkL7tqbRWuYkrTA1LzrDIgJIVbQV8TiK2zaXW2+dc5KejrHdOQZ2vmpkUL+O5uc8 5E29WHOWGUxNoO6oY60t+u4SB/iWv6VMRtEKk/SB2UCwBM1PiUokD2cddb8UKwe6RrXu ts2LtkOkMsWbX3fUDPPoXdeWublRcoIE8gjbCxbINXMns81DlL+Kuv9JOrQe8TRyQ0XE RAiMw4FdpTPE7Pfo1di7dxeQtN1xcY3/AN9tbRC7t+qP12cACslPxGCDlAw5xFC412KA PO0wHGLdGFz/Y8vRBOz1B9ThBTtszI2/pkhNONDQpltk56ZTmLcjw7ZFuPUwO6i3PSIb 9P+A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature:dmarc-filter:delivered-to; bh=H8/zl94gO5lUjoS9SpUcVYA6SnOwR66/jSEvNWHPmvY=; b=Fxabug8tJpqiA+y9L5Qheqc7XTFJrBQmBTrjLgqr6KsUwja2LJB02N1gPxC+eveVAF pWQGq2FVygBGovN6yO3+RZbl/Ug++xgoAazgmms92v02C4lfKoQUC9Rd0XmPHyTCPuL4 Xh3MgNGBGElVOdntosDcyJRIqfvquPj6UvB/2i2gcldpS7IgV+NuA2RnfJxLBjuiSNLt 3OH0dkdfkp6D2Ycsqr3M4dOBhev2KqjrXMr3G0WGPiE19OCq/V8hvmWAAnC5oCGfdYRL AhRuVAKAIympTBuMc4SAYKPnbFNUVo9lh9ym6pKevUJiaYWxNEPhTHT8E9zSHwvIoLTa /Rrw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@tim-lange.me header.s=default2108 header.b=PT64vXKr; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id o14-20020a170906358e00b00710487d3a4fsi1150895ejb.67.2022.08.11.10.26.24 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Aug 2022 10:26:24 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=fail header.i=@tim-lange.me header.s=default2108 header.b=PT64vXKr; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 82D12385BC23 for ; Thu, 11 Aug 2022 17:26:12 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from www523.your-server.de (www523.your-server.de [159.69.224.22]) by sourceware.org (Postfix) with ESMTPS id 935ED3856251 for ; Thu, 11 Aug 2022 17:25:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 935ED3856251 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=tim-lange.me Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=tim-lange.me DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tim-lange.me; s=default2108; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID; bh=H8/zl94gO5lUjoS9SpUcVYA6SnOwR66/jSEvNWHPmvY=; b=PT64vXKrJnVEbQm0fUcT3AZcN4 AKlxCNnkbubUVEgBI1ffY9alsDBbZozEDCVJwRh2v89kmXg+dM4Xj5za0IOHfAHjbEuXXPxe7ZubD eDv8YPg29d7svYqWcb2kyE4TQfgoqq2IxoRugwbcRye4WNmzXkeqmOm2W8psfjmCPPef3Y8hzPPLi 6o7doh61xrFStNDYVpofOmiIFIK1IRTFZU/lp/m+K7a654I40heKOengmjIctWBX1NJBLQ/fB1DfB o9joZ2r1oVVF3Kfy/zFw57ESClk5AmmguAQpRLf/E9EXRuP0fDJqR57ZH9MceC73U9SsC0uyG2YKd hmcS2HEA==; Received: from sslproxy05.your-server.de ([78.46.172.2]) by www523.your-server.de with esmtpsa (TLSv1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.92.3) (envelope-from ) id 1oMBvc-0006uE-ND; Thu, 11 Aug 2022 19:25:04 +0200 Received: from [2a02:908:1861:d6a0::6b5] (helo=fedora..) by sslproxy05.your-server.de with esmtpsa (TLSv1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1oMBvc-000RVC-H5; Thu, 11 Aug 2022 19:25:04 +0200 From: Tim Lange To: gcc-patches@gcc.gnu.org Subject: [PATCH 1/2 v2] analyzer: consider that realloc could shrink the buffer [PR106539] Date: Thu, 11 Aug 2022 19:24:51 +0200 Message-Id: <20220811172452.65996-1-mail@tim-lange.me> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20220809211943.82098-1-mail@tim-lange.me> References: <20220809211943.82098-1-mail@tim-lange.me> MIME-Version: 1.0 X-Authenticated-Sender: mail@tim-lange.me X-Virus-Scanned: Clear (ClamAV 0.103.6/26624/Thu Aug 11 09:52:26 2022) X-Spam-Status: No, score=-12.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_INFOUSMEBIZ, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Tim Lange Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1740720094081817987?= X-GMAIL-MSGID: =?utf-8?q?1740886543412111933?= This patch adds the "shrinks buffer" case to the success_with_move modelling of realloc. Regression-tested on Linux x86-64, further ran the analyzer tests with the -m32 option. 2022-08-11 Tim Lange gcc/analyzer/ChangeLog: PR analyzer/106539 * region-model-impl-calls.cc (region_model::impl_call_realloc): Use the result of get_copied_size as the size for the sized_regions in realloc. (success_with_move::get_copied_size): New function. gcc/testsuite/ChangeLog: PR analyzer/106539 * gcc.dg/analyzer/pr106539.c: New test. * gcc.dg/analyzer/realloc-5.c: New test. --- gcc/analyzer/region-model-impl-calls.cc | 48 ++++++++++++++++++++--- gcc/testsuite/gcc.dg/analyzer/pr106539.c | 15 +++++++ gcc/testsuite/gcc.dg/analyzer/realloc-5.c | 45 +++++++++++++++++++++ 3 files changed, 102 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr106539.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/realloc-5.c diff --git a/gcc/analyzer/region-model-impl-calls.cc b/gcc/analyzer/region-model-impl-calls.cc index 8c38e9206fa..fa0ec88b1f4 100644 --- a/gcc/analyzer/region-model-impl-calls.cc +++ b/gcc/analyzer/region-model-impl-calls.cc @@ -732,15 +732,17 @@ region_model::impl_call_realloc (const call_details &cd) const svalue *old_size_sval = model->get_dynamic_extents (freed_reg); if (old_size_sval) { - const region *sized_old_reg + const svalue *copied_size_sval + = get_copied_size (old_size_sval, new_size_sval); + const region *copied_old_reg = model->m_mgr->get_sized_region (freed_reg, NULL, - old_size_sval); + copied_size_sval); const svalue *buffer_content_sval - = model->get_store_value (sized_old_reg, cd.get_ctxt ()); - const region *sized_new_reg + = model->get_store_value (copied_old_reg, cd.get_ctxt ()); + const region *copied_new_reg = model->m_mgr->get_sized_region (new_reg, NULL, - old_size_sval); - model->set_value (sized_new_reg, buffer_content_sval, + copied_size_sval); + model->set_value (copied_new_reg, buffer_content_sval, cd.get_ctxt ()); } else @@ -774,6 +776,40 @@ region_model::impl_call_realloc (const call_details &cd) else return true; } + + private: + /* Return the lesser of OLD_SIZE_SVAL and NEW_SIZE_SVAL. + If either one is symbolic, the symbolic svalue is returned. */ + const svalue *get_copied_size (const svalue *old_size_sval, + const svalue *new_size_sval) const + { + tree old_size_cst = old_size_sval->maybe_get_constant (); + tree new_size_cst = new_size_sval->maybe_get_constant (); + + if (old_size_cst && new_size_cst) + { + /* Both are constants and comparable. */ + tree cmp = fold_binary (LT_EXPR, boolean_type_node, + old_size_cst, new_size_cst); + + if (cmp == boolean_true_node) + return old_size_sval; + else + return new_size_sval; + } + else if (new_size_cst) + { + /* OLD_SIZE_SVAL is symbolic, so return that. */ + return old_size_sval; + } + else + { + /* NEW_SIZE_SVAL is symbolic or both are symbolic. + Return NEW_SIZE_SVAL, because implementations of realloc + probably only moves the buffer if the new size is larger. */ + return new_size_sval; + } + } }; /* Body of region_model::impl_call_realloc. */ diff --git a/gcc/testsuite/gcc.dg/analyzer/pr106539.c b/gcc/testsuite/gcc.dg/analyzer/pr106539.c new file mode 100644 index 00000000000..fd270868e36 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr106539.c @@ -0,0 +1,15 @@ +#include + +void *test (void) +{ + void **p = (void **)malloc (sizeof (void *) * 2); + if (!p) + return NULL; + p[0] = malloc(10); + p[1] = malloc(20); /* { dg-message "allocated here" } */ + void *q = realloc (p, sizeof (void *)); /* { dg-message "when 'realloc' succeeds, moving buffer" } */ + if (!q) + /* { dg-warning "leak of ''" "leak of unknown" { target *-*-* } .-1 } */ + return p; + return q; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/realloc-5.c b/gcc/testsuite/gcc.dg/analyzer/realloc-5.c new file mode 100644 index 00000000000..2efe3371e12 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/realloc-5.c @@ -0,0 +1,45 @@ +#include "analyzer-decls.h" + +typedef __SIZE_TYPE__ size_t; + +#define NULL ((void *)0) + +extern void *malloc (size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__malloc__)) + __attribute__ ((__alloc_size__ (1))); +extern void *realloc (void *__ptr, size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__warn_unused_result__)) + __attribute__ ((__alloc_size__ (2))); +extern void free (void *__ptr) + __attribute__ ((__nothrow__ , __leaf__)); +extern void *memset (void *__ptr, int __value, size_t __size); + +/* realloc where the region shrinks on success_with_move. */ + +void test_1 () +{ + char *p = malloc (16); + if (!p) + return; + memset (p, 1, 16); + + char *q = realloc (p, 8); + if (!q) + { + free (p); + return; + } + else if (p != q) + { + __analyzer_dump_capacity (q); /* { dg-warning "capacity: '\\(\[^\n\r\]*\\)8'" } */ + __analyzer_eval (q[8] == 1); /* { dg-line eval } */ + + /* { dg-warning "UNKNOWN" "warning" { target *-*-* } eval } */ + /* { dg-warning "overread" "warning" { target *-*-* } eval } */ + /* { dg-warning "use of uninitialized value" "warning" { target *-*-* } eval } */ + } + + free (q); +}