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-ASN: AS22989 209.51.188.0/24 X-Spam-Status: No, score=-3.8 required=3.0 tests=AWL,BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, NICE_REPLY_A,RCVD_IN_DNSWL_HI,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL, SPF_HELO_PASS,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 E73AB1F5AE for ; Sat, 22 May 2021 23:00:11 +0000 (UTC) Received: from localhost ([::1]:37248 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lkabK-00061C-J8 for normalperson@yhbt.net; Sat, 22 May 2021 19:00:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58450) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lkabD-000610-Jq for bug-gnulib@gnu.org; Sat, 22 May 2021 19:00:03 -0400 Received: from mo4-p00-ob.smtp.rzone.de ([85.215.255.20]:28716) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lkab9-00044o-M1 for bug-gnulib@gnu.org; Sat, 22 May 2021 19:00:03 -0400 ARC-Seal: i=1; a=rsa-sha256; t=1621724395; cv=none; d=strato.com; s=strato-dkim-0002; b=c7rps0AEFHUjVL1ZzNB+LUyg4H5OPW7X1GIuzeHc+7sXFPeXBI7veW13y0lPYQbqc3 CkI6Y6XL9AeuDbise7xu6jM071NICUypg3IRBJJblZUgnULAIYr+8vdJFNwJcxatXPje mP3CLQM4ZpGb3IP9OOuKxv0+m0eo8akk4k0U8XBUk/wgCiiwos6YgKYem+Qfi87gDDf5 bmNDwUQRRxG6y3JGivQdO63NcrXtfJfipnNa9dnTdOm/JWruqLChEiNiUsdn2N1MSFso F1ApWhmXUBUoJM8SRqrzU3jMW4yZ7f4MD1NcGa1iOm1ltH2GnoGWa6CBs53ky9bzfQ9j 5QbQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; t=1621724395; s=strato-dkim-0002; d=strato.com; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=xdw7xQHk3RmLKUv68lewR6Xf10uicR0+9Q9/4xtSUEg=; b=XyeNWQKM/hLfLBPKtKhDmP+QvjzijGsi9jlJBO/FB2mgo67B6YoZ54LOU9Kvuqg8FV XcxiXTIqMZYLVliPMjVl0fVropdpt556uPbo32uDN3FSx1+9mQ/sCtaWvDgjPiH7Vm2y WxehMxsKBhqw+0blcvdYG5SHLz0pGIQwERYVq24tlQLrn7Ks+Juv7eXDWzoxYnlGpOSg Vc11iJGqsjIlzyhYMNYwWxfit8KBv54Iuoax5Rgw+c5zT5PbJ/iHklyrIrIV5Lved461 Nd/8ioSLdsaILgg1YHhvAKqzYYlIU39zh8J3ItO5DuZdhzfRDjjUDityfYvm03ttj7W7 Kstw== ARC-Authentication-Results: i=1; strato.com; dkim=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1621724395; s=strato-dkim-0002; d=clisp.org; h=References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=xdw7xQHk3RmLKUv68lewR6Xf10uicR0+9Q9/4xtSUEg=; b=E7nnfPKqtv40rAG9gg6MGsZrqPMYe+5wLL1ZhtwQUIDsrU+mtZB4skzJDTKoYwk73X o6o9hRidgQN/xkS6VI2ZS+mKHM0rrIJyiu08xVuqtvqvJ4jTwIBvNE+VeJZiiCLgkBK4 qlV5sKc9+cv6WSKeCPKI9+T4iE7EER6/NOdOqkFscdnpeMdrTBPRTR0hsCKtNJ5HgYVO aT/PxZIKJZMB1d5pgofaldkcBgaoiwIewoGQmorVsgylT8IFpKXAoMuf+ZJP1O1SJ8/3 /oFraRFrwI2B08qx3Cg1YkjYu+1LKAwlwSx3e6H8Iy54/CVWI3r4U1YxMQBWozMDZ6l3 e9Qg== Authentication-Results: strato.com; dkim=none X-RZG-AUTH: ":Ln4Re0+Ic/6oZXR1YgKryK8brlshOcZlIWs+iCP5vnk6shH+AHjwLuWOHqf3z5NW" X-RZG-CLASS-ID: mo00 Received: from bruno.haible.de by smtp.strato.de (RZmta 47.26.1 DYNA|AUTH) with ESMTPSA id Z0bd4cx4MMxt4dZ (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); Sun, 23 May 2021 00:59:55 +0200 (CEST) From: Bruno Haible To: Paul Eggert Subject: Re: sigsegv, c-stack: Avoid compilation error with glibc >= 2.34 Date: Sun, 23 May 2021 00:59:54 +0200 Message-ID: <33099571.YkAmQK1H3J@omega> User-Agent: KMail/5.1.3 (Linux/4.4.0-210-generic; KDE/5.18.0; x86_64; ; ) In-Reply-To: <8bdca38a-e947-7a28-01bf-1a50375aa32c@cs.ucla.edu> References: <1983155.9prZ3hhFlD@omega> <2419986.QI3XWb3JqY@omega> <8bdca38a-e947-7a28-01bf-1a50375aa32c@cs.ucla.edu> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="nextPart4458441.jbXDuRWpVy" Content-Transfer-Encoding: 7Bit Received-SPF: none client-ip=85.215.255.20; envelope-from=bruno@clisp.org; helo=mo4-p00-ob.smtp.rzone.de 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, NICE_REPLY_A=-0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no 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: bug-gnulib@gnu.org, Eric Blake Errors-To: bug-gnulib-bounces+normalperson=yhbt.net@gnu.org Sender: "bug-gnulib" This is a multi-part message in MIME format. --nextPart4458441.jbXDuRWpVy Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="UTF-8" Hi Paul, What you are doing now is to deconstruct - GCC extensions, and - POSIX. 1) Regarding GCC extensions: > > malloc'ed memory is not executable. But GCC's trampolines (used by nest= ed > > functions) require an executable stack. When an object file has such ne= sted > > functions, the toolchain arranges for the executable to ask the OS to > > allocate an executable stack. But that only has an effect on the primary > > stack of each thread. It does not have an effect on an alternate stack > > (AFAIK). >=20 > That should be OK so long as stack-overflow handlers don't used nested=20 > functions. Wait a moment. GCC's nested functions are a documented GCC feature [1] for ca. 30 years. When "security" became an important topic and people demanded non-executable stacks for web browsers, GCC and the binutils were extended in such a way that - on one hand, programs that use GCC nested functions (on most architectu= res) got a bit set in the executable, which has the consequence of an executable stack, - on the other hand, programs that don't need this =E2=80=94 such as web = browsers =E2=80=94 can have a non-executable stack. Now, you are arguing "let's ignore whether programs use nested functions". As if that wasn't a documented way, in the GNU system, of writing programs.= ?? > > I wouldn't mind, if it's done properly: > > - The problem with non-executable malloc'ed memory would need to be > > solved. >=20 > Or, we could just document that stack-overflow handers can't use=20 > trampolines. That is a reasonable restriction for most apps, I would thin= k. It adds complexity to the calling program. The developer has to check wheth= er their code uses nested functions. 2) Regarding POSIX: > The only place I found that assumed that SIGSTKSZ is a constant, was in=20 > Gnulib test cases. I removed that assumption by installing the first=20 > attached patch. By doing so, you moved the Gnulib code away from POSIX. In so many occasion= s, you voted for making Gnulib closer to POSIX, and that is a significant reason why Gnulib is successful. Here, - The current POSIX specifies a constant SIGSTKSZ, - Eric Blake is proposing that POSIX drops the constant-ness, and that SIGSTKSZ becomes a macro that merely expands to an expression. [2] So, being close to POSIX would mean to use SIGSTKSZ for the allocation of an alternate stack, most likely through malloc. Whereas your patch removes all traces of SIGSTKSZ and hardcodes a constant (1 << 24) in various places instead. The point of your patch appears to be to proactively react to other systems (FreeBSD, Solaris, etc.) to follow glibc's move and make SIGSTKSZ non- constant. But then, still, it would have been more maintainable to write /* SIGSTKSZ can no longer be guaranteed to be a constant. Until POSIX clarifies it, use a large constant anyway. */ #undef SIGSTKSZ #define SIGSTKSZ (1 << 24) 3) The approach you used now, to use a 16 MB space for sigaltstack(), is not portable to multithreaded situations. For example, I have a test program (attached) that I consider to add as a unit test to gnulib. It uses stack space from the thread itself as alternate signal stack. That is a perfectly natural thing to do, because - the permissions of the alternate stack are automatically right, - this alternate stack gets deallocated automatically when the thread dies (no memory leak). But allocating 16 MB on a thread's stack is not portable. On Solaris/SPARC, the main thread's size is only 8 MB. Really, my goals here are that the unit tests in Gnulib - use POSIX the best they can, - give a coding pattern that people can use in their applications, be they single-threaded or multi-threaded, and interoperable with whatever GCC extensions the programmer wants. Bruno [1] https://gcc.gnu.org/onlinedocs/gcc-11.1.0/gcc/Nested-Functions.html [2] https://sourceware.org/pipermail/libc-alpha/2021-March/123553.html --nextPart4458441.jbXDuRWpVy Content-Disposition: attachment; filename="sigaltstack-per-thread.c" Content-Transfer-Encoding: 7Bit Content-Type: text/x-csrc; charset="UTF-8"; name="sigaltstack-per-thread.c" /* Test whether sigaltstack works per thread. */ #include #include #include #include #include #include #include #include #include /* Correct the value of SIGSTKSZ on some systems. AIX 64-bit: original value 4096 is too small. HP-UX: original value 8192 is too small. */ #if defined _AIX && defined _ARCH_PPC64 # undef SIGSTKSZ # define SIGSTKSZ 8192 #endif #if defined __hpux || (defined __sun && (defined __x86_64__ || defined __amd64__)) # undef SIGSTKSZ # define SIGSTKSZ 16384 #endif static void* thread2_func (void *ignored) { stack_t current; stack_t alt_stack; char mystack_storage[SIGSTKSZ + 31]; char *mystack = (char *)((uintptr_t) mystack_storage | 31); fprintf (stderr, "thread2 running\n"); if (sigaltstack (NULL, ¤t) < 0) { perror ("thread2 sigaltstack"); exit (1); } fprintf (stderr, "thread2 sigaltstack: enabled=%s onstack=%s sp=0x%lx size=0x%lx\n", (current.ss_flags & SS_DISABLE) ? "no" : "yes", (current.ss_flags & SS_ONSTACK) ? "yes" : "no", (unsigned long) current.ss_sp, (unsigned long) current.ss_size); if ((current.ss_flags & SS_DISABLE) == 0 && current.ss_size > 0) { fprintf (stderr, "thread2 sigaltstack already enabled! Per-thread not supported.\n"); exit (1); } alt_stack.ss_flags = 0; alt_stack.ss_sp = mystack; alt_stack.ss_size = SIGSTKSZ; if (sigaltstack (&alt_stack, NULL) < 0) { perror ("thread2 sigaltstack set"); exit (1); } fprintf (stderr, "thread2 alternate stack installed\n"); if (sigaltstack (NULL, ¤t) < 0) { perror ("thread2 sigaltstack"); exit (1); } fprintf (stderr, "thread2 sigaltstack now: enabled=%s onstack=%s sp=0x%lx size=0x%lx\n", (current.ss_flags & SS_DISABLE) ? "no" : "yes", (current.ss_flags & SS_ONSTACK) ? "yes" : "no", (unsigned long) current.ss_sp, (unsigned long) current.ss_size); return 0; } int main () { stack_t alt_stack; stack_t current; stack_t last; pthread_t thread2; struct timeval sleeptime; char mystack_storage[SIGSTKSZ + 31]; char *mystack = (char *)((uintptr_t) mystack_storage | 31); alt_stack.ss_flags = 0; alt_stack.ss_sp = mystack; alt_stack.ss_size = SIGSTKSZ; if (sigaltstack (&alt_stack, NULL) < 0) { perror ("main-thread sigaltstack set"); exit (1); } fprintf (stderr, "alternate stack installed\n"); if (sigaltstack (NULL, ¤t) < 0) { perror ("main-thread sigaltstack"); exit (1); } fprintf (stderr, "main-thread sigaltstack: enabled=%s onstack=%s sp=0x%lx size=0x%lx\n", (current.ss_flags & SS_DISABLE) ? "no" : "yes", (current.ss_flags & SS_ONSTACK) ? "yes" : "no", (unsigned long) current.ss_sp, (unsigned long) current.ss_size); last = current; if (pthread_create (&thread2, NULL, thread2_func, NULL)) { fprintf (stderr, "creating of thread2 failed\n"); exit (1); } /* Sleep 2 sec. */ sleeptime.tv_sec = 2; sleeptime.tv_usec = 0; if (select (0, NULL, NULL, NULL, &sleeptime) < 0) { perror ("main-thread sleep"); exit (1); } if (sigaltstack (NULL, ¤t) < 0) { perror ("main-thread sigaltstack"); exit (1); } fprintf (stderr, "main-thread sigaltstack: enabled=%s onstack=%s sp=0x%lx size=0x%lx\n", (current.ss_flags & SS_DISABLE) ? "no" : "yes", (current.ss_flags & SS_ONSTACK) ? "yes" : "no", (unsigned long) current.ss_sp, (unsigned long) current.ss_size); if (!(current.ss_flags == last.ss_flags && current.ss_sp == last.ss_sp && current.ss_size == last.ss_size)) { fprintf (stderr, "main-thread sigaltstack has changed!\n"); exit (1); } fprintf (stderr, "SUPPORTED\n"); exit (0); } /* Results: Linux SUPPORTED Hurd SUPPORTED although "enabled=yes onstack=no sp=0x0 size=0x0" Mac OS X 10.5 SUPPORTED FreeBSD 11 SUPPORTED NetBSD 7 thread2 sigaltstack already enabled! Per-thread not supported. NetBSD 8 SUPPORTED OpenBSD 6.0 SUPPORTED AIX 7.1 SUPPORTED HP-UX 11.31 SUPPORTED IRIX 6.5 thread2 sigaltstack already enabled! Per-thread not supported. Solaris 9, 10 SUPPORTED Haiku SUPPORTED Cygwin SUPPORTED */ --nextPart4458441.jbXDuRWpVy--