This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] Fix crash in __longjmp on hppa architecture (BZ #21049)
- From: Helge Deller <deller at gmx dot de>
- To: libc-alpha at sourceware dot org
- Cc: Carlos O'Donell <carlos at redhat dot com>, Mike Frysinger <vapier at gentoo dot org>, Aurelien Jarno <aurelien at aurel32 dot net>, John David Anglin <danglin at gcc dot gnu dot org>
- Date: Sun, 15 Jan 2017 13:36:29 +0100
- Subject: [PATCH] Fix crash in __longjmp on hppa architecture (BZ #21049)
- Authentication-results: sourceware.org; auth=none
This fixes a crash in __longjmp on the hppa architecture which happens if the
new sigaltstack is above the current stack. In that case CHECK_SP() does an
INTERNAL_SYSCALL which clobbers %r26. Fix this issue by calling CHECK_SP before
assigning the local register variables r26 and r25.
The bug exists in all glibc versions and is triggered by running the GNU forth
compiler.
I don't have write access, so somebody should commit this for me. Thanks.
ChangeLog:
2017-01-15 Helge Deller <deller@gmx.de>
[BZ #21049]
* sysdeps/hppa/__longjmp.c (__longjmp): Move call to CHECK_SP up
to avoid clobbering r26.
diff -up ./sysdeps/hppa/__longjmp.c.org ./sysdeps/hppa/__longjmp.c
--- ./sysdeps/hppa/__longjmp.c.org 2017-01-13 10:45:24.180424626 +0100
+++ ./sysdeps/hppa/__longjmp.c 2017-01-13 10:47:41.720409134 +0100
@@ -24,15 +24,16 @@
void
__longjmp (__jmp_buf env, int val)
{
+#ifdef CHECK_SP
+ CHECK_SP (env[0].__jmp_buf.__sp);
+#endif
+
+ {
/* We must use one of the non-callee saves registers
for 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
-
asm volatile(
/* Set return value. */
"copy %0, %%r28\n\t"
@@ -79,6 +80,8 @@ __longjmp (__jmp_buf env, int val)
: /* No outputs. */
: "r" (r25), "r" (r26)
: /* No point in clobbers. */ );
+ }
+
/* Avoid `volatile function does return' warnings. */
for (;;);
}