From patchwork Mon Jan 29 08:25:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 193325 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:2087:b0:106:209c:c626 with SMTP id gs7csp428387dyb; Mon, 29 Jan 2024 00:26:46 -0800 (PST) X-Google-Smtp-Source: AGHT+IGmesE2ZL1Supee81Ba/88NykYMw/tQlJry8kVw1JNTS4bQCe48g9g2iBdcKrBfNIu8ZxeS X-Received: by 2002:a05:622a:174e:b0:42a:6e2f:cb6e with SMTP id l14-20020a05622a174e00b0042a6e2fcb6emr7112517qtk.46.1706516805846; Mon, 29 Jan 2024 00:26:45 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706516805; cv=pass; d=google.com; s=arc-20160816; b=NVPj31/vm0f6I+b/ByILNcEr1vFS4OO0gKwsoawS7D64lr/UlluP/ywcyxihyh/9Bv 2KWmkbWtiWolUIxBvbuPb/YeNAXLBTDE3okhjuKLOaAFbyFbR+6J4tvvgdNsWfoEsLIk 4xsNv5N0Pf8jn0xVzf4NivBjYlk8vHinwJDQ91Q2AsYbKSdwFMk8a+SJ3eq01CzfPZ6y saJCSKH6Qr64uqzp/jYkRyXCO5s4RNjz9fp+Vz7pV78snijBacf1cof8mkg6SUVMUVx6 wpHU8NmvuXa2/qBel00VfrUlSwSt+H0S0AFJvfXijVhOcLBoxlUOvX3unDySDkeMzxeY cS3g== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:reply-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-disposition :mime-version:message-id:subject:cc:to:from:date:dkim-signature :arc-filter:dmarc-filter:delivered-to; bh=cU6GaMnwdTzQfWhrLFMWf72jdMFb2Byg2SevtggjPkU=; fh=lFYQHvTg9MF9RPfUVKuuvRAP8kqWw7dDGuJusFB1EQA=; b=QNBaqF8Lo/qBOoz9Hvyu5T1uPw3fMpsrFvwoq5nLOo+P1QeUAHH5VnTpvTlt21TVy1 f8pI0X21whDDWoAm446X82cL842Qq5QvRkqgYo3rgzJz3+q8z/yyj8tpVT97x02ifOUt ZAfOCv084pPT8bUgeHknxpiwnwPRmWzYtcKgNxOul7hXTcQwK1Pr9gHDEU/FBUqSFgge 62hhnNx9Lo4ceK+PLjU99ykOVR/eV4+r2T+z1DSzuS4vTFu2V+OcYjlg8lUPsLIbMlI7 B3kU//jyYrETAkYhN6AiKz8PmVUpK2yXX755bFVY5bWXXKFmjyOnvZeSComKwPgtt8k1 2JVA== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=g7YGDXK6; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from server2.sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id h19-20020ac85e13000000b0042a9be4169asi2853340qtx.39.2024.01.29.00.26.45 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 29 Jan 2024 00:26:45 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=g7YGDXK6; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5B071385843B for ; Mon, 29 Jan 2024 08:26:45 +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.133.124]) by sourceware.org (Postfix) with ESMTPS id DEA433858402 for ; Mon, 29 Jan 2024 08:25:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DEA433858402 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 DEA433858402 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1706516730; cv=none; b=HAUGj8YLpMRddCmYoEbVNrWd9oTtijuJl3iOk9uFM9cH1fDYZGXadVAb9II2g87NEkcVxsR0JhWzL/vdr/5PnGJhh95m2wxQQ3fEOM2JIbLtkhfz6E9LYdtaBbpwBRzq2XTa/Gm+VlKsiWXCoXpCJbNC0KgURYhJwx7n5pZN6A4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1706516730; c=relaxed/simple; bh=hBgBEFvAYsonDfS7KY51nCEYu7DRVW0DCaQ6jpFO2mE=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=DqzG8Xug23jsdRBvliGiNXyqUtVKGKl5g4d8IWPw7bJCWKvFbTI/M6ajehf5HqIshTuV2Zl2ZiypOBCHzn0G0D9mP/rsPYRMS1Pgt4JsAfa3ILA3G26o8+46kY4OQvAcIPu3kwaaBJ6ncdMm86VRxv1w1QQ1Lxnn2bahIwTkdLw= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1706516726; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type; bh=cU6GaMnwdTzQfWhrLFMWf72jdMFb2Byg2SevtggjPkU=; b=g7YGDXK6UXaLd+UDNJWpX6Jh1g7NYTuue2pfM0yY7IPeJ7RfZBqVpuQsBAQgJGntEblDHi okC4tdzLmoeuiOYBuerBsdMPHGTO5e3acItxdnMKOUtzOLv8/278FuyNkdnWCanluC0PKN tWW4TurNrbjdjE43z9uCtotzTLVkhJc= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-454-3K3cbucnPmm3FSzFPJNQOg-1; Mon, 29 Jan 2024 03:25:22 -0500 X-MC-Unique: 3K3cbucnPmm3FSzFPJNQOg-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (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 9A407381D4C4; Mon, 29 Jan 2024 08:25:22 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.192.70]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 610C3492BC8; Mon, 29 Jan 2024 08:25:22 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 40T8PJJ52967530 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Mon, 29 Jan 2024 09:25:20 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 40T8PIVG2967529; Mon, 29 Jan 2024 09:25:18 +0100 Date: Mon, 29 Jan 2024 09:25:18 +0100 From: Jakub Jelinek To: Jeff Law , Richard Biener Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] tree-ssa-strlen: Fix pdata->maxlen computation [PR110603] Message-ID: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.9 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-4.3 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, 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.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Jakub Jelinek Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789412566059406795 X-GMAIL-MSGID: 1789412566059406795 Hi! On the following testcase we emit an invalid range of [2, 1] due to UB in the source. Older VRP code silently swapped the boundaries and made [1, 2] range out of it, but newer code just ICEs on it. The reason for pdata->minlen 2 is that we see a memcpy in this case setting both elements of the array to non-zero value, so strlen (a) can't be smaller than 2. The reason for pdata->maxlen 1 is that in char a[2] array without UB there can be at most 1 non-zero character because there needs to be '\0' termination in the buffer too. IMHO we shouldn't create invalid ranges like that and even creating for that case a range [1, 2] looks wrong to me, so the following patch just doesn't set maxlen in that case to the array size - 1, matching what will really happen at runtime when triggering such UB (strlen will be at least 2, perhaps more or will crash). This is what the second hunk of the patch does. The first hunk fixes a fortunately harmless thinko. If the strlen pass knows the string length (i.e. get_string_length function returns non-NULL), we take a different path, we get to this only if all we know is that there are certain number of non-zero characters but we don't know what it is followed with, whether further non-zero characters or zero termination or either of that. If we know exactly how many non-zero characters it is, such as char a[42]; ... memcpy (a, "01234567890123456789", 20); then we take an earlier if for the INTEGER_CST case and set correctly just pdata->minlen to 20 in that case, but if we have something like int len; ... if (len < 15 || len > 32) return; memcpy (a, "0123456789012345678901234567890123456789", len); then we have [15, 32] range for the nonzero_chars and we set pdata->minlen correctly to 15, but incorrectly set also pdata->maxlen to 32. That is not what the above implies, it just means that in some cases we know that there are at least 32 non-zero characters, followed by something we don't know. There is no guarantee that there is '\0' right after it, so it means nothing. The reason this is harmless, just confusing, is that the code a few lines later fortunately overwrites this incorrect pdata->maxlen value with something different (either array length - 1 or all ones etc.). Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2024-01-29 Jakub Jelinek PR tree-optimization/110603 * tree-ssa-strlen.cc (get_range_strlen_dynamic): Remove incorrect setting of pdata->maxlen to vr.upper_bound (which is unconditionally overwritten anyway). Avoid creating invalid range with minlen larger than maxlen. Formatting fix. * gcc.c-torture/compile/pr110603.c: New test. Jakub --- gcc/tree-ssa-strlen.cc.jj 2024-01-03 11:51:32.664715465 +0100 +++ gcc/tree-ssa-strlen.cc 2024-01-27 13:32:25.506401969 +0100 @@ -1228,7 +1228,6 @@ get_range_strlen_dynamic (tree src, gimp { tree type = vr.type (); pdata->minlen = wide_int_to_tree (type, vr.lower_bound ()); - pdata->maxlen = wide_int_to_tree (type, vr.upper_bound ()); } } else @@ -1253,9 +1252,21 @@ get_range_strlen_dynamic (tree src, gimp { ++off; /* Increment for the terminating nul. */ tree toffset = build_int_cst (size_type_node, off); - pdata->maxlen = fold_build2 (MINUS_EXPR, size_type_node, size, - toffset); - pdata->maxbound = pdata->maxlen; + pdata->maxlen = fold_build2 (MINUS_EXPR, size_type_node, + size, toffset); + if (tree_int_cst_lt (pdata->maxlen, pdata->minlen)) + /* This can happen when triggering UB, when base is an + array which is known to be filled with at least size + non-zero bytes. E.g. for + char a[2]; memcpy (a, "12", sizeof a); + We don't want to create an invalid range [2, 1] + where 2 comes from the number of non-zero bytes and + 1 from longest valid zero-terminated string that can + be stored in such an array, so pick just one of + those, pdata->minlen. See PR110603. */ + pdata->maxlen = build_all_ones_cst (size_type_node); + else + pdata->maxbound = pdata->maxlen; } else pdata->maxlen = build_all_ones_cst (size_type_node); --- gcc/testsuite/gcc.c-torture/compile/pr110603.c.jj 2024-01-27 13:37:29.375194755 +0100 +++ gcc/testsuite/gcc.c-torture/compile/pr110603.c 2024-01-27 13:37:03.104558479 +0100 @@ -0,0 +1,16 @@ +/* PR tree-optimization/110603 */ + +typedef __SIZE_TYPE__ size_t; +void *memcpy (void *, const void *, size_t); +int snprintf (char *restrict, size_t, const char *restrict, ...); +extern char a[2]; +void bar (void); + +void +foo (void) +{ + memcpy (a, "12", sizeof (a)); + int b = snprintf (0, 0, "%s", a); + if (b <= 3) + bar (); +}