Linux/x86: Update cancel_jmp_buf to match __jmp_buf_tag [BZ #22563]

On x86, padding in struct __jmp_buf_tag is used for shadow stack pointer
to support shadow stack in Intel Control-flow Enforcemen Technology.
Since the cancel_jmp_buf array is passed to setjmp and longjmp by
casting it to pointer to struct __jmp_buf_tag, it should be as large
as struct __jmp_buf_tag.  Otherwise when shadow stack is enabled,
setjmp and longjmp will write and read beyond cancel_jmp_buf when saving
and restoring shadow stack pointer.

This patch adds bits/types/__cancel_jmp_buf_tag.h to define struct
__cancel_jmp_buf_tag so that Linux/x86 can add saved_mask to
cancel_jmp_buf.

Tested natively on i386, x86_64 and x32.  Tested hppa-linux-gnu with
build-many-glibcs.py.

	[BZ #22563]
	* bits/types/__cancel_jmp_buf_tag.h: New file.
	* sysdeps/unix/sysv/linux/x86/bits/types/__cancel_jmp_buf_tag.h
	* sysdeps/unix/sysv/linux/x86/pthreaddef.h: Likewise.
	* sysdeps/unix/sysv/linux/x86/nptl/pthreadP.h: Likewise.
	* nptl/Makefile (headers): Add
	bits/types/__cancel_jmp_buf_tag.h.
	* nptl/descr.h [NEED_SAVED_MASK_IN_CANCEL_JMP_BUF]
	(pthread_unwind_buf): Add saved_mask to cancel_jmp_buf.
	* sysdeps/nptl/pthread.h: Include
	<bits/types/__cancel_jmp_buf_tag.h>.
	(__pthread_unwind_buf_t): Use struct __cancel_jmp_buf_tag with
	__cancel_jmp_buf.
	* sysdeps/unix/sysv/linux/hppa/pthread.h: Likewise.
This commit is contained in:
H.J. Lu 2017-12-19 02:43:50 -08:00
parent 1a49fc59e4
commit f81ddabffd
9 changed files with 143 additions and 11 deletions

View File

@ -1,3 +1,20 @@
2017-12-19 H.J. Lu <hongjiu.lu@intel.com>
[BZ #22563]
* bits/types/__cancel_jmp_buf_tag.h: New file.
* sysdeps/unix/sysv/linux/x86/bits/types/__cancel_jmp_buf_tag.h
* sysdeps/unix/sysv/linux/x86/pthreaddef.h: Likewise.
* sysdeps/unix/sysv/linux/x86/nptl/pthreadP.h: Likewise.
* nptl/Makefile (headers): Add
bits/types/__cancel_jmp_buf_tag.h.
* nptl/descr.h [NEED_SAVED_MASK_IN_CANCEL_JMP_BUF]
(pthread_unwind_buf): Add saved_mask to cancel_jmp_buf.
* sysdeps/nptl/pthread.h: Include
<bits/types/__cancel_jmp_buf_tag.h>.
(__pthread_unwind_buf_t): Use struct __cancel_jmp_buf_tag with
__cancel_jmp_buf.
* sysdeps/unix/sysv/linux/hppa/pthread.h: Likewise.
2017-12-18 H.J. Lu <hongjiu.lu@intel.com> 2017-12-18 H.J. Lu <hongjiu.lu@intel.com>
* scripts/build-many-glibcs.py (Context.add_all_configs): Add * scripts/build-many-glibcs.py (Context.add_all_configs): Add

View File

@ -0,0 +1,28 @@
/* Define struct __cancel_jmp_buf_tag.
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 ____cancel_jmp_buf_tag_defined
#define ____cancel_jmp_buf_tag_defined 1
struct __cancel_jmp_buf_tag
{
__jmp_buf __cancel_jmp_buf;
int __mask_was_saved;
};
#endif

View File

@ -22,7 +22,8 @@ subdir := nptl
include ../Makeconfig include ../Makeconfig
headers := pthread.h semaphore.h bits/semaphore.h headers := pthread.h semaphore.h bits/semaphore.h \
bits/types/__cancel_jmp_buf_tag.h
extra-libs := libpthread extra-libs := libpthread
extra-libs-others := $(extra-libs) extra-libs-others := $(extra-libs)

View File

@ -65,6 +65,9 @@ struct pthread_unwind_buf
{ {
__jmp_buf jmp_buf; __jmp_buf jmp_buf;
int mask_was_saved; int mask_was_saved;
#ifdef NEED_SAVED_MASK_IN_CANCEL_JMP_BUF
__sigset_t saved_mask;
#endif
} cancel_jmp_buf[1]; } cancel_jmp_buf[1];
union union

View File

@ -27,6 +27,7 @@
#include <bits/setjmp.h> #include <bits/setjmp.h>
#include <bits/wordsize.h> #include <bits/wordsize.h>
#include <bits/types/struct_timespec.h> #include <bits/types/struct_timespec.h>
#include <bits/types/__cancel_jmp_buf_tag.h>
/* Detach state. */ /* Detach state. */
@ -523,11 +524,7 @@ extern void pthread_testcancel (void);
typedef struct typedef struct
{ {
struct struct __cancel_jmp_buf_tag __cancel_jmp_buf[1];
{
__jmp_buf __cancel_jmp_buf;
int __mask_was_saved;
} __cancel_jmp_buf[1];
void *__pad[4]; void *__pad[4];
} __pthread_unwind_buf_t __attribute__ ((__aligned__)); } __pthread_unwind_buf_t __attribute__ ((__aligned__));

View File

@ -27,6 +27,7 @@
#include <bits/setjmp.h> #include <bits/setjmp.h>
#include <bits/wordsize.h> #include <bits/wordsize.h>
#include <bits/types/struct_timespec.h> #include <bits/types/struct_timespec.h>
#include <bits/types/__cancel_jmp_buf_tag.h>
/* Detach state. */ /* Detach state. */
@ -499,11 +500,7 @@ extern void pthread_testcancel (void);
typedef struct typedef struct
{ {
struct struct __cancel_jmp_buf_tag __cancel_jmp_buf[1];
{
__jmp_buf __cancel_jmp_buf;
int __mask_was_saved;
} __cancel_jmp_buf[1];
void *__pad[4]; void *__pad[4];
} __pthread_unwind_buf_t __attribute__ ((__aligned__)); } __pthread_unwind_buf_t __attribute__ ((__aligned__));

View File

@ -0,0 +1,31 @@
/* Define struct __cancel_jmp_buf_tag.
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 ____cancel_jmp_buf_tag_defined
#define ____cancel_jmp_buf_tag_defined 1
#include <bits/types/__sigset_t.h>
struct __cancel_jmp_buf_tag
{
__jmp_buf __cancel_jmp_buf;
int __mask_was_saved;
__sigset_t __saved_mask;
};
#endif

View File

@ -0,0 +1,36 @@
/* Internal pthread header. 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/>. */
#include_next <nptl/pthreadP.h>
#ifndef _PTHREADP_H_X86
#define _PTHREADP_H_X86 1
extern struct pthread_unwind_buf ____pthread_unwind_buf_private;
_Static_assert (sizeof (____pthread_unwind_buf_private.cancel_jmp_buf)
>= sizeof (struct __jmp_buf_tag),
"size of cancel_jmp_buf < sizeof __jmp_buf_tag");
extern __pthread_unwind_buf_t ____pthread_unwind_buf;
_Static_assert (sizeof (____pthread_unwind_buf.__cancel_jmp_buf)
>= sizeof (struct __jmp_buf_tag),
"size of __cancel_jmp_buf < sizeof __jmp_buf_tag");
#endif

View File

@ -0,0 +1,22 @@
/* Pthread macros. 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/>. */
#include_next <pthreaddef.h>
/* Need saved_mask in cancel_jmp_buf. */
#define NEED_SAVED_MASK_IN_CANCEL_JMP_BUF 1