This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch master updated. glibc-2.26.9000-871-gf33632c


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  f33632ccd1dec3217583fcfdd965afb62954203c (commit)
      from  34697694e8a93b325b18f25f7dcded55d6baeaf6 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=f33632ccd1dec3217583fcfdd965afb62954203c

commit f33632ccd1dec3217583fcfdd965afb62954203c
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Nov 30 04:49:25 2017 -0800

    x86: Make a space in jmpbuf for shadow stack pointer
    
    To support Shadow Stack (SHSTK) in Intel Control-flow Enforcement
    Technology (CET) in setjmp/longjmp, we need to save shadow stack
    pointer in jmp_buf.  The __saved_mask field in jmp_buf has type
    of __sigset_t.  On Linux, __sigset_t is defined as
    
     #define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int)))
    typedef struct
    {
      unsigned long int __val[_SIGSET_NWORDS];
    } __sigset_t;
    
    which is much bigger than expected by the __sigprocmask system call,
    which has
    
    typedef struct {
            unsigned long sig[_NSIG_WORDS];
    } sigset_t;
    
    For Linux/x86, we can shrink __sigset_t used by __saved_mask in jmp_buf
    to add paddings for shadow stack pointer.  As long as the new __sigset_t
    is not smaller than sigset_t expected by the __sigprocmask system call,
    it should work correctly.
    
    This patch adds an internal header file, <setjmpP.h>, to define
    __jmp_buf_sigset_t for __saved_mask in jmp_buf for Linux/x86 with a
    space to store shadow stack pointer.  It verifies __jmp_buf_sigset_t has
    the suitable size for the __sigprocmask system call.   A run-time test,
    tst-saved_mask-1.c, is added to verify that size of __jmp_buf_sigset_t
    is sufficient.  If its size is too small, the test fails with
    
    rt_sigprocmask(SIG_SETMASK, strace: umoven: short read (4 < 8) @0x7fa8aa28effc
    0x7fa8aa28effc, NULL, 8) = -1 EFAULT (Bad address)
    rt_sigprocmask(SIG_SETMASK, strace: umoven: short read (4 < 8) @0x7fa8aa28effc
    0x7fa8aa28effc, NULL, 8) = -1 EFAULT (Bad address)
    rt_sigprocmask(SIG_SETMASK, NULL, 0x7fa8aa28effc, 8) = -1 EFAULT (Bad address)
    exit_group(1)                           = ?
    
    Tested with build-many-glibcs.py.
    
    	* debug/longjmp_chk.c: Include <setjmpP.h> instead of
    	<setjmp.h>.
    	* setjmp/longjmp.c: Include <setjmpP.h> instead of <setjmp.h>.
    	(__libc_siglongjmp): Cast &env[0].__saved_mask to "sigset_t *".
    	* setjmp/sigjmp.c: Include <setjmpP.h> instead of <setjmp.h>.
    	(__sigjmp_save): Cast &env[0].__saved_mask to "sigset_t *".
    	* sysdeps/generic/setjmpP.h: New file.
    	* sysdeps/unix/sysv/linux/x86/jmp_buf-ssp.sym: Likewise.
    	* sysdeps/unix/sysv/linux/x86/setjmpP.h: Likewise.
    	* sysdeps/unix/sysv/linux/x86/tst-saved_mask-1.c: Likewise.
    	* sysdeps/unix/sysv/linux/x86/Makefile (gen-as-const-headers):
    	Add jmp_buf-ssp.sym.
    	(tests): Add tst-saved_mask-1.

diff --git a/ChangeLog b/ChangeLog
index 888f9fb..d4cc1ab 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2017-11-30  H.J. Lu  <hongjiu.lu@intel.com>
+
+	* debug/longjmp_chk.c: Include <setjmpP.h> instead of
+	<setjmp.h>.
+	* setjmp/longjmp.c: Include <setjmpP.h> instead of <setjmp.h>.
+	(__libc_siglongjmp): Cast &env[0].__saved_mask to "sigset_t *".
+	* setjmp/sigjmp.c: Include <setjmpP.h> instead of <setjmp.h>.
+	(__sigjmp_save): Cast &env[0].__saved_mask to "sigset_t *".
+	* sysdeps/generic/setjmpP.h: New file.
+	* sysdeps/unix/sysv/linux/x86/jmp_buf-ssp.sym: Likewise.
+	* sysdeps/unix/sysv/linux/x86/setjmpP.h: Likewise.
+	* sysdeps/unix/sysv/linux/x86/tst-saved_mask-1.c: Likewise.
+	* sysdeps/unix/sysv/linux/x86/Makefile (gen-as-const-headers):
+	Add jmp_buf-ssp.sym.
+	(tests): Add tst-saved_mask-1.
+
 2017-11-30  Arjun Shankar  <arjun@redhat.com>
 
 	[BZ #22375]
diff --git a/debug/longjmp_chk.c b/debug/longjmp_chk.c
index 1cea6c0..61be0da 100644
--- a/debug/longjmp_chk.c
+++ b/debug/longjmp_chk.c
@@ -15,7 +15,7 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <setjmp.h>
+#include <setjmpP.h>
 
 #define __longjmp ____longjmp_chk
 #define __libc_siglongjmp __longjmp_chk
diff --git a/setjmp/longjmp.c b/setjmp/longjmp.c
index 2453c2c..e144a87 100644
--- a/setjmp/longjmp.c
+++ b/setjmp/longjmp.c
@@ -16,7 +16,7 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <stddef.h>
-#include <setjmp.h>
+#include <setjmpP.h>
 #include <signal.h>
 
 
@@ -31,7 +31,8 @@ __libc_siglongjmp (sigjmp_buf env, int val)
 
   if (env[0].__mask_was_saved)
     /* Restore the saved signal mask.  */
-    (void) __sigprocmask (SIG_SETMASK, &env[0].__saved_mask,
+    (void) __sigprocmask (SIG_SETMASK,
+			  (sigset_t *) &env[0].__saved_mask,
 			  (sigset_t *) NULL);
 
   /* Call the machine-dependent function to restore machine state.  */
diff --git a/setjmp/sigjmp.c b/setjmp/sigjmp.c
index 30839ae..32b727f 100644
--- a/setjmp/sigjmp.c
+++ b/setjmp/sigjmp.c
@@ -16,7 +16,7 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <stddef.h>
-#include <setjmp.h>
+#include <setjmpP.h>
 #include <signal.h>
 
 /* This function is called by the `sigsetjmp' macro
@@ -28,7 +28,7 @@ __sigjmp_save (sigjmp_buf env, int savemask)
 {
   env[0].__mask_was_saved = (savemask &&
 			     __sigprocmask (SIG_BLOCK, (sigset_t *) NULL,
-					    &env[0].__saved_mask) == 0);
+					    (sigset_t *) &env[0].__saved_mask) == 0);
 
   return 0;
 }
diff --git a/debug/longjmp_chk.c b/sysdeps/generic/setjmpP.h
similarity index 81%
copy from debug/longjmp_chk.c
copy to sysdeps/generic/setjmpP.h
index 1cea6c0..a878ce6 100644
--- a/debug/longjmp_chk.c
+++ b/sysdeps/generic/setjmpP.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 2009-2017 Free Software Foundation, Inc.
+/* Internal header file for <setjmp.h>.  Generic version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -15,9 +16,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <setjmp.h>
+#ifndef	_SETJMPP_H
+#define	_SETJMPP_H	1
 
-#define __longjmp ____longjmp_chk
-#define __libc_siglongjmp __longjmp_chk
+#include <setjmp.h>
 
-#include <setjmp/longjmp.c>
+#endif /* setjmpP.h  */
diff --git a/sysdeps/unix/sysv/linux/x86/Makefile b/sysdeps/unix/sysv/linux/x86/Makefile
index c069570..c55a43e 100644
--- a/sysdeps/unix/sysv/linux/x86/Makefile
+++ b/sysdeps/unix/sysv/linux/x86/Makefile
@@ -19,3 +19,8 @@ endif
 ifeq ($(subdir),elf)
 sysdep_routines += dl-vdso
 endif
+
+ifeq ($(subdir),setjmp)
+gen-as-const-headers += jmp_buf-ssp.sym
+tests += tst-saved_mask-1
+endif
diff --git a/sysdeps/unix/sysv/linux/x86/jmp_buf-ssp.sym b/sysdeps/unix/sysv/linux/x86/jmp_buf-ssp.sym
new file mode 100644
index 0000000..1282919
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/jmp_buf-ssp.sym
@@ -0,0 +1,5 @@
+#include <setjmpP.h>
+#undef __saved_mask
+
+--
+SHADOW_STACK_POINTER_OFFSET offsetof(struct __jmp_buf_tag, __saved_mask.__saved.__shadow_stack_pointer)
diff --git a/sysdeps/unix/sysv/linux/x86/setjmpP.h b/sysdeps/unix/sysv/linux/x86/setjmpP.h
new file mode 100644
index 0000000..69a46d0
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/setjmpP.h
@@ -0,0 +1,67 @@
+/* Internal header file for <setjmp.h>.  Linux/x86 version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef	_SETJMPP_H
+#define	_SETJMPP_H	1
+
+#include <bits/types/__sigset_t.h>
+
+/* The biggest signal number + 1.  As of kernel 4.14, x86 _NSIG is 64.
+   Define it to 513 to leave some rooms for future use.  */
+#define _JUMP_BUF_SIGSET_NSIG	513
+/* Number of longs to hold all signals.  */
+#define _JUMP_BUF_SIGSET_NWORDS \
+  ((_JUMP_BUF_SIGSET_NSIG - 1 + 7) / (8 * sizeof (unsigned long int)))
+
+typedef struct
+  {
+    unsigned long int __val[_JUMP_BUF_SIGSET_NWORDS];
+  } __jmp_buf_sigset_t;
+
+typedef union
+  {
+    __sigset_t __saved_mask_compat;
+    struct
+      {
+	__jmp_buf_sigset_t __saved_mask;
+	/* Used for shadow stack pointer.  */
+	unsigned long int __shadow_stack_pointer;
+      } __saved;
+  } __jmpbuf_arch_t;
+
+#undef __sigset_t
+#define __sigset_t __jmpbuf_arch_t
+#include <setjmp.h>
+#undef __saved_mask
+#define __saved_mask __saved_mask.__saved.__saved_mask
+
+#include <signal.h>
+
+#define _SIGPROCMASK_NSIG_WORDS (_NSIG / (8 * sizeof (unsigned long int)))
+
+typedef struct
+  {
+    unsigned long int __val[_SIGPROCMASK_NSIG_WORDS];
+  } __sigprocmask_sigset_t;
+
+extern jmp_buf ___buf;
+extern  __typeof (___buf[0].__saved_mask) ___saved_mask;
+_Static_assert (sizeof (___saved_mask) >= sizeof (__sigprocmask_sigset_t),
+		"size of ___saved_mask < size of __sigprocmask_sigset_t");
+
+#endif /* setjmpP.h  */
diff --git a/sysdeps/unix/sysv/linux/x86/tst-saved_mask-1.c b/sysdeps/unix/sysv/linux/x86/tst-saved_mask-1.c
new file mode 100644
index 0000000..f383408
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/tst-saved_mask-1.c
@@ -0,0 +1,55 @@
+/* Test that sigprocmask does not read from the unused part of jmpbuf.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include <errno.h>
+#include <setjmpP.h>
+#include <support/next_to_fault.h>
+
+#define SIZEOF_SIGSET_T sizeof (__jmp_buf_sigset_t)
+
+static int
+do_test (void)
+{
+  sigjmp_buf sj;
+  struct support_next_to_fault sigset_t_buf
+    = support_next_to_fault_allocate (SIZEOF_SIGSET_T);
+  sigset_t *m_p = (sigset_t *) sigset_t_buf.buffer;
+  sigset_t m;
+
+  sigemptyset (&m);
+  memcpy (m_p, &m, SIZEOF_SIGSET_T);
+  sigprocmask (SIG_SETMASK, m_p, NULL);
+  memcpy (&m, m_p, SIZEOF_SIGSET_T);
+  if (sigsetjmp (sj, 0) == 0)
+    {
+      sigaddset (&m, SIGUSR1);
+      memcpy (m_p, &m, SIZEOF_SIGSET_T);
+      sigprocmask (SIG_SETMASK, m_p, NULL);
+      memcpy (&m, m_p, SIZEOF_SIGSET_T);
+      siglongjmp (sj, 1);
+      return EXIT_FAILURE;
+    }
+  sigprocmask (SIG_SETMASK, NULL, m_p);
+  memcpy (&m, m_p, SIZEOF_SIGSET_T);
+  return sigismember (&m, SIGUSR1) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+#include <support/test-driver.c>

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                                      |   16 ++++++
 debug/longjmp_chk.c                            |    2 +-
 setjmp/longjmp.c                               |    5 +-
 setjmp/sigjmp.c                                |    4 +-
 sysdeps/generic/setjmpP.h                      |   24 +++++++++
 sysdeps/unix/sysv/linux/x86/Makefile           |    5 ++
 sysdeps/unix/sysv/linux/x86/jmp_buf-ssp.sym    |    5 ++
 sysdeps/unix/sysv/linux/x86/setjmpP.h          |   67 ++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/x86/tst-saved_mask-1.c |   55 +++++++++++++++++++
 9 files changed, 178 insertions(+), 5 deletions(-)
 create mode 100644 sysdeps/generic/setjmpP.h
 create mode 100644 sysdeps/unix/sysv/linux/x86/jmp_buf-ssp.sym
 create mode 100644 sysdeps/unix/sysv/linux/x86/setjmpP.h
 create mode 100644 sysdeps/unix/sysv/linux/x86/tst-saved_mask-1.c


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]