------- Comment #6 from vapier at gentoo dot org  2010-08-15 05:49 -------
Created an attachment (id=21479)
 --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=21479&action=view)
signaler.c

register a signal handler that goes though __libc_sigaction(), then trigger
that signal and attempt to return.  since glibc set the sa_restorer field by
reading the data at the address of __rt_sigaction instead of using the address
itself, the kernel sets the return address to an invalid address.

here is a semi-overly-complicated example:
  gcc -o signaler signaler.c -static
  ./signaler

set a break point at *sigvtalarm and look at the return address:
  (gdb) x/1g $rsp
  0x7fffffffd1f8: 0x0f0000000fc0c748

that's because gcc generated a mov insn which loaded the 64bits at the address
of __restore_rt instead of storing the address of __restore_rt itself:

0000000000000010 <__restore_rt>:
  10:   48 c7 c0 0f 00 00 00    mov    $0xf,%rax
  17:   0f 05                   syscall 


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45286

Reply via email to