This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug libc/21049] New: segfault in longjmp_chk() due to clobbered processor register


https://sourceware.org/bugzilla/show_bug.cgi?id=21049

            Bug ID: 21049
           Summary: segfault in longjmp_chk() due to clobbered processor
                    register
           Product: glibc
           Version: 2.26
               URL: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=85083
                    5
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: libc
          Assignee: unassigned at sourceware dot org
          Reporter: deller at gmx dot de
                CC: danglin at gcc dot gnu.org, drepper.fsp at gmail dot com
  Target Milestone: ---
              Host: hppa-linux
            Target: hppa-linux
             Build: hppa-linux

Created attachment 9752
  --> https://sourceware.org/bugzilla/attachment.cgi?id=9752&action=edit
Patch to ./sysdeps/hppa/__longjmp.c

While compiling the gforth debian package on hppa I noticed that it crashed
while running the testsuite.

Debugging showed that the crash happened in ____longjmp_chk().

Dump of assembler code for function ____longjmp_chk:
   0xf98b59e0 <+0>:     stw rp,-14(sp)
   0xf98b59e4 <+4>:     ldo 80(sp),sp
   0xf98b59e8 <+8>:     stw r3,-68(sp)
   0xf98b59ec <+12>:    cmpiclr,<> 0,r25,r0
   0xf98b59f0 <+16>:    ldi 1,r25
   0xf98b59f4 <+20>:    stw r4,-6c(sp)
   0xf98b59f8 <+24>:    ldo 4c(r26),r3
   0xf98b59fc <+28>:    stw r19,-20(sp)
   0xf98b5a00 <+32>:    ldw 0(r3),ret0
   0xf98b5a04 <+36>:    cmpb,>>=,n sp,ret0,0xf98b5a60 <____longjmp_chk+128>
   0xf98b5a08 <+40>:    ldo -78(sp),r25
   0xf98b5a0c <+44>:    ldi 0,r26
   0xf98b5a10 <+48>:    copy r19,r4
   0xf98b5a14 <+52>:    be,l 100(sr2,r0),sr0,r31
   0xf98b5a18 <+56>:    ldi a6,r20
   0xf98b5a1c <+60>:    copy r4,r19
   0xf98b5a20 <+64>:    ldi ffd,r20
   0xf98b5a24 <+68>:    ldo ffe(ret0),ret0
   0xf98b5a28 <+72>:    cmpb,>>= r20,ret0,0xf98b5a60 <____longjmp_chk+128>
   0xf98b5a2c <+76>:    ldw -74(sp),ret0
   0xf98b5a30 <+80>:    bb,*>= ret0,1f,0xf98b5a50 <____longjmp_chk+112>
   0xf98b5a34 <+84>:    ldw -70(sp),r20
   0xf98b5a38 <+88>:    ldw 0(r25),ret0
   0xf98b5a3c <+92>:    add,l ret0,r20,ret0
   0xf98b5a40 <+96>:    ldw 0(r3),r21
   0xf98b5a44 <+100>:   sub ret0,r21,ret0
   0xf98b5a48 <+104>:   cmpclr,<< ret0,r20,r0
   0xf98b5a4c <+108>:   b,l,n 0xf98b5a60 <____longjmp_chk+128>,r0
   0xf98b5a50 <+112>:   addil L%800,r19,r1
   0xf98b5a54 <+116>:   ldw 254(r1),r26
   0xf98b5a58 <+120>:   b,l 0xf98b5ba0 <__GI___fortify_fail>,rp
   0xf98b5a5c <+124>:   nop
   0xf98b5a60 <+128>:   copy r25,ret0
=> 0xf98b5a64 <+132>:   ldw 0(r26),r3
   0xf98b5a68 <+136>:   ldw 8(r26),r4
   0xf98b5a6c <+140>:   ldw c(r26),r5
   0xf98b5a70 <+144>:   ldw 10(r26),r6
   0xf98b5a74 <+148>:   ldw 14(r26),r7
   0xf98b5a78 <+152>:   ldw 18(r26),r8
   0xf98b5a7c <+156>:   ldw 1c(r26),r9
   0xf98b5a80 <+160>:   ldw 20(r26),r10
   0xf98b5a84 <+164>:   ldw 24(r26),r11
   0xf98b5a88 <+168>:   ldw 28(r26),r12
   0xf98b5a8c <+172>:   ldw 2c(r26),r13
   0xf98b5a90 <+176>:   ldw 30(r26),r14

The code of __longjmp is this:
void __longjmp (__jmp_buf env, int val)
{
  /* We must use one of the non-callee saves registersfor env.  */
  register unsigned long r26 asm ("r26") = (unsigned long)&env[0];
  register unsigned long r25 asm ("r25") = (unsigned long)(val == 0 ? 1 : val);
#ifdef CHECK_SP
  CHECK_SP (env[0].__jmp_buf.__sp);
#endif
....
  inline-asm(...., r25 r26)
}

__longjmp uses a register variable (%r26) to hand over &env[0] to the inline
assembly later down.
On the other hand, if the new stack pointer is higher than the current stack
pointer, CHECK_SP() calls INTERNAL_SYSCALL() which clobbers %r26.

Attached patch avoids this problem by moving the assignment of r25 and r26 down
below the CHECK_SP() macros and putting it in a seperate {...} block. That way
the compiler will correctly take care of saving the needed variables (r25/r26)
across the INTERNAL_SYSCALL() call.

Build- &  Run-tested on hppa-linux with the gforth debian package.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]