This is the mail archive of the
glibc-bugs@sourceware.org
mailing list for the glibc project.
[Bug libc/21049] New: segfault in longjmp_chk() due to clobbered processor register
- From: "deller at gmx dot de" <sourceware-bugzilla at sourceware dot org>
- To: glibc-bugs at sourceware dot org
- Date: Fri, 13 Jan 2017 17:39:31 +0000
- Subject: [Bug libc/21049] New: segfault in longjmp_chk() due to clobbered processor register
- Auto-submitted: auto-generated
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.