[Bug middle-end/61118] [6/7/8 Regression] Indirect call generated for pthread_cleanup_push with constant cleanup function

fw at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Tue Nov 21 19:22:00 GMT 2017


Florian Weimer <fw at gcc dot gnu.org> changed:

           What    |Removed                     |Added
            Summary|[6/7/8 Regression] Spurious |[6/7/8 Regression] Indirect
                   |-Wclobbered warning         |call generated for
                   |generated by gcc 4.9.0 for  |pthread_cleanup_push with
                   |pthread_cleanup_push        |constant cleanup function

--- Comment #13 from Florian Weimer <fw at gcc dot gnu.org> ---
This is not simply a spurious warning (the variables in question are only
assigned once and their address is not taken, so C semantics do not allow that
they are clobbered by setjmp+longjmp).

I compiled the reproducer with


to see the cleanup action on the non-cancellation path, too.  All compilation
with -fpic to avoid yet another GCC 7 weirdness (movl $cleanup_fn; %eax, call

GCC 4.8.5 20150623 (Red Hat 4.8.5-22) produces:

        call    pthread_cond_wait@PLT
        movq    %r14, %rdi
        call    __pthread_unregister_cancel@PLT
        movq    %rbx, %rdi
        call    cleanup_fn@PLT

GCC 7.2.1 20170829 (Red Hat 7.2.1-1) gives me:

        movq    cleanup_fn@GOTPCREL(%rip), %rax
        movq    %rax, 32(%rsp)
        call    pthread_cond_wait@PLT
        movq    %rbx, %rdi
        call    __pthread_unregister_cancel@PLT
        movq    32(%rsp), %rax
        movq    40(%rsp), %rdi
        call    *%rax

This is quite unsatisfying from a security hardening point of view because we
now have an unencrypted function pointer on the stack.  This situation is
somewhat analogous to Windows SEH, which turned out very problematic.  (The
jmp_buf on the stack isn't ideal, but at least the PC value in it is mangled.)

More information about the Gcc-bugs mailing list