Major new features:
+* Add _SC_MINSIGSTKSZ and _SC_SIGSTKSZ. When _SC_SIGSTKSZ_SOURCE or
+ _GNU_SOURCE are defined, MINSIGSTKSZ and SIGSTKSZ are no longer
+ constant on Linux. MINSIGSTKSZ is redefined to sysconf(_SC_MINSIGSTKSZ)
+ and SIGSTKSZ is redefined to sysconf (_SC_SIGSTKSZ).
+
* The dynamic linker accepts the --list-tunables argument which prints
all the supported tunables. This option is disable if glibc is
configured with tunables disabled (--enable-tunables=no).
_SC_THREAD_ROBUST_PRIO_INHERIT,
#define _SC_THREAD_ROBUST_PRIO_INHERIT _SC_THREAD_ROBUST_PRIO_INHERIT
- _SC_THREAD_ROBUST_PRIO_PROTECT
+ _SC_THREAD_ROBUST_PRIO_PROTECT,
#define _SC_THREAD_ROBUST_PRIO_PROTECT _SC_THREAD_ROBUST_PRIO_PROTECT
+
+ _SC_MINSIGSTKSZ,
+#define _SC_MINSIGSTKSZ _SC_MINSIGSTKSZ
+
+ _SC_SIGSTKSZ
+#define _SC_SIGSTKSZ _SC_SIGSTKSZ
};
/* Values for the NAME argument to `confstr'. */
--- /dev/null
+/* Definition of MINSIGSTKSZ. Generic version.
+ Copyright (C) 2020 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
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _SIGNAL_H
+# error "Never include <bits/sigstksz.h> directly; use <signal.h> instead."
+#endif
size_t _dl_pagesize = EXEC_PAGESIZE;
+size_t _dl_minsigstacksize = CONSTANT_MINSIGSTKSZ;
+
int _dl_inhibit_cache;
unsigned int _dl_osversion;
case AT_RANDOM:
_dl_random = (void *) av->a_un.a_val;
break;
+ case AT_MINSIGSTKSZ:
+ _dl_minsigstacksize = av->a_un.a_val;
+ break;
DL_PLATFORM_AUXV
}
if (seen == 0xf)
user_entry = (ElfW(Addr)) ENTRY_POINT;
GLRO(dl_platform) = NULL; /* Default to nothing known about the platform. */
+ /* NB: Default to a constant CONSTANT_MINSIGSTKSZ. */
+ _Static_assert (__builtin_constant_p (CONSTANT_MINSIGSTKSZ),
+ "CONSTANT_MINSIGSTKSZ is constant");
+ GLRO(dl_minsigstacksize) = CONSTANT_MINSIGSTKSZ;
+
for (av = GLRO(dl_auxv); av->a_type != AT_NULL; set_seen (av++))
switch (av->a_type)
{
case AT_RANDOM:
_dl_random = (void *) av->a_un.a_val;
break;
+ case AT_MINSIGSTKSZ:
+ GLRO(dl_minsigstacksize) = av->a_un.a_val;
+ break;
DL_PLATFORM_AUXV
}
[AT_SYSINFO_EHDR - 2] = { "SYSINFO_EHDR: 0x", hex },
[AT_RANDOM - 2] = { "RANDOM: 0x", hex },
[AT_HWCAP2 - 2] = { "HWCAP2: 0x", hex },
+ [AT_MINSIGSTKSZ - 2] = { "MINSIGSTKSZ ", dec },
[AT_L1I_CACHESIZE - 2] = { "L1I_CACHESIZE: ", dec },
[AT_L1I_CACHEGEOMETRY - 2] = { "L1I_CACHEGEOMETRY: 0x", hex },
[AT_L1D_CACHESIZE - 2] = { "L1D_CACHESIZE: ", dec },
--- /dev/null
+#include_next <bits/sigstack.h>
+
+#if !defined _ISOMAC && !defined CONSTANT_MINSIGSTKSZ
+# define CONSTANT_MINSIGSTKSZ MINSIGSTKSZ
+#endif
--- /dev/null
+/* NB: Don't define MINSIGSTKSZ nor SIGSTKSZ to sysconf (SC_SIGSTKSZ) for
+ glibc build. IS_IN can only be used when _ISOMAC isn't defined. */
+#ifdef _ISOMAC
+# include_next <bits/sigstksz.h>
+#elif IS_IN (libsupport)
+# include_next <bits/sigstksz.h>
+#endif
_LARGEFILE64_SOURCE Additional functionality from LFS for large files.
_FILE_OFFSET_BITS=N Select default filesystem interface.
_ATFILE_SOURCE Additional *at interfaces.
+ _SC_SIGSTKSZ_SOURCE Select correct (but non compile-time constant)
+ MINSIGSTKSZ and SIGSTKSZ.
_GNU_SOURCE All of the above, plus GNU extensions.
_DEFAULT_SOURCE The default set of features (taking precedence over
__STRICT_ANSI__).
__USE_FILE_OFFSET64 Define 64bit interface as default.
__USE_MISC Define things from 4.3BSD or System V Unix.
__USE_ATFILE Define *at interfaces and AT_* constants for them.
+ __USE_SC_SIGSTKSZ Define correct (but non compile-time constant)
+ MINSIGSTKSZ and SIGSTKSZ.
__USE_GNU Define GNU extensions.
__USE_FORTIFY_LEVEL Additional security measures used, according to level.
#undef __USE_FILE_OFFSET64
#undef __USE_MISC
#undef __USE_ATFILE
+#undef __USE_SC_SIGSTKSZ
#undef __USE_GNU
#undef __USE_FORTIFY_LEVEL
#undef __KERNEL_STRICT_NAMES
# define _DEFAULT_SOURCE 1
# undef _ATFILE_SOURCE
# define _ATFILE_SOURCE 1
+# undef _SC_SIGSTKSZ_SOURCE
+# define _SC_SIGSTKSZ_SOURCE 1
#endif
/* If nothing (other than _GNU_SOURCE and _DEFAULT_SOURCE) is defined,
# define __USE_ATFILE 1
#endif
+#ifdef _SC_SIGSTKSZ_SOURCE
+# define __USE_SC_SIGSTKSZ 1
+#endif
+
#ifdef _GNU_SOURCE
# define __USE_GNU 1
#endif
@item _SC_NL_TEXTMAX
@standards{X/Open, unistd.h}
Inquire about the parameter corresponding to @code{NL_TEXTMAX}.
+
+@item _SC_MINSIGSTKSZ
+@standards{GNU, unistd.h}
+Inquire about the minimum number of bytes of free stack space required
+in order to guarantee successful, non-nested handling of a single signal
+whose handler is an empty function.
+
+@item _SC_SIGSTKSZ
+@standards{GNU, unistd.h}
+Inquire about the suggested minimum number of bytes of stack space
+required for a signal stack.
+
+This is not guaranteed to be enough for any specific purpose other than
+the invocation of a single, non-nested, empty handler, but nonetheless
+should be enough for basic scenarios involving simple signal handlers
+and very low levels of signal nesting (say, 2 or 3 levels at the very
+most).
+
+This value is provided for developer convenience and to ease migration
+from the legacy @code{SIGSTKSZ} constant. Programs requiring stronger
+guarantees should avoid using it if at all possible.
@end vtable
@node Examples of Sysconf
checks that may have an additional performance overhead.
@end defvr
+@defvr Macro _SC_SIGSTKSZ_SOURCE
+@standards{GNU, (none)}
+If this macro is defined, correct (but non compile-time constant)
+MINSIGSTKSZ and SIGSTKSZ are defined.
+@end defvr
+
@defvr Macro _REENTRANT
@defvrx Macro _THREAD_SAFE
@standards{Obsolete, (none)}
case _SC_XOPEN_REALTIME:
case _SC_XOPEN_REALTIME_THREADS:
+ case _SC_MINSIGSTKSZ:
+ case _SC_SIGSTKSZ:
+
break;
}
bits/types/sigevent_t.h bits/types/siginfo_t.h \
bits/types/sigset_t.h bits/types/sigval_t.h \
bits/types/stack_t.h bits/types/struct_sigstack.h \
- bits/types/__sigval_t.h bits/signal_ext.h
+ bits/types/__sigval_t.h bits/signal_ext.h \
+ bits/sigstksz.h
routines := signal raise killpg \
sigaction sigprocmask kill \
tests := tst-signal tst-sigset tst-sigsimple tst-raise tst-sigset2 \
tst-sigwait-eintr tst-sigaction \
tst-minsigstksz-1 tst-minsigstksz-2 tst-minsigstksz-3 \
- tst-minsigstksz-3a tst-minsigstksz-4 \
+ tst-minsigstksz-3a tst-minsigstksz-4 tst-minsigstksz-5 \
tst-sigisemptyset
include ../Rules
__attribute_deprecated_msg__ ("Use sigaction with SA_RESTART instead");
# include <bits/sigstack.h>
+# include <bits/sigstksz.h>
# include <bits/ss_flags.h>
/* Alternate signal handler stack interface.
--- /dev/null
+/* Test of signal delivery on an alternate stack with MINSIGSTKSZ size.
+ Copyright (C) 2020 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
+ <https://www.gnu.org/licenses/>. */
+
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <support/check.h>
+#include <support/support.h>
+
+static volatile sig_atomic_t handler_run;
+
+static void
+handler (int signo)
+{
+ /* Clear a bit of on-stack memory. */
+ volatile char buffer[256];
+ for (size_t i = 0; i < sizeof (buffer); ++i)
+ buffer[i] = 0;
+ handler_run = 1;
+}
+
+int
+do_test (void)
+{
+ size_t stack_buffer_size = 64 * 1024 * 1024;
+ void *stack_buffer = xmalloc (stack_buffer_size);
+ void *stack_end = stack_buffer + stack_buffer_size;
+ memset (stack_buffer, 0xCC, stack_buffer_size);
+
+ void *stack_bottom = stack_buffer + (stack_buffer_size + MINSIGSTKSZ) / 2;
+ void *stack_top = stack_bottom + MINSIGSTKSZ;
+ stack_t stack =
+ {
+ .ss_sp = stack_bottom,
+ .ss_size = MINSIGSTKSZ,
+ };
+ if (sigaltstack (&stack, NULL) < 0)
+ FAIL_RET ("sigaltstack: %m\n");
+
+ struct sigaction act =
+ {
+ .sa_handler = handler,
+ .sa_flags = SA_ONSTACK,
+ };
+ if (sigaction (SIGUSR1, &act, NULL) < 0)
+ FAIL_RET ("sigaction: %m\n");
+
+ if (kill (getpid (), SIGUSR1) < 0)
+ FAIL_RET ("kill: %m\n");
+
+ if (handler_run != 1)
+ FAIL_RET ("handler did not run\n");
+
+ for (void *p = stack_buffer; p < stack_bottom; ++p)
+ if (*(unsigned char *) p != 0xCC)
+ FAIL_RET ("changed byte %ld bytes below configured stack\n",
+ (long) (stack_bottom - p));
+ for (void *p = stack_top; p < stack_end; ++p)
+ if (*(unsigned char *) p != 0xCC)
+ FAIL_RET ("changed byte %ld bytes above configured stack\n",
+ (long) (p - stack_top));
+
+ free (stack_buffer);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
/* Cached value of `getpagesize ()'. */
EXTERN size_t _dl_pagesize;
+ /* Cached value of `sysconf (_SC_MINSIGSTKSZ)'. */
+ EXTERN size_t _dl_minsigstacksize;
+
/* Do we read from ld.so.cache? */
EXTERN int _dl_inhibit_cache;
--- /dev/null
+/* Definition of MINSIGSTKSZ and SIGSTKSZ. Linux version.
+ Copyright (C) 2020 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
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _SIGNAL_H
+# error "Never include <bits/sigstksz.h> directly; use <signal.h> instead."
+#endif
+
+#if defined __USE_SC_SIGSTKSZ && __USE_SC_SIGSTKSZ
+# include <unistd.h>
+
+/* Default stack size for a signal handler: sysconf (SC_SIGSTKSZ). */
+# undef SIGSTKSZ
+# define SIGSTKSZ sysconf (_SC_SIGSTKSZ)
+
+/* Minimum stack size for a signal handler: SIGSTKSZ. */
+# undef MINSIGSTKSZ
+# define MINSIGSTKSZ SIGSTKSZ
+#endif
--- /dev/null
+/* sysconf_sigstksz (). Linux/ia64 version.
+ Copyright (C) 2020 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
+ <https://www.gnu.org/licenses/>. */
+
+/* Return sysconf (_SC_SIGSTKSZ). */
+
+static long int
+sysconf_sigstksz (void)
+{
+ _Static_assert (__builtin_constant_p (SIGSTKSZ),
+ "SIGSTKSZ is constant");
+ return SIGSTKSZ;
+}
--- /dev/null
+/* sysconf_sigstksz (). Linux version.
+ Copyright (C) 2020 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
+ <https://www.gnu.org/licenses/>. */
+
+/* Return sysconf (_SC_SIGSTKSZ). */
+
+static long int
+sysconf_sigstksz (void)
+{
+ long int minsigstacksize = GLRO(dl_minsigstacksize);
+ assert (minsigstacksize != 0);
+ _Static_assert (__builtin_constant_p (MINSIGSTKSZ),
+ "MINSIGSTKSZ is constant");
+ if (minsigstacksize < MINSIGSTKSZ)
+ minsigstacksize = MINSIGSTKSZ;
+ /* MAX (MINSIGSTKSZ, sysconf (_SC_MINSIGSTKSZ)) * 4. */
+ long int sigstacksize = minsigstacksize * 4;
+ /* Return MAX (SIGSTKSZ, sigstacksize). */
+ _Static_assert (__builtin_constant_p (SIGSTKSZ),
+ "SIGSTKSZ is constant");
+ if (sigstacksize < SIGSTKSZ)
+ sigstacksize = SIGSTKSZ;
+ return sigstacksize;
+}
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/param.h>
#include <not-cancel.h>
#include <ldsodefs.h>
+#include <sysconf-sigstksz.h>
/* Legacy value of ARG_MAX. The macro is now not defined since the
actual value varies based on the stack size. */
}
break;
+ case _SC_MINSIGSTKSZ:
+ assert (GLRO(dl_minsigstacksize) != 0);
+ return GLRO(dl_minsigstacksize);
+
+ case _SC_SIGSTKSZ:
+ return sysconf_sigstksz ();
+
default:
break;
}
--- /dev/null
+/* Emulate AT_MINSIGSTKSZ. Linux/x86 version.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+
+ 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
+ <https://www.gnu.org/licenses/>. */
+
+/* Emulate AT_MINSIGSTKSZ with XSAVE. */
+
+static inline void
+dl_check_minsigstacksize (const struct cpu_features *cpu_features)
+{
+ /* Return if AT_MINSIGSTKSZ is provide by kernel. */
+ if (GLRO(dl_minsigstacksize) != 0)
+ return;
+
+ if (cpu_features->basic.max_cpuid >= 0xd
+ && CPU_FEATURES_CPU_P (cpu_features, OSXSAVE))
+ {
+ /* Emulate AT_MINSIGSTKSZ. In Linux kernel, the signal frame data
+ with XSAVE is composed of the following areas and laid out as:
+ ------------------------------
+ | alignment padding |
+ ------------------------------
+ | xsave buffer |
+ ------------------------------
+ | fsave header (32-bit only) |
+ ------------------------------
+ | siginfo + ucontext |
+ ------------------------------
+ */
+
+ unsigned int sigframe_size;
+
+#ifdef __x86_64__
+ /* NB: sizeof(struct rt_sigframe) + 8-byte return address in Linux
+ kernel. */
+ sigframe_size = 440 + 8;
+#else
+ /* NB: sizeof(struct sigframe_ia32) + sizeof(struct fregs_state)) +
+ 4-byte return address + 3 * 4-byte arguments in Linux kernel. */
+ sigframe_size = 736 + 112 + 4 + 3 * 4;
+#endif
+
+ /* Add 15 bytes to align the stack to 16 bytes. */
+ sigframe_size += 15;
+
+ /* Make the space before xsave buffer multiple of 16 bytes. */
+ sigframe_size = ALIGN_UP (sigframe_size, 16);
+
+ /* Add (64 - 16)-byte padding to align xsave buffer at 64 bytes. */
+ sigframe_size += 64 - 16;
+
+ unsigned int eax, ebx, ecx, edx;
+ __cpuid_count (0xd, 0, eax, ebx, ecx, edx);
+
+ /* Add the size of xsave buffer. */
+ sigframe_size += ebx;
+
+ /* Add the size of FP_XSTATE_MAGIC2. */
+#define FP_XSTATE_MAGIC2 0x46505845U
+ sigframe_size += sizeof (FP_XSTATE_MAGIC2);
+
+ GLRO(dl_minsigstacksize) = sigframe_size;
+ }
+ else
+ {
+ /* NB: Default to a constant MINSIGSTKSZ. */
+ _Static_assert (__builtin_constant_p (MINSIGSTKSZ),
+ "MINSIGSTKSZ is constant");
+ GLRO(dl_minsigstacksize) = MINSIGSTKSZ;
+ }
+}
--- /dev/null
+#include_next <bits/sigstack.h>
+
+#ifndef _ISOMAC
+# define CONSTANT_MINSIGSTKSZ 0
+#endif
#include <get-isa-level.h>
#include <cacheinfo.h>
#include <dl-cacheinfo.h>
+#include <dl-minsigstacksize.h>
#if HAVE_TUNABLES
extern void TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *)
cpu_features->features[CPUID_INDEX_19].cpuid.ebx,
cpu_features->features[CPUID_INDEX_19].cpuid.ecx,
cpu_features->features[CPUID_INDEX_19].cpuid.edx);
+
+ dl_check_minsigstacksize (cpu_features);
}
_Static_assert (((index_arch_Fast_Unaligned_Load
--- /dev/null
+/* Emulate AT_MINSIGSTKSZ. Generic x86 version.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+
+ 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
+ <https://www.gnu.org/licenses/>. */
+
+/* Emulate AT_MINSIGSTKSZ with XSAVE. */
+
+static inline void
+dl_check_minsigstacksize (const struct cpu_features *cpu_features)
+{
+ /* NB: Default to a constant MINSIGSTKSZ. */
+ _Static_assert (__builtin_constant_p (MINSIGSTKSZ),
+ "MINSIGSTKSZ is constant");
+ GLRO(dl_minsigstacksize) = MINSIGSTKSZ;
+}