From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id A1634385703F; Wed, 28 Oct 2020 17:14:02 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A1634385703F From: "0x66726565 at gmail dot com" To: glibc-bugs@sourceware.org Subject: [Bug libc/26802] New: raise() marked __leaf__ is not C-compliant Date: Wed, 28 Oct 2020 17:14:02 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: glibc X-Bugzilla-Component: libc X-Bugzilla-Version: 2.30 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: 0x66726565 at gmail dot com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: unassigned at sourceware dot org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter cc target_milestone Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://sourceware.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: glibc-bugs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Glibc-bugs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Oct 2020 17:14:02 -0000 https://sourceware.org/bugzilla/show_bug.cgi?id=3D26802 Bug ID: 26802 Summary: raise() marked __leaf__ is not C-compliant Product: glibc Version: 2.30 Status: UNCONFIRMED Severity: normal Priority: P2 Component: libc Assignee: unassigned at sourceware dot org Reporter: 0x66726565 at gmail dot com CC: drepper.fsp at gmail dot com Target Milestone: --- To quote the C standard on the signal() function (C90, C99, C11, and C18 basically say the same) described in Section 7.14.1.1 Paragraph 5 of [1]: If the signal occurs other than as the result of calling the abort or raise function, the behavior is undefined if the signal handler refers to any obj= ect with static or thread storage duration that is not a lock-free atomic object other than by assigning a value to an object declared as volatile sig_atomi= c_t End quote. Based on that, a signal handler that is run as the result of calling raise() has no UB (undefined behavior) when the handler accesses an object with sta= tic storage duration that is not qualified with volatile. Indeed, the C standa= rd does not say that it is a UB to access an object with static storage durati= on that is not qualified with volatile and/or is not of type sig_atomic_t from= a signal handler that is run as the result of calling raise(). However, glibc 2.30 for my x86_64 machine managed by the Linux kernel versi= on 4.15.0 marks raise() using the GCC function attribute __leaf__. This resul= ts in a UB because the following test program terminates when compiled by GCC = with -O0 and -Os but never terminates when compiled by GCC with -O2: -- 8< -------------------- #include #include static int terminated; static void handler(int signo) { terminated =3D 1; } int main(int argc, char **argv) { unsigned total =3D 0, delta =3D drand48() >=3D argc ? 1 : 0; /* At runtime, delta will be 0 as argc is 1 */ signal(SIGUSR1, handler); /* Infinite loop unless `terminated' is 1 (delta is 0) */ for (int i =3D 0; !terminated && i < 100; i +=3D delta) { total +=3D i; raise(SIGUSR1); /* synchronously runs `handler' */ } return total; } -- 8< -------------------- As a reminder, the C standard says the following about the raise() function (C99, C11, and C18 basically say the same), which is stated on page 195 of = [1]: If a signal handler is called, the raise function shall not return until af= ter the signal handler does. End quote. Now the GCC documentation on __leaf__ [2] says the following (words in squa= re brackets are additions/replacements to fit this context): Note that leaf functions might indirectly run a signal handler defined in t= he current compilation unit that uses static variables. [...] There is no standard-compliant way to write such [an] implementation function[, for example, glibc-2.30 raise()], and the best that you can do is to remove the leaf attribute or mark all such static variables volatile. End quote. Since glibc-2.30 raise() definitely runs a signal handler as required by th= e C standard, and the signal handler can be defined in the current compilation = unit to use static variables, then unless the C standard says that it is a UB to access a non-volatile object with static storage duration from within a sig= nal handler that is run using raise() on a normal execution path, the marking of raise() with __leaf__ makes raise() non-compliant with the C standard, and hence, this bug report. Therefore, this bug report requests that, to be compliant with the C standa= rd, glibc does not mark raise() with __leaf__. Furthermore, if glibc aims to be POSIX-compliant as well, in accordance with IEEE Std 1003.1-2017, Volume 2 "System Interfaces", Section 2.4.3 "Signal Actions", the following functions should not be marked with __leaf__ as well: abort(), raise(), kill(), pthread_kill(), and sigqueue(). Thank you for your attention. References: [1] https://web.archive.org/web/20181230041359/http://www.open-std.org/jtc1/sc2= 2/wg14/www/abq/c17_updated_proposed_fdis.pdf [2] https://gcc.gnu.org/onlinedocs/gcc-9.3.0/gcc/Common-Function-Attributes.htm= l#Common-Function-Attributes --=20 You are receiving this mail because: You are on the CC list for the bug.=