Bug 173460 - all versions of gcc may miscompile kernel's sigaddset if signal is constant
all versions of gcc may miscompile kernel's sigaddset if signal is constant
Status: CLOSED NOTABUG
Product: Red Hat Enterprise Linux 3
Classification: Red Hat
Component: gcc (Show other bugs)
3.0
i386 Linux
medium Severity high
: ---
: ---
Assigned To: Jakub Jelinek
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2005-11-17 03:07 EST by Constantine Gavrilov
Modified: 2007-11-30 17:07 EST (History)
0 users

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2005-11-17 03:41:12 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
A sample of c code that gets miscompiled if -O2 flags is used. (4.15 KB, text/plain)
2005-11-17 03:07 EST, Constantine Gavrilov
no flags Details

  None (edit)
Description Constantine Gavrilov 2005-11-17 03:07:20 EST
gcc may miscompile code on i386 using kernel sigsetadd if signal argument is
constant. The probem is also reproducible in user space.

All versions of gcc and all versiong of kernels are affected. Attached please
find a program that can be compiled into module or executable. If compiled with
-O2 flags, the resulting code is wrong.  Disassembly (or  running in the
debugger) shows miscompilation. Disabling optimization or just using -O fixes
the problem.

In short the following code is problematic:

sigset_t a;
sigset_t b;
sigset_t c;

...........
sigaddset(&a, const1);
sigaddset(&a,  const2);
................................
b =a;    /* this line causes incorrect code; any 64-bit assignment seems to
cause a problem! */
sigaddset(&c, const2);
sigaddset(&c,  const3);
/* more sigaddset to c */

At some iteration of sigaddset to c, c may get the value of a!!!
Comment 1 Constantine Gavrilov 2005-11-17 03:07:20 EST
Created attachment 121166 [details]
A sample of c code that gets miscompiled if -O2 flags is used.
Comment 2 Jakub Jelinek 2005-11-17 03:41:12 EST
That's just buggy testcase.
static __inline__ void __gen_sigaddset(sigset_t *set, int _sig)
{
        __asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig-1) : "cc");
}
You need either
__asm__("btsl %1,%0" : "+m"(*set) : "Ir"(_sig-1) : "cc");
or
__asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig-1), "m"(*set) : "cc");
because the btsl instruction doesn't just set the memory to some value, but needs
to read its previous content as well.  If you don't tell that fact to GCC,
GCC is of course free to optimize as if the asm was just setting the value
and not depended on the previous value.

Note You need to log in before you can comment on or make changes to this bug.