<html>
    <head>
      <base href="http://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - -fstack-protector + C11 atomics: binaries may crash"
   href="http://llvm.org/bugs/show_bug.cgi?id=16498">16498</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>-fstack-protector + C11 atomics: binaries may crash
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>FreeBSD
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Backend: X86
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>ed@80386.nl
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Consider the two following separate source files:

--- Begin source file 1 ---
#include <stddef.h>
#include <string.h>

typedef struct { char data[15]; } T;

void boom(_Atomic(T) *);

int
main(void)
{
    _Atomic(T) x;
    T y = {};

    __c11_atomic_init(&x, y);
    boom(&x);
}

#pragma redefine_extname __atomic_load_c __atomic_load

void
__atomic_load_c(int size, void *src, void *dest, int model)
{

    memcpy(dest, src, size);
}
--- End source file 1 ---

--- Begin source file 2 ---
typedef struct { char data[15]; } T;

void
boom(_Atomic(T) *v)
{

    __c11_atomic_load(v, __ATOMIC_SEQ_CST);
}
--- End source file 2 ---

In other words, source file 1 implements atomic_load() by doing a simple
memcpy() and calls a function in another compilation unit that ends up invoking
atomic_load() for a 15-byte structure type.

If we compile these two source files as follows, the resulting binary works
correctly:

$ clang -fstack-protector -o f f1.c f2.c
$ ./f
$

Now if we compile it as follows, it breaks:

$ clang -O2 -fstack-protector -o f f1.c f2.c
$ ./f
zsh: abort (core dumped)  ./f
$

When both pieces of code are placed in the same compilation unit, or if stack
protection is disabled, the code runs correctly at any optimisation level. The
boom() function is compiled to the following machine code:

--- Begin with -fstack-protector ---
0000000000000000 <boom>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   48 83 ec 20             sub    $0x20,%rsp
   8:   48 89 f8                mov    %rdi,%rax
   b:   48 8b 0d 00 00 00 00    mov    0x0(%rip),%rcx        # 12 <boom+0x12>
  12:   48 89 4d f8             mov    %rcx,-0x8(%rbp)
  16:   48 8d 55 e9             lea    -0x17(%rbp),%rdx
  1a:   bf 10 00 00 00          mov    $0x10,%edi
  1f:   48 89 c6                mov    %rax,%rsi
  22:   b9 05 00 00 00          mov    $0x5,%ecx
  27:   e8 00 00 00 00          callq  2c <boom+0x2c>
  2c:   48 8b 05 00 00 00 00    mov    0x0(%rip),%rax        # 33 <boom+0x33>
  33:   48 3b 45 f8             cmp    -0x8(%rbp),%rax
  37:   75 06                   jne    3f <boom+0x3f>
  39:   48 83 c4 20             add    $0x20,%rsp
  3d:   5d                      pop    %rbp
  3e:   c3                      retq   
  3f:   e8 00 00 00 00          callq  44 <boom+0x44>
--- End with -fstack-protector ---

--- Begin without -fstack-protector ---
0000000000000000 <boom>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   48 83 ec 10             sub    $0x10,%rsp
   8:   48 89 f8                mov    %rdi,%rax
   b:   48 8d 55 f1             lea    -0xf(%rbp),%rdx
   f:   bf 10 00 00 00          mov    $0x10,%edi
  14:   48 89 c6                mov    %rax,%rsi
  17:   b9 05 00 00 00          mov    $0x5,%ecx
  1c:   e8 00 00 00 00          callq  21 <boom+0x21>
  21:   48 83 c4 10             add    $0x10,%rsp
  25:   5d                      pop    %rbp
  26:   c3                      retq   
--- End without -fstack-protector ---</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>