about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/i386/sigaction.c
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2017-11-17 16:04:29 -0200
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2018-03-05 18:08:27 -0300
commit68448be208ee06e76665918b37b0a57e3e00c8b4 (patch)
tree07c9ed97d7afa4a6516db76079638e7329c12504 /sysdeps/unix/sysv/linux/i386/sigaction.c
parent8d965cde7a2bc18a010325607f6f526db86cdaf0 (diff)
downloadglibc-68448be208ee06e76665918b37b0a57e3e00c8b4.tar.gz
glibc-68448be208ee06e76665918b37b0a57e3e00c8b4.tar.xz
glibc-68448be208ee06e76665918b37b0a57e3e00c8b4.zip
i386: Fix i386 sigaction sa_restorer initialization (BZ#21269)
This patch fixes the i386 sa_restorer field initialization for sigaction
syscall for kernel with vDSO.  As described in bug report, i386 Linux
(and compat on x86_64) interprets SA_RESTORER clear with nonzero
sa_restorer as a request for stack switching if the SS segment is 'funny'.
This means that anything that tries to mix glibc's signal handling with
segmentation (for instance through modify_ldt syscall) is randomly broken
depending on what values lands in sa_restorer.

The testcase added  is based on Linux test tools/testing/selftests/x86/ldt_gdt.c,
more specifically in do_multicpu_tests function.  The main changes are:

  - C11 atomics instead of plain access.

  - Remove x86_64 support which simplifies the syscall handling and fallbacks.

  - Replicate only the test required to trigger the issue.

Checked on i686-linux-gnu.

	[BZ #21269]
	* sysdeps/unix/sysv/linux/i386/Makefile (tests): Add tst-bz21269.
	* sysdeps/unix/sysv/linux/i386/sigaction.c (SET_SA_RESTORER): Clear
	sa_restorer for vDSO case.
	* sysdeps/unix/sysv/linux/i386/tst-bz21269.c: New file.
Diffstat (limited to 'sysdeps/unix/sysv/linux/i386/sigaction.c')
-rw-r--r--sysdeps/unix/sysv/linux/i386/sigaction.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/sysdeps/unix/sysv/linux/i386/sigaction.c b/sysdeps/unix/sysv/linux/i386/sigaction.c
index a5eb9e0d3e..177ff60ee6 100644
--- a/sysdeps/unix/sysv/linux/i386/sigaction.c
+++ b/sysdeps/unix/sysv/linux/i386/sigaction.c
@@ -42,7 +42,6 @@ extern void restore_rt (void) asm ("__restore_rt") attribute_hidden;
 #endif
 extern void restore (void) asm ("__restore") attribute_hidden;
 
-
 /* If ACT is not NULL, change the action for SIG to *ACT.
    If OACT is not NULL, put the old action for SIG in *OACT.  */
 int
@@ -65,6 +64,8 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
 	  kact.sa_restorer = ((act->sa_flags & SA_SIGINFO)
 			      ? &restore_rt : &restore);
 	}
+      else
+	kact.sa_restorer = NULL;
     }
 
   /* XXX The size argument hopefully will have to be changed to the