Patch "s390/compat: correct uc_sigmask of the compat signal frame" has been added to the 4.1-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
s390/compat: correct uc_sigmask of the compat signal frame
to the 4.1-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
s390-compat-correct-uc_sigmask-of-the-compat-signal-frame.patch
and it can be found in the queue-4.1 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
8d4bd0ed0439dfc780aab801a085961925ed6838Mon Sep 17 00:00:00 2001
From: Martin Schwidefsky <[email protected]>
Date: Tue, 8 Sep 2015 15:25:39 +0200
Subject: s390/compat: correct uc_sigmask of the compat signal frame
From: Martin Schwidefsky <[email protected]>
commit 8d4bd0ed0439dfc780aab801a085961925ed6838 upstream.
The uc_sigmask in the ucontext structure is an array of words to keep the 64 signal bits (or 1024 if you ask glibc but the kernel sigset_t only has 64 bits).
For 64 bit the sigset_t contains a single 8 byte word, but for 31 bit there are two 4 byte words. The compat signal handler code uses a simple copy of the 64 bit sigset_t to the 31 bit compat_sigset_t. As s390 is a big-endian architecture this is incorrect, the two words in the 31 bit sigset_t array need to be swapped.
--- arch/s390/kernel/compat_signal.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-)
arch/s390/kernel/compat_signal.c +23 -4
@@ -48,6 +48,19 @@ typedef structstruct ucontext32 uc; } rt_sigframe32; +static inline void sigset_to_sigset32 (unsigned long *set64, +compat_sigset_word *set32) +{ + set32[0 ] = (compat_sigset_word ) set64[0 ]; + set32[1 ] = (compat_sigset_word)(set64[0 ] >>32 ); +} + +static inline void sigset32_to_sigset (compat_sigset_word *set32, +unsigned long *set64) +{ + set64[0 ] = (unsigned long ) set32[0 ] | ((unsigned long ) set32[1 ] <<32 ); +} +int copy_siginfo_to_user32 (compat_siginfo_t __user *to,const siginfo_t *from) {int err;
@@ -303,10 +316,12 @@ COMPAT_SYSCALL_DEFINE0(sigreturn) {struct pt_regs *regs =task_pt_regs (current);sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15 ]; +compat_sigset_t cset;sigset_t set; -if (__copy_from_user (&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32)) +if (__copy_from_user (&cset.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32)) goto badframe; +sigset32_to_sigset (cset.sig, set.sig);set_current_blocked (&set);if (restore_sigregs32 (regs, &frame->sregs)) goto badframe;
@@ -323,10 +338,12 @@ COMPAT_SYSCALL_DEFINE0(rt_sigreturn) {struct pt_regs *regs =task_pt_regs (current);rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15 ]; +compat_sigset_t cset;sigset_t set; -if (__copy_from_user (&set, &frame->uc.uc_sigmask,sizeof (set))) +if (__copy_from_user (&cset, &frame->uc.uc_sigmask,sizeof (cset))) goto badframe; +sigset32_to_sigset (cset.sig, set.sig);set_current_blocked (&set);if (compat_restore_altstack (&frame->uc.uc_stack)) goto badframe;
@@ -397,7 +414,7 @@ static int setup_frame32(struct ksignalreturn -EFAULT ;/* Create struct sigcontext32 on the signal stack */ -memcpy (&sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE32); +sigset_to_sigset32 (set->sig, sc.oldmask); sc.sregs = (__u32 )(unsigned long __force ) &frame->sregs;if (__copy_to_user (&frame->sc, &sc,sizeof (frame->sc)))return -EFAULT ;
@@ -458,6 +475,7 @@ static int setup_frame32(struct ksignalstatic int setup_rt_frame32 (struct ksignal *ksig,sigset_t *set,struct pt_regs *regs) { +compat_sigset_t cset;rt_sigframe32 __user *frame;unsigned long restorer;size_t frame_size;
@@ -505,11 +523,12 @@ static int setup_rt_frame32(struct ksignstore_sigregs ();/* Create ucontext on the signal stack. */ +sigset_to_sigset32 (set->sig, cset.sig);if (__put_user (uc_flags, &frame->uc.uc_flags) ||__put_user (0 , &frame->uc.uc_link) ||__compat_save_altstack (&frame->uc.uc_stack, regs->gprs[15 ]) ||save_sigregs32 (regs, &frame->uc.uc_mcontext) || -__copy_to_user (&frame->uc.uc_sigmask, set,sizeof (*set)) || +__copy_to_user (&frame->uc.uc_sigmask, &cset,sizeof (cset)) ||save_sigregs_ext32 (regs, &frame->uc.uc_mcontext_ext))return -EFAULT ;
Patches currently in stable-queue which might be from [email protected] are
queue-4.1/s390-compat-correct-uc_sigmask-of-the-compat-signal-frame.patch