[llvm-bugs] [Bug 27829] New: stack smash protection epilogue code incorrectly associated with inlined body

via llvm-bugs llvm-bugs at lists.llvm.org
Fri May 20 16:47:46 PDT 2016


https://llvm.org/bugs/show_bug.cgi?id=27829

            Bug ID: 27829
           Summary: stack smash protection epilogue code incorrectly
                    associated with inlined body
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Severity: normal
          Priority: P
         Component: DebugInfo
          Assignee: unassignedbugs at nondot.org
          Reporter: warren_ristow at playstation.sony.com
                CC: llvm-bugs at lists.llvm.org
    Classification: Unclassified

Compiling the test-case at the end of this description as:

  clang++ -c -g -O2 -fstack-protector-strong test.cpp

shows a problem where the Stack Smash Protection code in the epilogue of
'main()' is incorrectly associated with the inlined body of 'bar()'.  In the
example, 'main()' calls 'foo()', which calls 'bar()' 3 times (all of these
calls are inlined into 'main()').

Running 'llvm-dwarfdump' on "test.o" created as above, shows 3
DW_TAG_inlined_subroutine entries for 'bar()':

0x000000dc:       DW_TAG_inlined_subroutine [11]  
                      ...
                    DW_AT_low_pc [DW_FORM_addr] (0x000000000000004c)
                    DW_AT_high_pc [DW_FORM_data4]       (0x0000000c)
                      ...
0x000000ef:       DW_TAG_inlined_subroutine [11]  
                      ...
                    DW_AT_low_pc [DW_FORM_addr] (0x0000000000000058)
                    DW_AT_high_pc [DW_FORM_data4]       (0x0000000c)
                      ...
0x00000102:       DW_TAG_inlined_subroutine [11]  
                      ...
                    DW_AT_low_pc [DW_FORM_addr] (0x0000000000000064)
                    DW_AT_high_pc [DW_FORM_data4]       (0x0000001c)
                      ...

The first two have 12 (0xc) bytes in them, whereas the last one shows 28
(0x1c) bytes.  Those additional 16 bytes of code are actually part of the
stack smash protection check in the epilogue of 'main()'.  The disassembly
of 'main()', annotated to show the relevant area, is:

    0000000000000030 <main>:
      30:   48 83 ec 18             sub    $0x18,%rsp
      34:   64 48 8b 04 25 28 00    mov    %fs:0x28,%rax
      3b:   00 00 
      3d:   48 89 44 24 10          mov    %rax,0x10(%rsp)
      42:   48 8d 7c 24 08          lea    0x8(%rsp),%rdi
      47:   e8 d4 ff ff ff          callq  20 <_Z4initPi>

 Start of 1st inlined call to 'bar()'
      4c:   83 05 00 00 00 00 2a    addl   $0x2a,0x0(%rip) # 53 <main+0x23>
      53:   e8 a8 ff ff ff          callq  0 <_Z7printItv>
 End of 1st inlined call to 'bar()'

 Start of 2nd inlined call to 'bar()'
      58:   83 05 00 00 00 00 2a    addl   $0x2a,0x0(%rip) # 5f <main+0x2f>
      5f:   e8 9c ff ff ff          callq  0 <_Z7printItv>
 End of 2nd inlined call to 'bar()'

 Start of 3rd inlined call to 'bar()'
      64:   83 05 00 00 00 00 2a    addl   $0x2a,0x0(%rip) # 6b <main+0x3b>
      6b:   e8 90 ff ff ff          callq  0 <_Z7printItv>
 >>>  70:   64 48 8b 04 25 28 00    mov    %fs:0x28,%rax
 >>>  77:   00 00 
 >>>  79:   48 3b 44 24 10          cmp    0x10(%rsp),%rax
 >>>  7e:   75 07                   jne    87 <main+0x57>
 End of 3rd inlined call to 'bar()'

      80:   31 c0                   xor    %eax,%eax
      82:   48 83 c4 18             add    $0x18,%rsp
      86:   c3                      retq   
      87:   e8 00 00 00 00          callq  8c <main+0x5c>

The area marked with '>>>' is part of the epilogue of 'main()', but it's
identified as part of the inlined body of the 3rd call to 'bar()'.

This was found in a reasonably modern x86_64 Linux compiler (r269832), but
the behavior isn't new (also tested with an llvm 3.6 based compiler, which
shows the same behavior).

"test.cpp" is below.
___________________________________________________________________

    // clang++ -c -g -O2 -fstack-protector-strong test.cpp
    extern "C" int printf(const char *, ...);
    extern void __attribute__((noinline)) init(int *p);
    extern void __attribute__((noinline)) printIt();
    static int glb = 17;

    void __attribute__((noinline)) printIt() {      // line 7
      printf("glb = %d\n", glb);                    // line 8
    }

    void __attribute__((noinline)) init(int *p) {   // line 11
      *p = 1;                                       // line 12
    }

    static void __attribute__((always_inline)) bar() {
      glb += 42;    // line 16
      printIt();    // line 17
    }

    static void __attribute__((always_inline)) foo() {
      bar();        // line 21
      bar();        // line 22
      bar();        // line 23
    }

    int main() {
      int array[2]; // Just to force SSP check in 'main()'.
      init(array);  // line 28

      foo();        // line 30
      return 0;
    }

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20160520/1dbb0fe4/attachment-0001.html>


More information about the llvm-bugs mailing list