From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-Status: No, score=-3.7 required=3.0 tests=AWL,BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE, SPF_PASS shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dcvr.yhbt.net (Postfix) with ESMTPS id D74FD1F55B for ; Sat, 23 May 2020 21:53:40 +0000 (UTC) Received: from localhost ([::1]:46754 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jcc5L-0003MS-OF for normalperson@yhbt.net; Sat, 23 May 2020 17:53:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38648) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jcc5I-0003M6-7r for bug-gnulib@gnu.org; Sat, 23 May 2020 17:53:36 -0400 Received: from mo6-p00-ob.smtp.rzone.de ([2a01:238:20a:202:5300::5]:20876) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jcc5F-0002cA-Tn for bug-gnulib@gnu.org; Sat, 23 May 2020 17:53:35 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1590270809; s=strato-dkim-0002; d=clisp.org; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: X-RZG-CLASS-ID:X-RZG-AUTH:From:Subject:Sender; bh=qB4oChrV7fS58A9g7vBAnN39O/+N5z41gZdQ28c+xT0=; b=GxHVnoFjYWrhFfNUllqUzcYmef+IAnSADF/I9xuEgSjwcHsPNELOVF1qeD2AIk/rLM JZE0I3dsIVVvBRTc4YmzQSlv2Q2MdnnntG1tH0bq1h2W8oaC+zRFEpQzxC2J/V6YjWFH n9lo3LLM+i6jZTOg7ETEYBmJIROyBa2NneiLRZpTJJVicWODi4zmjIDHB6nj20ZJrCb1 /G3/xSLQTHZREsa5/XF6a56hYYUk/PliZ5nvWlsvDyG0kUPCFLnrpuXnXO2VHBVJGrx4 XL4ksoP7ocFHWNUPRnvC177ZjzVHZuNVXRXHh4CLh12TJBClWXWLSOUyjT84esL/enkK CXdg== X-RZG-AUTH: ":Ln4Re0+Ic/6oZXR1YgKryK8brlshOcZlIWs+iCP5vnk6shH+AHjwLuWOH6fzxfs=" X-RZG-CLASS-ID: mo00 Received: from bruno.haible.de by smtp.strato.de (RZmta 46.7.0 DYNA|AUTH) with ESMTPSA id x0bd30w4NLrSQFV (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (curve X9_62_prime256v1 with 256 ECDH bits, eq. 3072 bits RSA)) (Client did not present a certificate); Sat, 23 May 2020 23:53:28 +0200 (CEST) From: Bruno Haible To: Paul Eggert Subject: Re: Fix calloc.m4 test Date: Sat, 23 May 2020 23:53:27 +0200 Message-ID: <7723323.VmqtHH8jJT@omega> User-Agent: KMail/5.1.3 (Linux/4.4.0-177-generic; KDE/5.18.0; x86_64; ; ) In-Reply-To: References: <1872257.AoR9L2n4HY@omega> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" Received-SPF: none client-ip=2a01:238:20a:202:5300::5; envelope-from=bruno@clisp.org; helo=mo6-p00-ob.smtp.rzone.de X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: bug-gnulib@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Gnulib discussion list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Tim =?ISO-8859-1?Q?R=FChsen?= , bug-gnulib@gnu.org Errors-To: bug-gnulib-bounces+normalperson=yhbt.net@gnu.org Sender: "bug-gnulib" Hi Paul, > Unfortunately Vincent Lefevre is correct that the C Standard allows calloc > (SIZE_MAX, 2) to succeed on a hypothetical machine that actually can allocate > that amount of memory. This could in theory occur on a machine that doesn't have > a flat address space. > > A program like the following should defeat Clang's optimization, though (at > least, if Clang is not buggy). And it would also detect the hypothetical machine > that Vincent alluded to, which would make it more-accurate than the 'volatile' > workaround. How about if we switch calloc.m4 to use this test instead? > > #include > int main () > { > struct { char c[8]; } *s; > size_t sn = (size_t) -1 / sizeof *s + 2; > int result = 0; > char *p = calloc (0, 0); > if (!p) > result |= 1; > free (p); > s = calloc (sn, sizeof *s); > if (s) > { > s[0].c[0] = 1; > if (s[sn - 1].c[0]) > result |= 2; > } > free (s); > return result; > } OK, I'm adding this to calloc.m4. Patch below. However, the 'volatile' is still needed. And even if it wasn't, it would be good to keep two arrows in our quiver. Now, this looks really like a bug that you could report: With clang 10.0.0 on x86_64 (Ubuntu 18.04), the following program ================================= foo.c ============================ #include int main () { int result; typedef struct { char c[8]; } S8; size_t n = (size_t) -1 / sizeof (S8) + 2; S8 *s = calloc (n, sizeof (S8)); if (s) { s[0].c[0] = 1; if (s[n - 1].c[0]) result = 0; else result = 2; } else result = 3; free (s); return result; } ==================================================================== returns with exit code 0, when optimization is enabled: $ clang -O2 foo.c $ ./a.out; echo $? 0 When no optimization is enabled, it returns with exit code 3, as expected. Does this look like a reportable bug? :-) 2020-05-23 Bruno Haible calloc-gnu: Make test work in non-flat address spaces. Uses code by Paul Eggert. * m4/calloc.m4 (_AC_FUNC_CALLOC_IF): Allow a calloc() implementation to return more than SIZE_MAX bytes, but only without wrap-around bugs. diff --git a/m4/calloc.m4 b/m4/calloc.m4 index a93439e..f179a8a 100644 --- a/m4/calloc.m4 +++ b/m4/calloc.m4 @@ -1,4 +1,4 @@ -# calloc.m4 serial 22 +# calloc.m4 serial 23 # Copyright (C) 2004-2020 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation @@ -38,16 +38,27 @@ AC_DEFUN([_AC_FUNC_CALLOC_IF], AC_RUN_IFELSE( [AC_LANG_PROGRAM( [AC_INCLUDES_DEFAULT], - [[int result = 0; - char * volatile p = calloc ((size_t) -1 / 8 + 1, 8); - if (!p) - result |= 2; - free (p); + [[int result; + typedef struct { char c[8]; } S8; + size_t n = (size_t) -1 / sizeof (S8) + 2; + S8 * volatile s = calloc (n, sizeof (S8)); + if (s) + { + s[0].c[0] = 1; + if (s[n - 1].c[0]) + result = 0; + else + result = 2; + } + else + result = 3; + free (s); return result; ]])], - dnl The exit code of this program is 0 if calloc() succeeded (which - dnl it shouldn't), 2 if calloc() failed, or 1 if some leak sanitizer - dnl terminated the program as a result of the calloc() call. + dnl The exit code of this program is 0 if calloc() succeeded with a + dnl wrap-around bug (which it shouldn't), 2 if calloc() succeeded in + dnl a non-flat address space, 3 if calloc() failed, or 1 if some leak + dnl sanitizer terminated the program as a result of the calloc() call. [ac_cv_func_calloc_0_nonnull=no], []) else