[klibc] Bug#943425: Debian #943425: klibc: [s390x] setjmp/longjmp do not save/restore all registers in use

Thorsten Glaser tg at mirbsd.de
Wed May 5 15:21:39 PDT 2021


tags 943425 + patch
tags 988027 + patch
thanks

Dixi quod…

>Patches for klibc upstream git attched; I’m currently trying to test
>them, will report.

This was really tricky given we can’t install patched B-Ds on
porterboxen, but I managed. I can confirm this fixes my issue.

bye,
//mirabilos
-- 
<diogenese> Beware of ritual lest you forget the meaning behind it.
<igli> yeah but it means if you really care about something, don't
    ritualise it, or you will lose it. don't fetishise it, don't
    obsess. or you'll forget why you love it in the first place.
-------------- next part --------------
diff -Nru klibc-2.0.8/debian/changelog klibc-2.0.8/debian/changelog
--- klibc-2.0.8/debian/changelog	2021-04-30 03:05:23.000000000 +0200
+++ klibc-2.0.8/debian/changelog	2021-05-05 21:38:31.000000000 +0200
@@ -1,3 +1,11 @@
+klibc (2.0.8-6.1) unstable; urgency=medium
+
+  * Non-maintainer upload.
+  * Fix sig{set,long}jmp always saves the signal mask (Closes: #988027)
+  * [s390x] Fix {set,long}jmp registers to save (Closes: #943425)
+
+ -- Thorsten Glaser <tg at mirbsd.de>  Wed, 05 May 2021 21:38:31 +0200
+
 klibc (2.0.8-6) unstable; urgency=medium
 
   * Upload to unstable
diff -Nru klibc-2.0.8/debian/patches/0001-klibc-sig-set-long-jmp-do-not-ignore-sigsetjmp-s-sec.patch klibc-2.0.8/debian/patches/0001-klibc-sig-set-long-jmp-do-not-ignore-sigsetjmp-s-sec.patch
--- klibc-2.0.8/debian/patches/0001-klibc-sig-set-long-jmp-do-not-ignore-sigsetjmp-s-sec.patch	1970-01-01 01:00:00.000000000 +0100
+++ klibc-2.0.8/debian/patches/0001-klibc-sig-set-long-jmp-do-not-ignore-sigsetjmp-s-sec.patch	2021-05-05 21:38:31.000000000 +0200
@@ -0,0 +1,71 @@
+From ba9cce08553cb49fe077485b13ae99548bb2da5c Mon Sep 17 00:00:00 2001
+From: mirabilos <tg at debian.org>
+Date: Wed, 5 May 2021 21:02:37 +0200
+Subject: [PATCH 1/2] [klibc] sig{set,long}jmp: do not ignore sigsetjmp's
+ second argument
+
+Save and restore the signal mask only if that argument is nonzero,
+as required by the standards.  (Closes: Debian #988027)
+
+Signed-off-by: mirabilos <tg at debian.org>
+---
+ usr/include/setjmp.h   | 7 ++++++-
+ usr/klibc/CAVEATS      | 3 +--
+ usr/klibc/siglongjmp.c | 3 ++-
+ 3 files changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/usr/include/setjmp.h b/usr/include/setjmp.h
+index abebccde..5916cd8a 100644
+--- a/usr/include/setjmp.h
++++ b/usr/include/setjmp.h
+@@ -27,6 +27,7 @@ __extern __noreturn longjmp(jmp_buf, int);
+ struct __sigjmp_buf {
+ 	jmp_buf __jmpbuf;
+ 	sigset_t __sigs;
++	unsigned char __sigs_saved;
+ };
+ 
+ typedef struct __sigjmp_buf sigjmp_buf[1];
+@@ -34,7 +35,11 @@ typedef struct __sigjmp_buf sigjmp_buf[1];
+ #define sigsetjmp(__env, __save) \
+ ({ \
+   struct __sigjmp_buf *__e = (__env); \
+-  sigprocmask(0, NULL, &__e->__sigs); \
++  if (__save) { \
++    sigprocmask(0, NULL, &__e->__sigs); \
++    __e->__sigs_saved = 1; \
++  } else \
++    __e->__sigs_saved = 0; \
+   setjmp(__e->__jmpbuf); \
+ })
+ 
+diff --git a/usr/klibc/CAVEATS b/usr/klibc/CAVEATS
+index 5e991cb7..39949c28 100644
+--- a/usr/klibc/CAVEATS
++++ b/usr/klibc/CAVEATS
+@@ -13,8 +13,7 @@ Compiling with -O0 is more likely to work on gcc 3.
+ setjmp()/longjmp():
+ -------------------
+ setjmp() and longjmp() *do not* save signal state.  sigsetjmp() and
+-siglongjmp() *do* save the signal mask -- regardless of the value of
+-the extra argument.
++siglongjmp() *do* save the signal mask if the extra argument is nonzero.
+ 
+ The standards actually state that if you pass longjmp() a final value
+ of zero the library should change that to a 1!  Presumably the reason
+diff --git a/usr/klibc/siglongjmp.c b/usr/klibc/siglongjmp.c
+index 31042cbd..45f4e400 100644
+--- a/usr/klibc/siglongjmp.c
++++ b/usr/klibc/siglongjmp.c
+@@ -10,6 +10,7 @@
+ 
+ __noreturn siglongjmp(sigjmp_buf buf, int retval)
+ {
+-	sigprocmask(SIG_SETMASK, &buf->__sigs, NULL);
++	if (buf->__sigs_saved)
++		sigprocmask(SIG_SETMASK, &buf->__sigs, NULL);
+ 	longjmp(buf->__jmpbuf, retval);
+ }
+-- 
+2.31.1
+
diff -Nru klibc-2.0.8/debian/patches/0002-klibc-set-long-jmp-s390x-save-restore-the-correct-re.patch klibc-2.0.8/debian/patches/0002-klibc-set-long-jmp-s390x-save-restore-the-correct-re.patch
--- klibc-2.0.8/debian/patches/0002-klibc-set-long-jmp-s390x-save-restore-the-correct-re.patch	1970-01-01 01:00:00.000000000 +0100
+++ klibc-2.0.8/debian/patches/0002-klibc-set-long-jmp-s390x-save-restore-the-correct-re.patch	2021-05-05 21:38:31.000000000 +0200
@@ -0,0 +1,76 @@
+From fc5a53932ee56d61a9fd8db75784e9f39ca474a3 Mon Sep 17 00:00:00 2001
+From: mirabilos <tg at debian.org>
+Date: Wed, 5 May 2021 21:26:33 +0200
+Subject: [PATCH 2/2] [klibc] {set,long}jmp [s390x]: save/restore the correct
+ registers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The s390x ABI actually has FPU registers f8‥f15, not f1/f3/f5/f7,
+to be saved. (Closes: Debian #943425)
+
+Signed-off-by: mirabilos <tg at debian.org>
+---
+ usr/include/arch/s390/klibc/archsetjmp.h |  2 +-
+ usr/klibc/arch/s390/setjmp.S             | 24 ++++++++++++++++--------
+ 2 files changed, 17 insertions(+), 9 deletions(-)
+
+diff --git a/usr/include/arch/s390/klibc/archsetjmp.h b/usr/include/arch/s390/klibc/archsetjmp.h
+index 728780ad..1167c8b6 100644
+--- a/usr/include/arch/s390/klibc/archsetjmp.h
++++ b/usr/include/arch/s390/klibc/archsetjmp.h
+@@ -16,7 +16,7 @@ struct __jmp_buf {
+ 
+ struct __jmp_buf {
+ 	uint64_t __gregs[10]; /* general registers r6-r15 */
+-	uint64_t __fpregs[4]; /* fp registers f1, f3, f5, f7 */
++	uint64_t __fpregs[8]; /* fp registers f8-f15 */
+ };
+ 
+ #endif /* __s390x__ */
+diff --git a/usr/klibc/arch/s390/setjmp.S b/usr/klibc/arch/s390/setjmp.S
+index c36a0517..1386419a 100644
+--- a/usr/klibc/arch/s390/setjmp.S
++++ b/usr/klibc/arch/s390/setjmp.S
+@@ -38,10 +38,14 @@ longjmp:
+ 
+ setjmp:
+ 	stmg	%r6,%r15,0(%r2)		# save all general registers
+-	std	%f1,80(%r2)		# save fp registers f4 and f6
+-	std	%f3,88(%r2)
+-	std	%f5,96(%r2)
+-	std	%f7,104(%r2)
++	std	%f8,80(%r2)		# save fp registers f8 to f15
++	std	%f9,88(%r2)
++	std	%f10,96(%r2)
++	std	%f11,104(%r2)
++	std	%f12,112(%r2)
++	std	%f13,120(%r2)
++	std	%f14,128(%r2)
++	std	%f15,136(%r2)
+ 	lghi	%r2,0			# return 0
+ 	br	%r14
+ 
+@@ -54,10 +58,14 @@ setjmp:
+ longjmp:
+ 	lgr	%r1,%r2			# jmp_buf
+ 	lgr	%r2,%r3			# return value
+-	ld	%f7,104(%r1)		# restore all saved registers
+-	ld	%f5,96(%r1)
+-	ld	%f3,88(%r1)
+-	ld	%f1,80(%r1)
++	ld	%f15,136(%r1)		# restore all saved registers
++	ld	%f14,128(%r1)
++	ld	%f13,120(%r1)
++	ld	%f12,112(%r1)
++	ld	%f11,104(%r1)
++	ld	%f10,96(%r1)
++	ld	%f9,88(%r1)
++	ld	%f8,80(%r1)
+ 	lmg	%r6,%r15,0(%r1)
+ 	br	%r14			# return to restored address
+ 
+-- 
+2.31.1
+
diff -Nru klibc-2.0.8/debian/patches/series klibc-2.0.8/debian/patches/series
--- klibc-2.0.8/debian/patches/series	2021-04-30 02:38:31.000000000 +0200
+++ klibc-2.0.8/debian/patches/series	2021-05-05 21:38:17.000000000 +0200
@@ -10,3 +10,5 @@
 0037-klibc-calloc-Fail-if-multiplication-overflows.patch
 0039-klibc-cpio-Fix-possible-integer-overflow-on-32-bit-s.patch
 0040-klibc-cpio-Fix-possible-crash-on-64-bit-systems.patch
+0001-klibc-sig-set-long-jmp-do-not-ignore-sigsetjmp-s-sec.patch
+0002-klibc-set-long-jmp-s390x-save-restore-the-correct-re.patch


More information about the klibc mailing list