* V10 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
@ 2021-01-25 13:53 H.J. Lu
2021-07-19 10:10 ` Andreas Schwab
2021-07-19 11:09 ` Andreas Schwab
0 siblings, 2 replies; 13+ messages in thread
From: H.J. Lu @ 2021-01-25 13:53 UTC (permalink / raw)
To: libc-alpha
Add _SC_MINSIGSTKSZ for the minimum signal stack size derived from
AT_MINSIGSTKSZ, which is the minimum number of bytes of free stack
space required in order to gurantee successful, non-nested handling
of a single signal whose handler is an empty function, and _SC_SIGSTKSZ
which is the suggested minimum number of bytes of stack space required
for a signal stack.
If AT_MINSIGSTKSZ isn't available, sysconf (_SC_MINSIGSTKSZ) returns
MINSIGSTKSZ. On Linux/x86 with XSAVE, the signal frame used by kernel
is composed of the following areas and laid out as:
------------------------------
| alignment padding |
------------------------------
| xsave buffer |
------------------------------
| fsave header (32-bit only) |
------------------------------
| siginfo + ucontext |
------------------------------
Compute AT_MINSIGSTKSZ value as size of xsave buffer + size of fsave
header (32-bit only) + size of siginfo and ucontext + alignment padding.
If _SC_SIGSTKSZ_SOURCE or _GNU_SOURCE are defined, MINSIGSTKSZ and SIGSTKSZ
are redefined as
/* 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
Compilation will fail if the source assumes constant MINSIGSTKSZ or
SIGSTKSZ.
The reason for not simply increasing the kernel's MINSIGSTKSZ #define
(apart from the fact that it is rarely used, due to glibc's shadowing
definitions) was that userspace binaries will have baked in the old
value of the constant and may be making assumptions about it.
For example, the type (char [MINSIGSTKSZ]) changes if this #define
changes. This could be a problem if an newly built library tries to
memcpy() or dump such an object defined by and old binary.
Bounds-checking and the stack sizes passed to things like sigaltstack()
and makecontext() could similarly go wrong.
---
NEWS | 5 ++
bits/confname.h | 8 +-
bits/sigstksz.h | 21 +++++
elf/dl-support.c | 5 ++
elf/dl-sysdep.c | 9 ++
include/bits/sigstack.h | 5 ++
include/bits/sigstksz.h | 7 ++
include/features.h | 11 +++
manual/conf.texi | 21 +++++
manual/creature.texi | 6 ++
posix/sysconf.c | 3 +
signal/Makefile | 5 +-
signal/signal.h | 1 +
signal/tst-minsigstksz-5.c | 84 +++++++++++++++++++
sysdeps/generic/ldsodefs.h | 3 +
sysdeps/unix/sysv/linux/bits/sigstksz.h | 33 ++++++++
.../unix/sysv/linux/ia64/sysconf-sigstksz.h | 27 ++++++
sysdeps/unix/sysv/linux/sysconf-sigstksz.h | 38 +++++++++
sysdeps/unix/sysv/linux/sysconf.c | 9 ++
.../unix/sysv/linux/x86/dl-minsigstacksize.h | 83 ++++++++++++++++++
.../sysv/linux/x86/include/bits/sigstack.h | 5 ++
sysdeps/x86/cpu-features.c | 3 +
sysdeps/x86/dl-minsigstacksize.h | 27 ++++++
23 files changed, 416 insertions(+), 3 deletions(-)
create mode 100644 bits/sigstksz.h
create mode 100644 include/bits/sigstack.h
create mode 100644 include/bits/sigstksz.h
create mode 100644 signal/tst-minsigstksz-5.c
create mode 100644 sysdeps/unix/sysv/linux/bits/sigstksz.h
create mode 100644 sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h
create mode 100644 sysdeps/unix/sysv/linux/sysconf-sigstksz.h
create mode 100644 sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h
create mode 100644 sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h
create mode 100644 sysdeps/x86/dl-minsigstacksize.h
diff --git a/NEWS b/NEWS
index d121f7df87..0758bb37e3 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,11 @@ Version 2.33
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).
diff --git a/bits/confname.h b/bits/confname.h
index 8068bda273..ec6cd07957 100644
--- a/bits/confname.h
+++ b/bits/confname.h
@@ -525,8 +525,14 @@ enum
_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'. */
diff --git a/bits/sigstksz.h b/bits/sigstksz.h
new file mode 100644
index 0000000000..5535d873b5
--- /dev/null
+++ b/bits/sigstksz.h
@@ -0,0 +1,21 @@
+/* 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
diff --git a/elf/dl-support.c b/elf/dl-support.c
index 7abb65d8e3..7fc2ee78e2 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -142,6 +142,8 @@ void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
size_t _dl_pagesize = EXEC_PAGESIZE;
+size_t _dl_minsigstacksize = CONSTANT_MINSIGSTKSZ;
+
int _dl_inhibit_cache;
unsigned int _dl_osversion;
@@ -307,6 +309,9 @@ _dl_aux_init (ElfW(auxv_t) *av)
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)
diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c
index 0658c17da6..bd5066fe3b 100644
--- a/elf/dl-sysdep.c
+++ b/elf/dl-sysdep.c
@@ -115,6 +115,11 @@ _dl_sysdep_start (void **start_argptr,
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)
{
@@ -179,6 +184,9 @@ _dl_sysdep_start (void **start_argptr,
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
}
@@ -306,6 +314,7 @@ _dl_show_auxv (void)
[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 },
diff --git a/include/bits/sigstack.h b/include/bits/sigstack.h
new file mode 100644
index 0000000000..eea939f59d
--- /dev/null
+++ b/include/bits/sigstack.h
@@ -0,0 +1,5 @@
+#include_next <bits/sigstack.h>
+
+#if !defined _ISOMAC && !defined CONSTANT_MINSIGSTKSZ
+# define CONSTANT_MINSIGSTKSZ MINSIGSTKSZ
+#endif
diff --git a/include/bits/sigstksz.h b/include/bits/sigstksz.h
new file mode 100644
index 0000000000..2ca891e918
--- /dev/null
+++ b/include/bits/sigstksz.h
@@ -0,0 +1,7 @@
+/* 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
diff --git a/include/features.h b/include/features.h
index a71ac85af4..cc05a31ae1 100644
--- a/include/features.h
+++ b/include/features.h
@@ -48,6 +48,8 @@
_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__).
@@ -94,6 +96,8 @@
__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.
@@ -137,6 +141,7 @@
#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
@@ -213,6 +218,8 @@
# 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,
@@ -388,6 +395,10 @@
# define __USE_ATFILE 1
#endif
+#ifdef _SC_SIGSTKSZ_SOURCE
+# define __USE_SC_SIGSTKSZ 1
+#endif
+
#ifdef _GNU_SOURCE
# define __USE_GNU 1
#endif
diff --git a/manual/conf.texi b/manual/conf.texi
index f959b00bb6..ba9847aaa4 100644
--- a/manual/conf.texi
+++ b/manual/conf.texi
@@ -913,6 +913,27 @@ Inquire about the parameter corresponding to @code{NL_SETMAX}.
@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
diff --git a/manual/creature.texi b/manual/creature.texi
index 31208ccb2b..5090735e4f 100644
--- a/manual/creature.texi
+++ b/manual/creature.texi
@@ -258,6 +258,12 @@ checks are applied. If defined to @math{3}, @theglibc{} may also use
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)}
diff --git a/posix/sysconf.c b/posix/sysconf.c
index bb9e132e5c..67d17ca0f8 100644
--- a/posix/sysconf.c
+++ b/posix/sysconf.c
@@ -266,6 +266,9 @@ __sysconf (int name)
case _SC_XOPEN_REALTIME:
case _SC_XOPEN_REALTIME_THREADS:
+ case _SC_MINSIGSTKSZ:
+ case _SC_SIGSTKSZ:
+
break;
}
diff --git a/signal/Makefile b/signal/Makefile
index e89c308889..3d8cab1f50 100644
--- a/signal/Makefile
+++ b/signal/Makefile
@@ -31,7 +31,8 @@ headers := signal.h sys/signal.h \
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 \
@@ -48,7 +49,7 @@ routines := signal raise killpg \
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
diff --git a/signal/signal.h b/signal/signal.h
index 6463c98e11..b17203c99c 100644
--- a/signal/signal.h
+++ b/signal/signal.h
@@ -312,6 +312,7 @@ extern int siginterrupt (int __sig, int __interrupt) __THROW
__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.
diff --git a/signal/tst-minsigstksz-5.c b/signal/tst-minsigstksz-5.c
new file mode 100644
index 0000000000..d657d2f4e6
--- /dev/null
+++ b/signal/tst-minsigstksz-5.c
@@ -0,0 +1,84 @@
+/* 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>
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index aab7245e93..9720a4e446 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -536,6 +536,9 @@ struct rtld_global_ro
/* 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;
diff --git a/sysdeps/unix/sysv/linux/bits/sigstksz.h b/sysdeps/unix/sysv/linux/bits/sigstksz.h
new file mode 100644
index 0000000000..926508f2b4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/bits/sigstksz.h
@@ -0,0 +1,33 @@
+/* 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
diff --git a/sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h b/sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h
new file mode 100644
index 0000000000..7e5ceba151
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h
@@ -0,0 +1,27 @@
+/* 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;
+}
diff --git a/sysdeps/unix/sysv/linux/sysconf-sigstksz.h b/sysdeps/unix/sysv/linux/sysconf-sigstksz.h
new file mode 100644
index 0000000000..64d450b22c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sysconf-sigstksz.h
@@ -0,0 +1,38 @@
+/* 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;
+}
diff --git a/sysdeps/unix/sysv/linux/sysconf.c b/sysdeps/unix/sysv/linux/sysconf.c
index bfad5b6858..366fcef01e 100644
--- a/sysdeps/unix/sysv/linux/sysconf.c
+++ b/sysdeps/unix/sysv/linux/sysconf.c
@@ -16,6 +16,7 @@
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>
@@ -26,6 +27,7 @@
#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. */
@@ -75,6 +77,13 @@ __sysconf (int name)
}
break;
+ case _SC_MINSIGSTKSZ:
+ assert (GLRO(dl_minsigstacksize) != 0);
+ return GLRO(dl_minsigstacksize);
+
+ case _SC_SIGSTKSZ:
+ return sysconf_sigstksz ();
+
default:
break;
}
diff --git a/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h b/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h
new file mode 100644
index 0000000000..6088bbc99e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h
@@ -0,0 +1,83 @@
+/* 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;
+ }
+}
diff --git a/sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h b/sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h
new file mode 100644
index 0000000000..208754c497
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h
@@ -0,0 +1,5 @@
+#include_next <bits/sigstack.h>
+
+#ifndef _ISOMAC
+# define CONSTANT_MINSIGSTKSZ 0
+#endif
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
index 6496512a0d..dfeca31967 100644
--- a/sysdeps/x86/cpu-features.c
+++ b/sysdeps/x86/cpu-features.c
@@ -21,6 +21,7 @@
#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 *)
@@ -362,6 +363,8 @@ get_common_indices (struct cpu_features *cpu_features,
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
diff --git a/sysdeps/x86/dl-minsigstacksize.h b/sysdeps/x86/dl-minsigstacksize.h
new file mode 100644
index 0000000000..959871c970
--- /dev/null
+++ b/sysdeps/x86/dl-minsigstacksize.h
@@ -0,0 +1,27 @@
+/* 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;
+}
--
2.29.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PING: V7 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
@ 2020-11-04 16:50 Dave Martin
2020-11-04 17:48 ` H.J. Lu
0 siblings, 1 reply; 13+ messages in thread
From: Dave Martin @ 2020-11-04 16:50 UTC (permalink / raw)
To: H.J. Lu; +Cc: GNU C Library, Joseph Myers
On Mon, Nov 02, 2020 at 07:06:13PM -0800, H.J. Lu via Libc-alpha wrote:
> On Tue, Oct 20, 2020 at 11:19 AM H.J. Lu <hjl.tools@gmail.com> wrote:
> >
> > On Tue, Oct 20, 2020 at 7:59 AM H.J. Lu <hjl.tools@gmail.com> wrote:
> > >
> > > On Tue, Oct 20, 2020 at 2:19 AM Dave Martin <Dave.Martin@arm.com> wrote:
> > > >
> > > > On Mon, Oct 19, 2020 at 02:32:35PM -0700, H.J. Lu via Libc-alpha wrote:
> > > > > On Mon, Oct 19, 2020 at 8:08 AM Dave Martin <Dave.Martin@arm.com> wrote:
> > > > > >
> > > > > > On Thu, Oct 15, 2020 at 04:57:28AM -0700, H.J. Lu via Libc-alpha wrote:
> > > >
> > > > [...]
> > > >
> > > > > > > > > diff --git a/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h b/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h
> > > >
> > > > [...]
> > > >
> > > > > > > > > +/* Emulate AT_MINSIGSTKSZ with XSAVE. */
> > > > > > > > > +
> > > > > > > > > +static inline void
> > > > > > > > > +dl_check_minsigstacksize (void)
> > > > > > > > > +{
> > > > > > > > > + /* NB: Default to a constant MINSIGSTKSZ. */
> > > > > > > > > + _Static_assert (__builtin_constant_p (MINSIGSTKSZ),
> > > > > > > > > + "MINSIGSTKSZ is constant");
> > > > > > > > > + /* Return if AT_MINSIGSTKSZ is provide by kernel. */
> > > > > > > > > + if (GLRO(dl_minsigstacksize) != MINSIGSTKSZ)
> > > > > > > > > + return;
> > > > > > > >
> > > > > > > > Couldn't the kernel actually yield MINSIGSTKSZ or a smaller value, say,
> > > > > > > > if running on hardware that doesn't have AVX-512?
> > > > > > > >
> > > > > > > It is OK for MINSIGSTKSZ > AT_MINSIGSTKSZ. For _SC_SIGSTKSZ_SOURCE,
> > > > > > > dynamic MINSIGSTKSZ is defined as sysconf (_SC_SIGSTKSZ) which is
> > > > > > >
> > > > > > > MAX (SIGSTKSZ, MAX (MINSIGSTKSZ, sysconf (_SC_MINSIGSTKSZ)) * 4)
> > > > > > >
> > > > > > > and dynamic MINSIGSTKSZ is always > MINSIGSTKSZ.
> > > > > > >
> > > > > > > > We might want a separate flag to indicate whether we obtained a value
> > > > > > > > from the auxv, rather relying on MINSIGSTKSZ having this magic meaning.
> > > > > > >
> > > > > > > AT_MINSIGSTKSZ is the only way for GLRO(dl_minsigstacksize) != MINSIGSTKSZ.
> > > > > >
> > > > > > Yes, but reading AT_MINSIGSTKSZ doesn't guarantee that
> > > > > > GLRO(dl_minsigstkszsize) != MINSIGSTKSZ, no?
> > > > > >
> > > > > > What if the value reported for AT_MINSIGSTKSZ is actually the same as
> > > > > > MINSIGSTKSZ? This could be the case on some arches in future even if
> > > > > > it's never true today. But the code here assumes that AT_MINSIGSTKSZ
> > > > > > wasn't available in this case, and reverts to a fallback guess.
> > > > >
> > > > > Since the fallback tracks what the kernel does, if AT_MINSIGSTKSZ
> > > > > is 2KB, the fallback will be 2KB or slightly larger.
> > > >
> > > > Well, I guess that should be safe. It still feels a bit like it works
> > > > by accident, but I may be being too paranoid.
> > >
> > > Let me work on that.
> > >
> >
> > Here is the updated patch to initialize GLRO(dl_minsigstacksize)
> > to 0 on x86.
> >
>
> PING:
>
> https://sourceware.org/pipermail/libc-alpha/2020-October/118843.html
Because the signal context doesn't actually fit in mcontext_t any more
(or, recursively, in ucontext_t), it would make sense to amend some of
the ucontext-related functions at the same time, and force people
towards this updated interface when building with _SC_SIGSTKSZ_SOURCE.
I'm aiming to get a draft proposal onto the list next week, if people
can wait for that before deciding whether the two sets of changes should
be coupled...
Cheers
---Dave
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PING: V7 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
2020-11-04 16:50 PING: V7 " Dave Martin
@ 2020-11-04 17:48 ` H.J. Lu
2020-11-18 14:13 ` H.J. Lu
0 siblings, 1 reply; 13+ messages in thread
From: H.J. Lu @ 2020-11-04 17:48 UTC (permalink / raw)
To: Dave Martin; +Cc: GNU C Library, Joseph Myers
On Wed, Nov 4, 2020 at 8:50 AM Dave Martin <Dave.Martin@arm.com> wrote:
>
> On Mon, Nov 02, 2020 at 07:06:13PM -0800, H.J. Lu via Libc-alpha wrote:
> > On Tue, Oct 20, 2020 at 11:19 AM H.J. Lu <hjl.tools@gmail.com> wrote:
> > >
> > > On Tue, Oct 20, 2020 at 7:59 AM H.J. Lu <hjl.tools@gmail.com> wrote:
> > > >
> > > > On Tue, Oct 20, 2020 at 2:19 AM Dave Martin <Dave.Martin@arm.com> wrote:
> > > > >
> > > > > On Mon, Oct 19, 2020 at 02:32:35PM -0700, H.J. Lu via Libc-alpha wrote:
> > > > > > On Mon, Oct 19, 2020 at 8:08 AM Dave Martin <Dave.Martin@arm.com> wrote:
> > > > > > >
> > > > > > > On Thu, Oct 15, 2020 at 04:57:28AM -0700, H.J. Lu via Libc-alpha wrote:
> > > > >
> > > > > [...]
> > > > >
> > > > > > > > > > diff --git a/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h b/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h
> > > > >
> > > > > [...]
> > > > >
> > > > > > > > > > +/* Emulate AT_MINSIGSTKSZ with XSAVE. */
> > > > > > > > > > +
> > > > > > > > > > +static inline void
> > > > > > > > > > +dl_check_minsigstacksize (void)
> > > > > > > > > > +{
> > > > > > > > > > + /* NB: Default to a constant MINSIGSTKSZ. */
> > > > > > > > > > + _Static_assert (__builtin_constant_p (MINSIGSTKSZ),
> > > > > > > > > > + "MINSIGSTKSZ is constant");
> > > > > > > > > > + /* Return if AT_MINSIGSTKSZ is provide by kernel. */
> > > > > > > > > > + if (GLRO(dl_minsigstacksize) != MINSIGSTKSZ)
> > > > > > > > > > + return;
> > > > > > > > >
> > > > > > > > > Couldn't the kernel actually yield MINSIGSTKSZ or a smaller value, say,
> > > > > > > > > if running on hardware that doesn't have AVX-512?
> > > > > > > > >
> > > > > > > > It is OK for MINSIGSTKSZ > AT_MINSIGSTKSZ. For _SC_SIGSTKSZ_SOURCE,
> > > > > > > > dynamic MINSIGSTKSZ is defined as sysconf (_SC_SIGSTKSZ) which is
> > > > > > > >
> > > > > > > > MAX (SIGSTKSZ, MAX (MINSIGSTKSZ, sysconf (_SC_MINSIGSTKSZ)) * 4)
> > > > > > > >
> > > > > > > > and dynamic MINSIGSTKSZ is always > MINSIGSTKSZ.
> > > > > > > >
> > > > > > > > > We might want a separate flag to indicate whether we obtained a value
> > > > > > > > > from the auxv, rather relying on MINSIGSTKSZ having this magic meaning.
> > > > > > > >
> > > > > > > > AT_MINSIGSTKSZ is the only way for GLRO(dl_minsigstacksize) != MINSIGSTKSZ.
> > > > > > >
> > > > > > > Yes, but reading AT_MINSIGSTKSZ doesn't guarantee that
> > > > > > > GLRO(dl_minsigstkszsize) != MINSIGSTKSZ, no?
> > > > > > >
> > > > > > > What if the value reported for AT_MINSIGSTKSZ is actually the same as
> > > > > > > MINSIGSTKSZ? This could be the case on some arches in future even if
> > > > > > > it's never true today. But the code here assumes that AT_MINSIGSTKSZ
> > > > > > > wasn't available in this case, and reverts to a fallback guess.
> > > > > >
> > > > > > Since the fallback tracks what the kernel does, if AT_MINSIGSTKSZ
> > > > > > is 2KB, the fallback will be 2KB or slightly larger.
> > > > >
> > > > > Well, I guess that should be safe. It still feels a bit like it works
> > > > > by accident, but I may be being too paranoid.
> > > >
> > > > Let me work on that.
> > > >
> > >
> > > Here is the updated patch to initialize GLRO(dl_minsigstacksize)
> > > to 0 on x86.
> > >
> >
> > PING:
> >
> > https://sourceware.org/pipermail/libc-alpha/2020-October/118843.html
>
> Because the signal context doesn't actually fit in mcontext_t any more
> (or, recursively, in ucontext_t), it would make sense to amend some of
> the ucontext-related functions at the same time, and force people
> towards this updated interface when building with _SC_SIGSTKSZ_SOURCE.
That may be useful.
> I'm aiming to get a draft proposal onto the list next week, if people
> can wait for that before deciding whether the two sets of changes should
> be coupled...
>
Thanks.
--
H.J.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PING: V7 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
2020-11-04 17:48 ` H.J. Lu
@ 2020-11-18 14:13 ` H.J. Lu
2020-11-18 14:25 ` Zack Weinberg
0 siblings, 1 reply; 13+ messages in thread
From: H.J. Lu @ 2020-11-18 14:13 UTC (permalink / raw)
To: Dave Martin; +Cc: GNU C Library, Joseph Myers
On Wed, Nov 4, 2020 at 9:48 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Wed, Nov 4, 2020 at 8:50 AM Dave Martin <Dave.Martin@arm.com> wrote:
> >
> > On Mon, Nov 02, 2020 at 07:06:13PM -0800, H.J. Lu via Libc-alpha wrote:
> > > On Tue, Oct 20, 2020 at 11:19 AM H.J. Lu <hjl.tools@gmail.com> wrote:
> > > >
> > > > On Tue, Oct 20, 2020 at 7:59 AM H.J. Lu <hjl.tools@gmail.com> wrote:
> > > > >
> > > > > On Tue, Oct 20, 2020 at 2:19 AM Dave Martin <Dave.Martin@arm.com> wrote:
> > > > > >
> > > > > > On Mon, Oct 19, 2020 at 02:32:35PM -0700, H.J. Lu via Libc-alpha wrote:
> > > > > > > On Mon, Oct 19, 2020 at 8:08 AM Dave Martin <Dave.Martin@arm.com> wrote:
> > > > > > > >
> > > > > > > > On Thu, Oct 15, 2020 at 04:57:28AM -0700, H.J. Lu via Libc-alpha wrote:
> > > > > >
> > > > > > [...]
> > > > > >
> > > > > > > > > > > diff --git a/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h b/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h
> > > > > >
> > > > > > [...]
> > > > > >
> > > > > > > > > > > +/* Emulate AT_MINSIGSTKSZ with XSAVE. */
> > > > > > > > > > > +
> > > > > > > > > > > +static inline void
> > > > > > > > > > > +dl_check_minsigstacksize (void)
> > > > > > > > > > > +{
> > > > > > > > > > > + /* NB: Default to a constant MINSIGSTKSZ. */
> > > > > > > > > > > + _Static_assert (__builtin_constant_p (MINSIGSTKSZ),
> > > > > > > > > > > + "MINSIGSTKSZ is constant");
> > > > > > > > > > > + /* Return if AT_MINSIGSTKSZ is provide by kernel. */
> > > > > > > > > > > + if (GLRO(dl_minsigstacksize) != MINSIGSTKSZ)
> > > > > > > > > > > + return;
> > > > > > > > > >
> > > > > > > > > > Couldn't the kernel actually yield MINSIGSTKSZ or a smaller value, say,
> > > > > > > > > > if running on hardware that doesn't have AVX-512?
> > > > > > > > > >
> > > > > > > > > It is OK for MINSIGSTKSZ > AT_MINSIGSTKSZ. For _SC_SIGSTKSZ_SOURCE,
> > > > > > > > > dynamic MINSIGSTKSZ is defined as sysconf (_SC_SIGSTKSZ) which is
> > > > > > > > >
> > > > > > > > > MAX (SIGSTKSZ, MAX (MINSIGSTKSZ, sysconf (_SC_MINSIGSTKSZ)) * 4)
> > > > > > > > >
> > > > > > > > > and dynamic MINSIGSTKSZ is always > MINSIGSTKSZ.
> > > > > > > > >
> > > > > > > > > > We might want a separate flag to indicate whether we obtained a value
> > > > > > > > > > from the auxv, rather relying on MINSIGSTKSZ having this magic meaning.
> > > > > > > > >
> > > > > > > > > AT_MINSIGSTKSZ is the only way for GLRO(dl_minsigstacksize) != MINSIGSTKSZ.
> > > > > > > >
> > > > > > > > Yes, but reading AT_MINSIGSTKSZ doesn't guarantee that
> > > > > > > > GLRO(dl_minsigstkszsize) != MINSIGSTKSZ, no?
> > > > > > > >
> > > > > > > > What if the value reported for AT_MINSIGSTKSZ is actually the same as
> > > > > > > > MINSIGSTKSZ? This could be the case on some arches in future even if
> > > > > > > > it's never true today. But the code here assumes that AT_MINSIGSTKSZ
> > > > > > > > wasn't available in this case, and reverts to a fallback guess.
> > > > > > >
> > > > > > > Since the fallback tracks what the kernel does, if AT_MINSIGSTKSZ
> > > > > > > is 2KB, the fallback will be 2KB or slightly larger.
> > > > > >
> > > > > > Well, I guess that should be safe. It still feels a bit like it works
> > > > > > by accident, but I may be being too paranoid.
> > > > >
> > > > > Let me work on that.
> > > > >
> > > >
> > > > Here is the updated patch to initialize GLRO(dl_minsigstacksize)
> > > > to 0 on x86.
> > > >
> > >
> > > PING:
> > >
> > > https://sourceware.org/pipermail/libc-alpha/2020-October/118843.html
> >
> > Because the signal context doesn't actually fit in mcontext_t any more
> > (or, recursively, in ucontext_t), it would make sense to amend some of
> > the ucontext-related functions at the same time, and force people
> > towards this updated interface when building with _SC_SIGSTKSZ_SOURCE.
>
> That may be useful.
>
> > I'm aiming to get a draft proposal onto the list next week, if people
> > can wait for that before deciding whether the two sets of changes should
> > be coupled...
> >
>
> Thanks.
If there are no more comments, I will check in it together with
https://sourceware.org/pipermail/libc-alpha/2020-October/118707.html
on Friday, Nov 20.
Thanks.
--
H.J.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PING: V7 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
2020-11-18 14:13 ` H.J. Lu
@ 2020-11-18 14:25 ` Zack Weinberg
2020-11-18 14:40 ` H.J. Lu
0 siblings, 1 reply; 13+ messages in thread
From: Zack Weinberg @ 2020-11-18 14:25 UTC (permalink / raw)
To: H.J. Lu; +Cc: Dave Martin, GNU C Library, Joseph Myers
On Wed, Nov 18, 2020 at 9:14 AM H.J. Lu via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
> If there are no more comments, I will check in it together with
>
> https://sourceware.org/pipermail/libc-alpha/2020-October/118707.html
>
> on Friday, Nov 20.
I don't think you have consensus for this ABI-breaking change, and I
*certainly* don't think you should check it in without positive
agreement from at least one other person.
zw
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PING: V7 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
2020-11-18 14:25 ` Zack Weinberg
@ 2020-11-18 14:40 ` H.J. Lu
2020-11-18 15:12 ` Zack Weinberg
0 siblings, 1 reply; 13+ messages in thread
From: H.J. Lu @ 2020-11-18 14:40 UTC (permalink / raw)
To: Zack Weinberg; +Cc: Dave Martin, GNU C Library, Joseph Myers
On Wed, Nov 18, 2020 at 6:26 AM Zack Weinberg <zackw@panix.com> wrote:
>
> On Wed, Nov 18, 2020 at 9:14 AM H.J. Lu via Libc-alpha
> <libc-alpha@sourceware.org> wrote:
> >
> > If there are no more comments, I will check in it together with
> >
> > https://sourceware.org/pipermail/libc-alpha/2020-October/118707.html
> >
> > on Friday, Nov 20.
>
> I don't think you have consensus for this ABI-breaking change, and I
> *certainly* don't think you should check it in without positive
> agreement from at least one other person.
>
My patch adds _SC_SIGSTKSZ_SOURCE. There are no changes
unless _SC_SIGSTKSZ_SOURCE is defined.
Dave, what do you think?
--
H.J.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PING: V7 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
2020-11-18 14:40 ` H.J. Lu
@ 2020-11-18 15:12 ` Zack Weinberg
2020-11-18 15:17 ` H.J. Lu
0 siblings, 1 reply; 13+ messages in thread
From: Zack Weinberg @ 2020-11-18 15:12 UTC (permalink / raw)
To: H.J. Lu; +Cc: Dave Martin, GNU C Library, Joseph Myers
On Wed, Nov 18, 2020 at 9:40 AM H.J. Lu <hjl.tools@gmail.com> wrote:
> On Wed, Nov 18, 2020 at 6:26 AM Zack Weinberg <zackw@panix.com> wrote:
> >
> > On Wed, Nov 18, 2020 at 9:14 AM H.J. Lu via Libc-alpha
> > <libc-alpha@sourceware.org> wrote:
> > >
> > > If there are no more comments, I will check in it together with
> > >
> > > https://sourceware.org/pipermail/libc-alpha/2020-October/118707.html
> > >
> > > on Friday, Nov 20.
> >
> > I don't think you have consensus for this ABI-breaking change, and I
> > *certainly* don't think you should check it in without positive
> > agreement from at least one other person.
> >
>
> My patch adds _SC_SIGSTKSZ_SOURCE. There are no changes
> unless _SC_SIGSTKSZ_SOURCE is defined.
OK, but do we have consensus on adding a new _*_SOURCE macro and a new
sysconf parameter ahead of their adoption by POSIX? This is not a
rhetorical question, I have not been following that part of the
discussion closely enough to tell.
zw
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PING: V7 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
2020-11-18 15:12 ` Zack Weinberg
@ 2020-11-18 15:17 ` H.J. Lu
2020-11-18 15:20 ` Florian Weimer
0 siblings, 1 reply; 13+ messages in thread
From: H.J. Lu @ 2020-11-18 15:17 UTC (permalink / raw)
To: Zack Weinberg; +Cc: Dave Martin, GNU C Library, Joseph Myers
On Wed, Nov 18, 2020 at 7:13 AM Zack Weinberg <zackw@panix.com> wrote:
>
> On Wed, Nov 18, 2020 at 9:40 AM H.J. Lu <hjl.tools@gmail.com> wrote:
> > On Wed, Nov 18, 2020 at 6:26 AM Zack Weinberg <zackw@panix.com> wrote:
> > >
> > > On Wed, Nov 18, 2020 at 9:14 AM H.J. Lu via Libc-alpha
> > > <libc-alpha@sourceware.org> wrote:
> > > >
> > > > If there are no more comments, I will check in it together with
> > > >
> > > > https://sourceware.org/pipermail/libc-alpha/2020-October/118707.html
> > > >
> > > > on Friday, Nov 20.
> > >
> > > I don't think you have consensus for this ABI-breaking change, and I
> > > *certainly* don't think you should check it in without positive
> > > agreement from at least one other person.
> > >
> >
> > My patch adds _SC_SIGSTKSZ_SOURCE. There are no changes
> > unless _SC_SIGSTKSZ_SOURCE is defined.
>
> OK, but do we have consensus on adding a new _*_SOURCE macro and a new
> sysconf parameter ahead of their adoption by POSIX? This is not a
This is what Dave and I came up with. This approach doesn't change ABI
unless it is requested by developers.
> rhetorical question, I have not been following that part of the
> discussion closely enough to tell.
>
> zw
--
H.J.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PING: V7 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
2020-11-18 15:17 ` H.J. Lu
@ 2020-11-18 15:20 ` Florian Weimer
2020-11-18 17:04 ` Dave Martin
0 siblings, 1 reply; 13+ messages in thread
From: Florian Weimer @ 2020-11-18 15:20 UTC (permalink / raw)
To: H.J. Lu via Libc-alpha; +Cc: Zack Weinberg, H.J. Lu, Dave Martin, Joseph Myers
* H. J. Lu via Libc-alpha:
> On Wed, Nov 18, 2020 at 7:13 AM Zack Weinberg <zackw@panix.com> wrote:
>>
>> On Wed, Nov 18, 2020 at 9:40 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>> > On Wed, Nov 18, 2020 at 6:26 AM Zack Weinberg <zackw@panix.com> wrote:
>> > >
>> > > On Wed, Nov 18, 2020 at 9:14 AM H.J. Lu via Libc-alpha
>> > > <libc-alpha@sourceware.org> wrote:
>> > > >
>> > > > If there are no more comments, I will check in it together with
>> > > >
>> > > > https://sourceware.org/pipermail/libc-alpha/2020-October/118707.html
>> > > >
>> > > > on Friday, Nov 20.
>> > >
>> > > I don't think you have consensus for this ABI-breaking change, and I
>> > > *certainly* don't think you should check it in without positive
>> > > agreement from at least one other person.
>> > >
>> >
>> > My patch adds _SC_SIGSTKSZ_SOURCE. There are no changes
>> > unless _SC_SIGSTKSZ_SOURCE is defined.
>>
>> OK, but do we have consensus on adding a new _*_SOURCE macro and a new
>> sysconf parameter ahead of their adoption by POSIX? This is not a
>
> This is what Dave and I came up with. This approach doesn't change ABI
> unless it is requested by developers.
Did you mean ABI?
I think we should use _GNU_SOURCE. We can add another feature macro if
it's adopted by POSIX.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PING: V7 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
2020-11-18 15:20 ` Florian Weimer
@ 2020-11-18 17:04 ` Dave Martin
2020-11-18 17:35 ` Florian Weimer
0 siblings, 1 reply; 13+ messages in thread
From: Dave Martin @ 2020-11-18 17:04 UTC (permalink / raw)
To: Florian Weimer; +Cc: H.J. Lu via Libc-alpha, Joseph Myers
On Wed, Nov 18, 2020 at 04:20:44PM +0100, Florian Weimer wrote:
> * H. J. Lu via Libc-alpha:
>
> > On Wed, Nov 18, 2020 at 7:13 AM Zack Weinberg <zackw@panix.com> wrote:
> >>
> >> On Wed, Nov 18, 2020 at 9:40 AM H.J. Lu <hjl.tools@gmail.com> wrote:
> >> > On Wed, Nov 18, 2020 at 6:26 AM Zack Weinberg <zackw@panix.com> wrote:
> >> > >
> >> > > On Wed, Nov 18, 2020 at 9:14 AM H.J. Lu via Libc-alpha
> >> > > <libc-alpha@sourceware.org> wrote:
> >> > > >
> >> > > > If there are no more comments, I will check in it together with
> >> > > >
> >> > > > https://sourceware.org/pipermail/libc-alpha/2020-October/118707.html
> >> > > >
> >> > > > on Friday, Nov 20.
> >> > >
> >> > > I don't think you have consensus for this ABI-breaking change, and I
> >> > > *certainly* don't think you should check it in without positive
> >> > > agreement from at least one other person.
> >> > >
> >> >
> >> > My patch adds _SC_SIGSTKSZ_SOURCE. There are no changes
> >> > unless _SC_SIGSTKSZ_SOURCE is defined.
> >>
> >> OK, but do we have consensus on adding a new _*_SOURCE macro and a new
> >> sysconf parameter ahead of their adoption by POSIX? This is not a
> >
> > This is what Dave and I came up with. This approach doesn't change ABI
> > unless it is requested by developers.
>
> Did you mean ABI?
>
> I think we should use _GNU_SOURCE. We can add another feature macro if
> it's adopted by POSIX.
Having _GNU_SOURCE enable this feature will break existing source code.
It probably should go under _GNU_SOURCE in the long term, but is there
usually a transitional period when the change is opt-in via some feature
macro?
Otherwise, it feels like we would have a chicken-and-egg problem, with
nobody wanting to be the first adopter.
And also, what, if anything, should be done about the ucontext API?
The signal frame on a couple of arches now overruns the original
mcontext_t definition.
Ucontext seems to be in quite a broken state and is hard to fix because
of the lack of extensibility in the design. Signals have also diverged
from setcontext() etc. -- some arches don't even encode the same data in
there, or put things in the same places between the two APIs.
I have some thoughts on what a better interface might look like --
basically separating the signal ucontext_t type from the setcontext()/
getcontext() etc. type, and providing accessors for the architectural
register state rather than just having a fixed struct definition for
mcontext_t.
But, there also may not be a lot of appetite for such a change, and
I can't see how it could be backwards compatible.
I can elaborate if people think it's worth discussing.
Cheers
---Dave
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PING: V7 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
2020-11-18 17:04 ` Dave Martin
@ 2020-11-18 17:35 ` Florian Weimer
2020-11-18 18:09 ` Dave Martin
0 siblings, 1 reply; 13+ messages in thread
From: Florian Weimer @ 2020-11-18 17:35 UTC (permalink / raw)
To: Dave Martin; +Cc: H.J. Lu via Libc-alpha, Joseph Myers
* Dave Martin:
> Having _GNU_SOURCE enable this feature will break existing source code.
Does this matter?
The code is already broken on a quickly increasing number of machines,
so it needs fixing anyway. A compile-time error is probably
preferable to an obscure run-time failure.
> It probably should go under _GNU_SOURCE in the long term, but is there
> usually a transitional period when the change is opt-in via some feature
> macro?
Not always. See the iszero and other macros in <math.h>, that also
broke existing sources (largely C++, so we worked around it by using
C++ features instead of macros). There are also many older examples.
> I have some thoughts on what a better interface might look like --
> basically separating the signal ucontext_t type from the setcontext()/
> getcontext() etc. type, and providing accessors for the architectural
> register state rather than just having a fixed struct definition for
> mcontext_t.
>
> But, there also may not be a lot of appetite for such a change, and
> I can't see how it could be backwards compatible.
>
> I can elaborate if people think it's worth discussing.
I think Rich Felker wants to copy signal contexts around to implement
critical sections that can't be interrupted by a signal handler, I
think that would need this fully fixed.
But this is somewhat separate from fixing stack sizes to accomodate
kernel and hardware needs.
By the way, something that I tried to raise in the past, but wasn't
good at it: In the future, we may need a mechanism to reduce the
kernel stack size usage for legacy binaries, perhaps using
virtualization. The last time I looked at this, the signal context
did not actually reduce when AVX-512 support was masked in a guest, I
think. (Okay, this is largely for H.J.'s benefit.) This also applies
to ld.so and its context save operation. Fortunately, not many people
have run into this compatibility issue so far. The case I remember
was an application that broke because it assumed zeros on the stack,
and the XSAVE trampoline wrote some non-zero bits there because it
reached much deeper into the stack. But the user was happy when we
found the root cause and was able to add the missing initializer to
their code, so all was good.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PING: V7 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
2020-11-18 17:35 ` Florian Weimer
@ 2020-11-18 18:09 ` Dave Martin
2020-11-20 14:08 ` H.J. Lu
0 siblings, 1 reply; 13+ messages in thread
From: Dave Martin @ 2020-11-18 18:09 UTC (permalink / raw)
To: Florian Weimer; +Cc: H.J. Lu via Libc-alpha, Joseph Myers
On Wed, Nov 18, 2020 at 06:35:00PM +0100, Florian Weimer wrote:
> * Dave Martin:
>
> > Having _GNU_SOURCE enable this feature will break existing source code.
>
> Does this matter?
>
> The code is already broken on a quickly increasing number of machines,
> so it needs fixing anyway. A compile-time error is probably
> preferable to an obscure run-time failure.
Fair point, but I didn't want to be the one making it :)
If people are happy to go this way, I don't see a problem with it.
Distro maintainers may shout a bit while they deal with the fallout of
that glibc upgrade though.
> > It probably should go under _GNU_SOURCE in the long term, but is there
> > usually a transitional period when the change is opt-in via some feature
> > macro?
>
> Not always. See the iszero and other macros in <math.h>, that also
> broke existing sources (largely C++, so we worked around it by using
> C++ features instead of macros). There are also many older examples.
I see. Well, I guess that's not my call.
> > I have some thoughts on what a better interface might look like --
> > basically separating the signal ucontext_t type from the setcontext()/
> > getcontext() etc. type, and providing accessors for the architectural
> > register state rather than just having a fixed struct definition for
> > mcontext_t.
> >
> > But, there also may not be a lot of appetite for such a change, and
> > I can't see how it could be backwards compatible.
> >
> > I can elaborate if people think it's worth discussing.
>
> I think Rich Felker wants to copy signal contexts around to implement
> critical sections that can't be interrupted by a signal handler, I
> think that would need this fully fixed.
Is rseq a more suitable way to do that sort of thing on new-ish Linux?
I guess a fallback may be needed for older / other kernels though.
I'm happy to follow up on here with my ucontext proposal, but it's quite
a big change. I wasn't sure people would really be up for it...
> But this is somewhat separate from fixing stack sizes to accomodate
> kernel and hardware needs.
I was wondering whether we could feed in ucontext changes on the back of
the MINSIGSTKSZ stuff, so that if people want one they must adopt both.
Probably best to deal with it independently though -- as you say, the
ucontext breakage already exists.
> By the way, something that I tried to raise in the past, but wasn't
> good at it: In the future, we may need a mechanism to reduce the
> kernel stack size usage for legacy binaries, perhaps using
> virtualization. The last time I looked at this, the signal context
> did not actually reduce when AVX-512 support was masked in a guest, I
> think. (Okay, this is largely for H.J.'s benefit.) This also applies
> to ld.so and its context save operation. Fortunately, not many people
> have run into this compatibility issue so far. The case I remember
> was an application that broke because it assumed zeros on the stack,
> and the XSAVE trampoline wrote some non-zero bits there because it
> reached much deeper into the stack. But the user was happy when we
> found the root cause and was able to add the missing initializer to
> their code, so all was good.
For aarch64 an explicit prctl()/sysctl opt-in is needed to enable jumbo
vector registers before you see oversized signal frames, though I don't
think there is a similar control for AVX-512.
Even on aarch64, this interface is not very friendly though. It might
be better to have some ELF attribute that ld.so or the libc startup can
arbitrate on and twiddle the appropriate switches.
Cheers
---Dave
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PING: V7 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
2020-11-18 18:09 ` Dave Martin
@ 2020-11-20 14:08 ` H.J. Lu
2020-11-20 14:11 ` Florian Weimer
0 siblings, 1 reply; 13+ messages in thread
From: H.J. Lu @ 2020-11-20 14:08 UTC (permalink / raw)
To: Dave Martin; +Cc: Florian Weimer, H.J. Lu via Libc-alpha, Joseph Myers
On Wed, Nov 18, 2020 at 10:09 AM Dave Martin via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
> On Wed, Nov 18, 2020 at 06:35:00PM +0100, Florian Weimer wrote:
> > * Dave Martin:
> >
> > > Having _GNU_SOURCE enable this feature will break existing source code.
> >
> > Does this matter?
> >
> > The code is already broken on a quickly increasing number of machines,
> > so it needs fixing anyway. A compile-time error is probably
> > preferable to an obscure run-time failure.
>
> Fair point, but I didn't want to be the one making it :)
>
> If people are happy to go this way, I don't see a problem with it.
> Distro maintainers may shout a bit while they deal with the fallout of
> that glibc upgrade though.
>
>
> > > It probably should go under _GNU_SOURCE in the long term, but is there
> > > usually a transitional period when the change is opt-in via some feature
> > > macro?
> >
> > Not always. See the iszero and other macros in <math.h>, that also
> > broke existing sources (largely C++, so we worked around it by using
> > C++ features instead of macros). There are also many older examples.
>
> I see. Well, I guess that's not my call.
>
Can we reach a consensus for _GNU_SOURCE vs _SC_SIGSTKSZ_SOURCE?
How about we make _GNU_SOURCE to enable _SC_SIGSTKSZ_SOURCE and
check _SC_SIGSTKSZ_SOURCE != 0? If _GNU_SOURCE triggers compilation
error and source codes can't be changed, we can add -D_SC_SIGSTKSZ_SOURCE=0
to disable _SC_SIGSTKSZ_SOURCE.
H.J.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: PING: V7 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
2020-11-20 14:08 ` H.J. Lu
@ 2020-11-20 14:11 ` Florian Weimer
2020-11-20 23:13 ` V8 " H.J. Lu
0 siblings, 1 reply; 13+ messages in thread
From: Florian Weimer @ 2020-11-20 14:11 UTC (permalink / raw)
To: H.J. Lu; +Cc: Dave Martin, H.J. Lu via Libc-alpha, Joseph Myers
* H. J. Lu:
> Can we reach a consensus for _GNU_SOURCE vs _SC_SIGSTKSZ_SOURCE?
>
> How about we make _GNU_SOURCE to enable _SC_SIGSTKSZ_SOURCE and
> check _SC_SIGSTKSZ_SOURCE != 0? If _GNU_SOURCE triggers compilation
> error and source codes can't be changed, we can add
> -D_SC_SIGSTKSZ_SOURCE=0 to disable _SC_SIGSTKSZ_SOURCE.
I think the source code compatibility is much more obscure than the
other things we broke quite recently, even without deprecation. Why
do we add the complexity in this case? I feel it is disproportional.
^ permalink raw reply [flat|nested] 13+ messages in thread
* V8 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
2020-11-20 14:11 ` Florian Weimer
@ 2020-11-20 23:13 ` H.J. Lu
2021-01-20 14:16 ` Carlos O'Donell
0 siblings, 1 reply; 13+ messages in thread
From: H.J. Lu @ 2020-11-20 23:13 UTC (permalink / raw)
To: Florian Weimer; +Cc: Dave Martin, H.J. Lu via Libc-alpha, Joseph Myers
[-- Attachment #1: Type: text/plain, Size: 698 bytes --]
On Fri, Nov 20, 2020 at 6:12 AM Florian Weimer <fw@deneb.enyo.de> wrote:
>
> * H. J. Lu:
>
> > Can we reach a consensus for _GNU_SOURCE vs _SC_SIGSTKSZ_SOURCE?
> >
> > How about we make _GNU_SOURCE to enable _SC_SIGSTKSZ_SOURCE and
> > check _SC_SIGSTKSZ_SOURCE != 0? If _GNU_SOURCE triggers compilation
> > error and source codes can't be changed, we can add
> > -D_SC_SIGSTKSZ_SOURCE=0 to disable _SC_SIGSTKSZ_SOURCE.
>
> I think the source code compatibility is much more obscure than the
> other things we broke quite recently, even without deprecation. Why
> do we add the complexity in this case? I feel it is disproportional.
Here is the patch with _GNU_SOURCE. Any comments?
--
H.J.
[-- Attachment #2: 0001-sysconf-Add-_SC_MINSIGSTKSZ-_SC_SIGSTKSZ-BZ-20305.patch --]
[-- Type: text/x-patch, Size: 28404 bytes --]
From 7ce7a0e753edd5fbda65cec987d681c65e86960d Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Fri, 25 Sep 2020 13:10:08 -0700
Subject: [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
Add _SC_MINSIGSTKSZ for the minimum signal stack size derived from
AT_MINSIGSTKSZ, which is the minimum number of bytes of free stack
space required in order to gurantee successful, non-nested handling
of a single signal whose handler is an empty function, and _SC_SIGSTKSZ
which is the suggested minimum number of bytes of stack space required
for a signal stack.
If AT_MINSIGSTKSZ isn't available, sysconf (_SC_MINSIGSTKSZ) returns
MINSIGSTKSZ. On Linux/x86 with XSAVE, the signal frame used by kernel
is composed of the following areas and laid out as:
------------------------------
| alignment padding |
------------------------------
| xsave buffer |
------------------------------
| fsave header (32-bit only) |
------------------------------
| siginfo + ucontext |
------------------------------
Compute AT_MINSIGSTKSZ value as size of xsave buffer + size of fsave
header (32-bit only) + size of siginfo and ucontext + alignment padding.
If _SC_SIGSTKSZ_SOURCE or _GNU_SOURCE are defined, MINSIGSTKSZ and SIGSTKSZ
are redefined as
/* 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
Compilation will fail if the source assumes constant MINSIGSTKSZ or
SIGSTKSZ.
The reason for not simply increasing the kernel's MINSIGSTKSZ #define
(apart from the fact that it is rarely used, due to glibc's shadowing
definitions) was that userspace binaries will have baked in the old
value of the constant and may be making assumptions about it.
For example, the type (char [MINSIGSTKSZ]) changes if this #define
changes. This could be a problem if an newly built library tries to
memcpy() or dump such an object defined by and old binary.
Bounds-checking and the stack sizes passed to things like sigaltstack()
and makecontext() could similarly go wrong.
---
NEWS | 5 ++
bits/confname.h | 8 +-
bits/sigstksz.h | 21 +++++
elf/dl-support.c | 5 ++
elf/dl-sysdep.c | 9 ++
include/bits/sigstack.h | 5 ++
include/bits/sigstksz.h | 7 ++
include/features.h | 11 +++
manual/conf.texi | 21 +++++
manual/creature.texi | 6 ++
posix/sysconf.c | 3 +
signal/Makefile | 5 +-
signal/signal.h | 1 +
signal/tst-minsigstksz-5.c | 84 +++++++++++++++++++
sysdeps/generic/ldsodefs.h | 3 +
sysdeps/unix/sysv/linux/bits/sigstksz.h | 33 ++++++++
.../unix/sysv/linux/ia64/sysconf-sigstksz.h | 27 ++++++
sysdeps/unix/sysv/linux/sysconf-sigstksz.h | 38 +++++++++
sysdeps/unix/sysv/linux/sysconf.c | 9 ++
.../unix/sysv/linux/x86/dl-minsigstacksize.h | 83 ++++++++++++++++++
.../sysv/linux/x86/include/bits/sigstack.h | 5 ++
sysdeps/x86/cpu-features.c | 3 +
sysdeps/x86/dl-minsigstacksize.h | 27 ++++++
23 files changed, 416 insertions(+), 3 deletions(-)
create mode 100644 bits/sigstksz.h
create mode 100644 include/bits/sigstack.h
create mode 100644 include/bits/sigstksz.h
create mode 100644 signal/tst-minsigstksz-5.c
create mode 100644 sysdeps/unix/sysv/linux/bits/sigstksz.h
create mode 100644 sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h
create mode 100644 sysdeps/unix/sysv/linux/sysconf-sigstksz.h
create mode 100644 sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h
create mode 100644 sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h
create mode 100644 sysdeps/x86/dl-minsigstacksize.h
diff --git a/NEWS b/NEWS
index 0335fb98e5..759a88ce5c 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,11 @@ Version 2.33
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 --argv0 argument and provides opportunity
to change argv[0] string.
diff --git a/bits/confname.h b/bits/confname.h
index 5dc8215093..451d3eb636 100644
--- a/bits/confname.h
+++ b/bits/confname.h
@@ -525,8 +525,14 @@ enum
_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'. */
diff --git a/bits/sigstksz.h b/bits/sigstksz.h
new file mode 100644
index 0000000000..5535d873b5
--- /dev/null
+++ b/bits/sigstksz.h
@@ -0,0 +1,21 @@
+/* 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
diff --git a/elf/dl-support.c b/elf/dl-support.c
index 15e6d787c9..dd631f50c4 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -136,6 +136,8 @@ void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
size_t _dl_pagesize = EXEC_PAGESIZE;
+size_t _dl_minsigstacksize = CONSTANT_MINSIGSTKSZ;
+
int _dl_inhibit_cache;
unsigned int _dl_osversion;
@@ -295,6 +297,9 @@ _dl_aux_init (ElfW(auxv_t) *av)
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)
diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c
index 854570821c..47400f2937 100644
--- a/elf/dl-sysdep.c
+++ b/elf/dl-sysdep.c
@@ -117,6 +117,11 @@ _dl_sysdep_start (void **start_argptr,
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)
{
@@ -181,6 +186,9 @@ _dl_sysdep_start (void **start_argptr,
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
}
@@ -308,6 +316,7 @@ _dl_show_auxv (void)
[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 },
diff --git a/include/bits/sigstack.h b/include/bits/sigstack.h
new file mode 100644
index 0000000000..eea939f59d
--- /dev/null
+++ b/include/bits/sigstack.h
@@ -0,0 +1,5 @@
+#include_next <bits/sigstack.h>
+
+#if !defined _ISOMAC && !defined CONSTANT_MINSIGSTKSZ
+# define CONSTANT_MINSIGSTKSZ MINSIGSTKSZ
+#endif
diff --git a/include/bits/sigstksz.h b/include/bits/sigstksz.h
new file mode 100644
index 0000000000..2ca891e918
--- /dev/null
+++ b/include/bits/sigstksz.h
@@ -0,0 +1,7 @@
+/* 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
diff --git a/include/features.h b/include/features.h
index f3e62d3362..deaf50928b 100644
--- a/include/features.h
+++ b/include/features.h
@@ -48,6 +48,8 @@
_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__).
@@ -94,6 +96,8 @@
__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.
@@ -137,6 +141,7 @@
#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
@@ -213,6 +218,8 @@
# 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,
@@ -388,6 +395,10 @@
# define __USE_ATFILE 1
#endif
+#ifdef _SC_SIGSTKSZ_SOURCE
+# define __USE_SC_SIGSTKSZ 1
+#endif
+
#ifdef _GNU_SOURCE
# define __USE_GNU 1
#endif
diff --git a/manual/conf.texi b/manual/conf.texi
index f959b00bb6..ba9847aaa4 100644
--- a/manual/conf.texi
+++ b/manual/conf.texi
@@ -913,6 +913,27 @@ Inquire about the parameter corresponding to @code{NL_SETMAX}.
@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
diff --git a/manual/creature.texi b/manual/creature.texi
index be5050468b..8fef4150fa 100644
--- a/manual/creature.texi
+++ b/manual/creature.texi
@@ -257,6 +257,12 @@ various library functions. If defined to @math{2}, even stricter
checks are applied.
@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)}
diff --git a/posix/sysconf.c b/posix/sysconf.c
index ba303384c1..ca7833e6c4 100644
--- a/posix/sysconf.c
+++ b/posix/sysconf.c
@@ -266,6 +266,9 @@ __sysconf (int name)
case _SC_XOPEN_REALTIME:
case _SC_XOPEN_REALTIME_THREADS:
+ case _SC_MINSIGSTKSZ:
+ case _SC_SIGSTKSZ:
+
break;
}
diff --git a/signal/Makefile b/signal/Makefile
index 2ec3ddd74f..641d30582d 100644
--- a/signal/Makefile
+++ b/signal/Makefile
@@ -31,7 +31,8 @@ headers := signal.h sys/signal.h \
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 \
@@ -48,7 +49,7 @@ routines := signal raise killpg \
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
diff --git a/signal/signal.h b/signal/signal.h
index effe3d698f..0311eb2a66 100644
--- a/signal/signal.h
+++ b/signal/signal.h
@@ -312,6 +312,7 @@ extern int siginterrupt (int __sig, int __interrupt) __THROW
__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.
diff --git a/signal/tst-minsigstksz-5.c b/signal/tst-minsigstksz-5.c
new file mode 100644
index 0000000000..d657d2f4e6
--- /dev/null
+++ b/signal/tst-minsigstksz-5.c
@@ -0,0 +1,84 @@
+/* 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>
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index b1da03cafe..38093e2b8a 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -536,6 +536,9 @@ struct rtld_global_ro
/* 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;
diff --git a/sysdeps/unix/sysv/linux/bits/sigstksz.h b/sysdeps/unix/sysv/linux/bits/sigstksz.h
new file mode 100644
index 0000000000..926508f2b4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/bits/sigstksz.h
@@ -0,0 +1,33 @@
+/* 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
diff --git a/sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h b/sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h
new file mode 100644
index 0000000000..7e5ceba151
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h
@@ -0,0 +1,27 @@
+/* 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;
+}
diff --git a/sysdeps/unix/sysv/linux/sysconf-sigstksz.h b/sysdeps/unix/sysv/linux/sysconf-sigstksz.h
new file mode 100644
index 0000000000..64d450b22c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sysconf-sigstksz.h
@@ -0,0 +1,38 @@
+/* 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;
+}
diff --git a/sysdeps/unix/sysv/linux/sysconf.c b/sysdeps/unix/sysv/linux/sysconf.c
index 9c5a4cb1a4..22eeac50ca 100644
--- a/sysdeps/unix/sysv/linux/sysconf.c
+++ b/sysdeps/unix/sysv/linux/sysconf.c
@@ -16,6 +16,7 @@
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>
@@ -26,6 +27,7 @@
#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. */
@@ -75,6 +77,13 @@ __sysconf (int name)
}
break;
+ case _SC_MINSIGSTKSZ:
+ assert (GLRO(dl_minsigstacksize) != 0);
+ return GLRO(dl_minsigstacksize);
+
+ case _SC_SIGSTKSZ:
+ return sysconf_sigstksz ();
+
default:
break;
}
diff --git a/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h b/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h
new file mode 100644
index 0000000000..6088bbc99e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h
@@ -0,0 +1,83 @@
+/* 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;
+ }
+}
diff --git a/sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h b/sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h
new file mode 100644
index 0000000000..208754c497
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h
@@ -0,0 +1,5 @@
+#include_next <bits/sigstack.h>
+
+#ifndef _ISOMAC
+# define CONSTANT_MINSIGSTKSZ 0
+#endif
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
index f26deba38d..bef6084f5e 100644
--- a/sysdeps/x86/cpu-features.c
+++ b/sysdeps/x86/cpu-features.c
@@ -19,6 +19,7 @@
#include <cpuid.h>
#include <dl-hwcap.h>
#include <libc-pointer-arith.h>
+#include <dl-minsigstacksize.h>
#if IS_IN (libc) && !defined SHARED
# include <assert.h>
# include <unistd.h>
@@ -367,6 +368,8 @@ get_common_indices (struct cpu_features *cpu_features,
cpu_features->features[COMMON_CPUID_INDEX_19].cpuid.ebx,
cpu_features->features[COMMON_CPUID_INDEX_19].cpuid.ecx,
cpu_features->features[COMMON_CPUID_INDEX_19].cpuid.edx);
+
+ dl_check_minsigstacksize (cpu_features);
}
_Static_assert (((index_arch_Fast_Unaligned_Load
diff --git a/sysdeps/x86/dl-minsigstacksize.h b/sysdeps/x86/dl-minsigstacksize.h
new file mode 100644
index 0000000000..959871c970
--- /dev/null
+++ b/sysdeps/x86/dl-minsigstacksize.h
@@ -0,0 +1,27 @@
+/* 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;
+}
--
2.28.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: V8 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
2020-11-20 23:13 ` V8 " H.J. Lu
@ 2021-01-20 14:16 ` Carlos O'Donell
2021-01-20 15:05 ` V9 " H.J. Lu
0 siblings, 1 reply; 13+ messages in thread
From: Carlos O'Donell @ 2021-01-20 14:16 UTC (permalink / raw)
To: H.J. Lu, Florian Weimer; +Cc: H.J. Lu via Libc-alpha, Dave Martin, Joseph Myers
On 11/20/20 6:13 PM, H.J. Lu via Libc-alpha wrote:
> On Fri, Nov 20, 2020 at 6:12 AM Florian Weimer <fw@deneb.enyo.de> wrote:
>>
>> * H. J. Lu:
>>
>>> Can we reach a consensus for _GNU_SOURCE vs _SC_SIGSTKSZ_SOURCE?
>>>
>>> How about we make _GNU_SOURCE to enable _SC_SIGSTKSZ_SOURCE and
>>> check _SC_SIGSTKSZ_SOURCE != 0? If _GNU_SOURCE triggers compilation
>>> error and source codes can't be changed, we can add
>>> -D_SC_SIGSTKSZ_SOURCE=0 to disable _SC_SIGSTKSZ_SOURCE.
>>
>> I think the source code compatibility is much more obscure than the
>> other things we broke quite recently, even without deprecation. Why
>> do we add the complexity in this case? I feel it is disproportional.
>
> Here is the patch with _GNU_SOURCE. Any comments?
(1) New version of patch.
This patch no longer compiles due to __cpuid_count errors.
Could you please update this and post a v9?
This is ABI addition for the constants so I want to make sure I review
something that works and is final from your end.
(2) Kernel definition of constant for AT_MINSIGSTKSZ?
We don't have a released kernel for x86 with this constant defined?
The kernel patch was only just updated 5 days ago:
https://sourceware.org/pipermail/libc-alpha/2021-January/121671.html
Doesn't this mean this patch is inappropriate for glibc 2.33?
--
Cheers,
Carlos.
^ permalink raw reply [flat|nested] 13+ messages in thread
* V9 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
2021-01-20 14:16 ` Carlos O'Donell
@ 2021-01-20 15:05 ` H.J. Lu
2021-01-22 19:41 ` V10 " H.J. Lu
0 siblings, 1 reply; 13+ messages in thread
From: H.J. Lu @ 2021-01-20 15:05 UTC (permalink / raw)
To: Carlos O'Donell
Cc: Florian Weimer, H.J. Lu via Libc-alpha, Dave Martin, Joseph Myers
[-- Attachment #1: Type: text/plain, Size: 1879 bytes --]
On Wed, Jan 20, 2021 at 6:16 AM Carlos O'Donell <carlos@redhat.com> wrote:
>
> On 11/20/20 6:13 PM, H.J. Lu via Libc-alpha wrote:
> > On Fri, Nov 20, 2020 at 6:12 AM Florian Weimer <fw@deneb.enyo.de> wrote:
> >>
> >> * H. J. Lu:
> >>
> >>> Can we reach a consensus for _GNU_SOURCE vs _SC_SIGSTKSZ_SOURCE?
> >>>
> >>> How about we make _GNU_SOURCE to enable _SC_SIGSTKSZ_SOURCE and
> >>> check _SC_SIGSTKSZ_SOURCE != 0? If _GNU_SOURCE triggers compilation
> >>> error and source codes can't be changed, we can add
> >>> -D_SC_SIGSTKSZ_SOURCE=0 to disable _SC_SIGSTKSZ_SOURCE.
> >>
> >> I think the source code compatibility is much more obscure than the
> >> other things we broke quite recently, even without deprecation. Why
> >> do we add the complexity in this case? I feel it is disproportional.
> >
> > Here is the patch with _GNU_SOURCE. Any comments?
>
> (1) New version of patch.
>
> This patch no longer compiles due to __cpuid_count errors.
>
> Could you please update this and post a v9?
Fixed.
> This is ABI addition for the constants so I want to make sure I review
> something that works and is final from your end.
>
> (2) Kernel definition of constant for AT_MINSIGSTKSZ?
>
> We don't have a released kernel for x86 with this constant defined?
>
> The kernel patch was only just updated 5 days ago:
> https://sourceware.org/pipermail/libc-alpha/2021-January/121671.html
>
> Doesn't this mean this patch is inappropriate for glibc 2.33?
The new glibc works with the older kernels. In many cases, we
use emulation for the older kernels. This patch only uses the
existing kernel interface. The kernel patch you referred doesn't
add any new interface. It simply uses the existing AT_MINSIGSTKSZ
for x86. My patch includes an emulation for the older kernels. I
think my patch is appropriate for glibc 2.33.
Here is the updated patc.
Thanks.
--
H.J.
[-- Attachment #2: 0001-sysconf-Add-_SC_MINSIGSTKSZ-_SC_SIGSTKSZ-BZ-20305.patch --]
[-- Type: text/x-patch, Size: 28541 bytes --]
From 677cef5c70fd3101586d5b5ed946e6a29ba39f3a Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Fri, 25 Sep 2020 13:10:08 -0700
Subject: [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
Add _SC_MINSIGSTKSZ for the minimum signal stack size derived from
AT_MINSIGSTKSZ, which is the minimum number of bytes of free stack
space required in order to gurantee successful, non-nested handling
of a single signal whose handler is an empty function, and _SC_SIGSTKSZ
which is the suggested minimum number of bytes of stack space required
for a signal stack.
If AT_MINSIGSTKSZ isn't available, sysconf (_SC_MINSIGSTKSZ) returns
MINSIGSTKSZ. On Linux/x86 with XSAVE, the signal frame used by kernel
is composed of the following areas and laid out as:
------------------------------
| alignment padding |
------------------------------
| xsave buffer |
------------------------------
| fsave header (32-bit only) |
------------------------------
| siginfo + ucontext |
------------------------------
Compute AT_MINSIGSTKSZ value as size of xsave buffer + size of fsave
header (32-bit only) + size of siginfo and ucontext + alignment padding.
If _SC_SIGSTKSZ_SOURCE or _GNU_SOURCE are defined, MINSIGSTKSZ and SIGSTKSZ
are redefined as
/* 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
Compilation will fail if the source assumes constant MINSIGSTKSZ or
SIGSTKSZ.
The reason for not simply increasing the kernel's MINSIGSTKSZ #define
(apart from the fact that it is rarely used, due to glibc's shadowing
definitions) was that userspace binaries will have baked in the old
value of the constant and may be making assumptions about it.
For example, the type (char [MINSIGSTKSZ]) changes if this #define
changes. This could be a problem if an newly built library tries to
memcpy() or dump such an object defined by and old binary.
Bounds-checking and the stack sizes passed to things like sigaltstack()
and makecontext() could similarly go wrong.
---
NEWS | 5 ++
bits/confname.h | 8 +-
bits/sigstksz.h | 21 +++++
elf/dl-support.c | 5 ++
elf/dl-sysdep.c | 9 ++
include/bits/sigstack.h | 5 ++
include/bits/sigstksz.h | 7 ++
include/features.h | 11 +++
manual/conf.texi | 21 +++++
manual/creature.texi | 6 ++
posix/sysconf.c | 3 +
signal/Makefile | 5 +-
signal/signal.h | 1 +
signal/tst-minsigstksz-5.c | 84 +++++++++++++++++++
sysdeps/generic/ldsodefs.h | 3 +
sysdeps/unix/sysv/linux/bits/sigstksz.h | 33 ++++++++
.../unix/sysv/linux/ia64/sysconf-sigstksz.h | 27 ++++++
sysdeps/unix/sysv/linux/sysconf-sigstksz.h | 38 +++++++++
sysdeps/unix/sysv/linux/sysconf.c | 9 ++
.../unix/sysv/linux/x86/dl-minsigstacksize.h | 83 ++++++++++++++++++
.../sysv/linux/x86/include/bits/sigstack.h | 5 ++
sysdeps/x86/cpu-features.c | 3 +
sysdeps/x86/dl-minsigstacksize.h | 27 ++++++
23 files changed, 416 insertions(+), 3 deletions(-)
create mode 100644 bits/sigstksz.h
create mode 100644 include/bits/sigstack.h
create mode 100644 include/bits/sigstksz.h
create mode 100644 signal/tst-minsigstksz-5.c
create mode 100644 sysdeps/unix/sysv/linux/bits/sigstksz.h
create mode 100644 sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h
create mode 100644 sysdeps/unix/sysv/linux/sysconf-sigstksz.h
create mode 100644 sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h
create mode 100644 sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h
create mode 100644 sysdeps/x86/dl-minsigstacksize.h
diff --git a/NEWS b/NEWS
index d121f7df87..0758bb37e3 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,11 @@ Version 2.33
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).
diff --git a/bits/confname.h b/bits/confname.h
index 8068bda273..ec6cd07957 100644
--- a/bits/confname.h
+++ b/bits/confname.h
@@ -525,8 +525,14 @@ enum
_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'. */
diff --git a/bits/sigstksz.h b/bits/sigstksz.h
new file mode 100644
index 0000000000..5535d873b5
--- /dev/null
+++ b/bits/sigstksz.h
@@ -0,0 +1,21 @@
+/* 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
diff --git a/elf/dl-support.c b/elf/dl-support.c
index 2434c470c7..9c3c71ba61 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -136,6 +136,8 @@ void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
size_t _dl_pagesize = EXEC_PAGESIZE;
+size_t _dl_minsigstacksize = CONSTANT_MINSIGSTKSZ;
+
int _dl_inhibit_cache;
unsigned int _dl_osversion;
@@ -301,6 +303,9 @@ _dl_aux_init (ElfW(auxv_t) *av)
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)
diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c
index 0658c17da6..bd5066fe3b 100644
--- a/elf/dl-sysdep.c
+++ b/elf/dl-sysdep.c
@@ -115,6 +115,11 @@ _dl_sysdep_start (void **start_argptr,
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)
{
@@ -179,6 +184,9 @@ _dl_sysdep_start (void **start_argptr,
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
}
@@ -306,6 +314,7 @@ _dl_show_auxv (void)
[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 },
diff --git a/include/bits/sigstack.h b/include/bits/sigstack.h
new file mode 100644
index 0000000000..eea939f59d
--- /dev/null
+++ b/include/bits/sigstack.h
@@ -0,0 +1,5 @@
+#include_next <bits/sigstack.h>
+
+#if !defined _ISOMAC && !defined CONSTANT_MINSIGSTKSZ
+# define CONSTANT_MINSIGSTKSZ MINSIGSTKSZ
+#endif
diff --git a/include/bits/sigstksz.h b/include/bits/sigstksz.h
new file mode 100644
index 0000000000..2ca891e918
--- /dev/null
+++ b/include/bits/sigstksz.h
@@ -0,0 +1,7 @@
+/* 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
diff --git a/include/features.h b/include/features.h
index a71ac85af4..cc05a31ae1 100644
--- a/include/features.h
+++ b/include/features.h
@@ -48,6 +48,8 @@
_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__).
@@ -94,6 +96,8 @@
__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.
@@ -137,6 +141,7 @@
#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
@@ -213,6 +218,8 @@
# 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,
@@ -388,6 +395,10 @@
# define __USE_ATFILE 1
#endif
+#ifdef _SC_SIGSTKSZ_SOURCE
+# define __USE_SC_SIGSTKSZ 1
+#endif
+
#ifdef _GNU_SOURCE
# define __USE_GNU 1
#endif
diff --git a/manual/conf.texi b/manual/conf.texi
index f959b00bb6..ba9847aaa4 100644
--- a/manual/conf.texi
+++ b/manual/conf.texi
@@ -913,6 +913,27 @@ Inquire about the parameter corresponding to @code{NL_SETMAX}.
@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
diff --git a/manual/creature.texi b/manual/creature.texi
index 31208ccb2b..5090735e4f 100644
--- a/manual/creature.texi
+++ b/manual/creature.texi
@@ -258,6 +258,12 @@ checks are applied. If defined to @math{3}, @theglibc{} may also use
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)}
diff --git a/posix/sysconf.c b/posix/sysconf.c
index bb9e132e5c..67d17ca0f8 100644
--- a/posix/sysconf.c
+++ b/posix/sysconf.c
@@ -266,6 +266,9 @@ __sysconf (int name)
case _SC_XOPEN_REALTIME:
case _SC_XOPEN_REALTIME_THREADS:
+ case _SC_MINSIGSTKSZ:
+ case _SC_SIGSTKSZ:
+
break;
}
diff --git a/signal/Makefile b/signal/Makefile
index e89c308889..3d8cab1f50 100644
--- a/signal/Makefile
+++ b/signal/Makefile
@@ -31,7 +31,8 @@ headers := signal.h sys/signal.h \
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 \
@@ -48,7 +49,7 @@ routines := signal raise killpg \
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
diff --git a/signal/signal.h b/signal/signal.h
index 6463c98e11..b17203c99c 100644
--- a/signal/signal.h
+++ b/signal/signal.h
@@ -312,6 +312,7 @@ extern int siginterrupt (int __sig, int __interrupt) __THROW
__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.
diff --git a/signal/tst-minsigstksz-5.c b/signal/tst-minsigstksz-5.c
new file mode 100644
index 0000000000..d657d2f4e6
--- /dev/null
+++ b/signal/tst-minsigstksz-5.c
@@ -0,0 +1,84 @@
+/* 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>
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index aab7245e93..9720a4e446 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -536,6 +536,9 @@ struct rtld_global_ro
/* 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;
diff --git a/sysdeps/unix/sysv/linux/bits/sigstksz.h b/sysdeps/unix/sysv/linux/bits/sigstksz.h
new file mode 100644
index 0000000000..926508f2b4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/bits/sigstksz.h
@@ -0,0 +1,33 @@
+/* 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
diff --git a/sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h b/sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h
new file mode 100644
index 0000000000..7e5ceba151
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h
@@ -0,0 +1,27 @@
+/* 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;
+}
diff --git a/sysdeps/unix/sysv/linux/sysconf-sigstksz.h b/sysdeps/unix/sysv/linux/sysconf-sigstksz.h
new file mode 100644
index 0000000000..64d450b22c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sysconf-sigstksz.h
@@ -0,0 +1,38 @@
+/* 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;
+}
diff --git a/sysdeps/unix/sysv/linux/sysconf.c b/sysdeps/unix/sysv/linux/sysconf.c
index bfad5b6858..366fcef01e 100644
--- a/sysdeps/unix/sysv/linux/sysconf.c
+++ b/sysdeps/unix/sysv/linux/sysconf.c
@@ -16,6 +16,7 @@
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>
@@ -26,6 +27,7 @@
#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. */
@@ -75,6 +77,13 @@ __sysconf (int name)
}
break;
+ case _SC_MINSIGSTKSZ:
+ assert (GLRO(dl_minsigstacksize) != 0);
+ return GLRO(dl_minsigstacksize);
+
+ case _SC_SIGSTKSZ:
+ return sysconf_sigstksz ();
+
default:
break;
}
diff --git a/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h b/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h
new file mode 100644
index 0000000000..6088bbc99e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h
@@ -0,0 +1,83 @@
+/* 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;
+ }
+}
diff --git a/sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h b/sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h
new file mode 100644
index 0000000000..208754c497
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h
@@ -0,0 +1,5 @@
+#include_next <bits/sigstack.h>
+
+#ifndef _ISOMAC
+# define CONSTANT_MINSIGSTKSZ 0
+#endif
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
index 06e4307b71..3a5ee9908d 100644
--- a/sysdeps/x86/cpu-features.c
+++ b/sysdeps/x86/cpu-features.c
@@ -21,6 +21,7 @@
#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 *)
@@ -362,6 +363,8 @@ get_common_indices (struct cpu_features *cpu_features,
cpu_features->features[COMMON_CPUID_INDEX_19].cpuid.ebx,
cpu_features->features[COMMON_CPUID_INDEX_19].cpuid.ecx,
cpu_features->features[COMMON_CPUID_INDEX_19].cpuid.edx);
+
+ dl_check_minsigstacksize (cpu_features);
}
_Static_assert (((index_arch_Fast_Unaligned_Load
diff --git a/sysdeps/x86/dl-minsigstacksize.h b/sysdeps/x86/dl-minsigstacksize.h
new file mode 100644
index 0000000000..959871c970
--- /dev/null
+++ b/sysdeps/x86/dl-minsigstacksize.h
@@ -0,0 +1,27 @@
+/* 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;
+}
--
2.29.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* V10 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
2021-01-20 15:05 ` V9 " H.J. Lu
@ 2021-01-22 19:41 ` H.J. Lu
2021-01-25 13:31 ` Carlos O'Donell
2021-01-25 13:58 ` Carlos O'Donell
0 siblings, 2 replies; 13+ messages in thread
From: H.J. Lu @ 2021-01-22 19:41 UTC (permalink / raw)
To: Carlos O'Donell
Cc: Florian Weimer, H.J. Lu via Libc-alpha, Dave Martin, Joseph Myers
[-- Attachment #1: Type: text/plain, Size: 2062 bytes --]
On Wed, Jan 20, 2021 at 7:05 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Wed, Jan 20, 2021 at 6:16 AM Carlos O'Donell <carlos@redhat.com> wrote:
> >
> > On 11/20/20 6:13 PM, H.J. Lu via Libc-alpha wrote:
> > > On Fri, Nov 20, 2020 at 6:12 AM Florian Weimer <fw@deneb.enyo.de> wrote:
> > >>
> > >> * H. J. Lu:
> > >>
> > >>> Can we reach a consensus for _GNU_SOURCE vs _SC_SIGSTKSZ_SOURCE?
> > >>>
> > >>> How about we make _GNU_SOURCE to enable _SC_SIGSTKSZ_SOURCE and
> > >>> check _SC_SIGSTKSZ_SOURCE != 0? If _GNU_SOURCE triggers compilation
> > >>> error and source codes can't be changed, we can add
> > >>> -D_SC_SIGSTKSZ_SOURCE=0 to disable _SC_SIGSTKSZ_SOURCE.
> > >>
> > >> I think the source code compatibility is much more obscure than the
> > >> other things we broke quite recently, even without deprecation. Why
> > >> do we add the complexity in this case? I feel it is disproportional.
> > >
> > > Here is the patch with _GNU_SOURCE. Any comments?
> >
> > (1) New version of patch.
> >
> > This patch no longer compiles due to __cpuid_count errors.
> >
> > Could you please update this and post a v9?
>
> Fixed.
>
> > This is ABI addition for the constants so I want to make sure I review
> > something that works and is final from your end.
> >
> > (2) Kernel definition of constant for AT_MINSIGSTKSZ?
> >
> > We don't have a released kernel for x86 with this constant defined?
> >
> > The kernel patch was only just updated 5 days ago:
> > https://sourceware.org/pipermail/libc-alpha/2021-January/121671.html
> >
> > Doesn't this mean this patch is inappropriate for glibc 2.33?
>
> The new glibc works with the older kernels. In many cases, we
> use emulation for the older kernels. This patch only uses the
> existing kernel interface. The kernel patch you referred doesn't
> add any new interface. It simply uses the existing AT_MINSIGSTKSZ
> for x86. My patch includes an emulation for the older kernels. I
> think my patch is appropriate for glibc 2.33.
>
> Here is the updated patc.
>
> Thanks.
Another rebase.
--
H.J.
[-- Attachment #2: 0001-sysconf-Add-_SC_MINSIGSTKSZ-_SC_SIGSTKSZ-BZ-20305.patch --]
[-- Type: text/x-patch, Size: 28520 bytes --]
From 9f040b4540feec52577b660cb151c79cdc2741a3 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Fri, 25 Sep 2020 13:10:08 -0700
Subject: [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
Add _SC_MINSIGSTKSZ for the minimum signal stack size derived from
AT_MINSIGSTKSZ, which is the minimum number of bytes of free stack
space required in order to gurantee successful, non-nested handling
of a single signal whose handler is an empty function, and _SC_SIGSTKSZ
which is the suggested minimum number of bytes of stack space required
for a signal stack.
If AT_MINSIGSTKSZ isn't available, sysconf (_SC_MINSIGSTKSZ) returns
MINSIGSTKSZ. On Linux/x86 with XSAVE, the signal frame used by kernel
is composed of the following areas and laid out as:
------------------------------
| alignment padding |
------------------------------
| xsave buffer |
------------------------------
| fsave header (32-bit only) |
------------------------------
| siginfo + ucontext |
------------------------------
Compute AT_MINSIGSTKSZ value as size of xsave buffer + size of fsave
header (32-bit only) + size of siginfo and ucontext + alignment padding.
If _SC_SIGSTKSZ_SOURCE or _GNU_SOURCE are defined, MINSIGSTKSZ and SIGSTKSZ
are redefined as
/* 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
Compilation will fail if the source assumes constant MINSIGSTKSZ or
SIGSTKSZ.
The reason for not simply increasing the kernel's MINSIGSTKSZ #define
(apart from the fact that it is rarely used, due to glibc's shadowing
definitions) was that userspace binaries will have baked in the old
value of the constant and may be making assumptions about it.
For example, the type (char [MINSIGSTKSZ]) changes if this #define
changes. This could be a problem if an newly built library tries to
memcpy() or dump such an object defined by and old binary.
Bounds-checking and the stack sizes passed to things like sigaltstack()
and makecontext() could similarly go wrong.
---
NEWS | 5 ++
bits/confname.h | 8 +-
bits/sigstksz.h | 21 +++++
elf/dl-support.c | 5 ++
elf/dl-sysdep.c | 9 ++
include/bits/sigstack.h | 5 ++
include/bits/sigstksz.h | 7 ++
include/features.h | 11 +++
manual/conf.texi | 21 +++++
manual/creature.texi | 6 ++
posix/sysconf.c | 3 +
signal/Makefile | 5 +-
signal/signal.h | 1 +
signal/tst-minsigstksz-5.c | 84 +++++++++++++++++++
sysdeps/generic/ldsodefs.h | 3 +
sysdeps/unix/sysv/linux/bits/sigstksz.h | 33 ++++++++
.../unix/sysv/linux/ia64/sysconf-sigstksz.h | 27 ++++++
sysdeps/unix/sysv/linux/sysconf-sigstksz.h | 38 +++++++++
sysdeps/unix/sysv/linux/sysconf.c | 9 ++
.../unix/sysv/linux/x86/dl-minsigstacksize.h | 83 ++++++++++++++++++
.../sysv/linux/x86/include/bits/sigstack.h | 5 ++
sysdeps/x86/cpu-features.c | 3 +
sysdeps/x86/dl-minsigstacksize.h | 27 ++++++
23 files changed, 416 insertions(+), 3 deletions(-)
create mode 100644 bits/sigstksz.h
create mode 100644 include/bits/sigstack.h
create mode 100644 include/bits/sigstksz.h
create mode 100644 signal/tst-minsigstksz-5.c
create mode 100644 sysdeps/unix/sysv/linux/bits/sigstksz.h
create mode 100644 sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h
create mode 100644 sysdeps/unix/sysv/linux/sysconf-sigstksz.h
create mode 100644 sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h
create mode 100644 sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h
create mode 100644 sysdeps/x86/dl-minsigstacksize.h
diff --git a/NEWS b/NEWS
index d121f7df87..0758bb37e3 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,11 @@ Version 2.33
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).
diff --git a/bits/confname.h b/bits/confname.h
index 8068bda273..ec6cd07957 100644
--- a/bits/confname.h
+++ b/bits/confname.h
@@ -525,8 +525,14 @@ enum
_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'. */
diff --git a/bits/sigstksz.h b/bits/sigstksz.h
new file mode 100644
index 0000000000..5535d873b5
--- /dev/null
+++ b/bits/sigstksz.h
@@ -0,0 +1,21 @@
+/* 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
diff --git a/elf/dl-support.c b/elf/dl-support.c
index 7abb65d8e3..7fc2ee78e2 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -142,6 +142,8 @@ void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
size_t _dl_pagesize = EXEC_PAGESIZE;
+size_t _dl_minsigstacksize = CONSTANT_MINSIGSTKSZ;
+
int _dl_inhibit_cache;
unsigned int _dl_osversion;
@@ -307,6 +309,9 @@ _dl_aux_init (ElfW(auxv_t) *av)
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)
diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c
index 0658c17da6..bd5066fe3b 100644
--- a/elf/dl-sysdep.c
+++ b/elf/dl-sysdep.c
@@ -115,6 +115,11 @@ _dl_sysdep_start (void **start_argptr,
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)
{
@@ -179,6 +184,9 @@ _dl_sysdep_start (void **start_argptr,
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
}
@@ -306,6 +314,7 @@ _dl_show_auxv (void)
[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 },
diff --git a/include/bits/sigstack.h b/include/bits/sigstack.h
new file mode 100644
index 0000000000..eea939f59d
--- /dev/null
+++ b/include/bits/sigstack.h
@@ -0,0 +1,5 @@
+#include_next <bits/sigstack.h>
+
+#if !defined _ISOMAC && !defined CONSTANT_MINSIGSTKSZ
+# define CONSTANT_MINSIGSTKSZ MINSIGSTKSZ
+#endif
diff --git a/include/bits/sigstksz.h b/include/bits/sigstksz.h
new file mode 100644
index 0000000000..2ca891e918
--- /dev/null
+++ b/include/bits/sigstksz.h
@@ -0,0 +1,7 @@
+/* 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
diff --git a/include/features.h b/include/features.h
index a71ac85af4..cc05a31ae1 100644
--- a/include/features.h
+++ b/include/features.h
@@ -48,6 +48,8 @@
_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__).
@@ -94,6 +96,8 @@
__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.
@@ -137,6 +141,7 @@
#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
@@ -213,6 +218,8 @@
# 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,
@@ -388,6 +395,10 @@
# define __USE_ATFILE 1
#endif
+#ifdef _SC_SIGSTKSZ_SOURCE
+# define __USE_SC_SIGSTKSZ 1
+#endif
+
#ifdef _GNU_SOURCE
# define __USE_GNU 1
#endif
diff --git a/manual/conf.texi b/manual/conf.texi
index f959b00bb6..ba9847aaa4 100644
--- a/manual/conf.texi
+++ b/manual/conf.texi
@@ -913,6 +913,27 @@ Inquire about the parameter corresponding to @code{NL_SETMAX}.
@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
diff --git a/manual/creature.texi b/manual/creature.texi
index 31208ccb2b..5090735e4f 100644
--- a/manual/creature.texi
+++ b/manual/creature.texi
@@ -258,6 +258,12 @@ checks are applied. If defined to @math{3}, @theglibc{} may also use
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)}
diff --git a/posix/sysconf.c b/posix/sysconf.c
index bb9e132e5c..67d17ca0f8 100644
--- a/posix/sysconf.c
+++ b/posix/sysconf.c
@@ -266,6 +266,9 @@ __sysconf (int name)
case _SC_XOPEN_REALTIME:
case _SC_XOPEN_REALTIME_THREADS:
+ case _SC_MINSIGSTKSZ:
+ case _SC_SIGSTKSZ:
+
break;
}
diff --git a/signal/Makefile b/signal/Makefile
index e89c308889..3d8cab1f50 100644
--- a/signal/Makefile
+++ b/signal/Makefile
@@ -31,7 +31,8 @@ headers := signal.h sys/signal.h \
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 \
@@ -48,7 +49,7 @@ routines := signal raise killpg \
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
diff --git a/signal/signal.h b/signal/signal.h
index 6463c98e11..b17203c99c 100644
--- a/signal/signal.h
+++ b/signal/signal.h
@@ -312,6 +312,7 @@ extern int siginterrupt (int __sig, int __interrupt) __THROW
__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.
diff --git a/signal/tst-minsigstksz-5.c b/signal/tst-minsigstksz-5.c
new file mode 100644
index 0000000000..d657d2f4e6
--- /dev/null
+++ b/signal/tst-minsigstksz-5.c
@@ -0,0 +1,84 @@
+/* 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>
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index aab7245e93..9720a4e446 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -536,6 +536,9 @@ struct rtld_global_ro
/* 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;
diff --git a/sysdeps/unix/sysv/linux/bits/sigstksz.h b/sysdeps/unix/sysv/linux/bits/sigstksz.h
new file mode 100644
index 0000000000..926508f2b4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/bits/sigstksz.h
@@ -0,0 +1,33 @@
+/* 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
diff --git a/sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h b/sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h
new file mode 100644
index 0000000000..7e5ceba151
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h
@@ -0,0 +1,27 @@
+/* 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;
+}
diff --git a/sysdeps/unix/sysv/linux/sysconf-sigstksz.h b/sysdeps/unix/sysv/linux/sysconf-sigstksz.h
new file mode 100644
index 0000000000..64d450b22c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sysconf-sigstksz.h
@@ -0,0 +1,38 @@
+/* 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;
+}
diff --git a/sysdeps/unix/sysv/linux/sysconf.c b/sysdeps/unix/sysv/linux/sysconf.c
index bfad5b6858..366fcef01e 100644
--- a/sysdeps/unix/sysv/linux/sysconf.c
+++ b/sysdeps/unix/sysv/linux/sysconf.c
@@ -16,6 +16,7 @@
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>
@@ -26,6 +27,7 @@
#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. */
@@ -75,6 +77,13 @@ __sysconf (int name)
}
break;
+ case _SC_MINSIGSTKSZ:
+ assert (GLRO(dl_minsigstacksize) != 0);
+ return GLRO(dl_minsigstacksize);
+
+ case _SC_SIGSTKSZ:
+ return sysconf_sigstksz ();
+
default:
break;
}
diff --git a/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h b/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h
new file mode 100644
index 0000000000..6088bbc99e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h
@@ -0,0 +1,83 @@
+/* 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;
+ }
+}
diff --git a/sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h b/sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h
new file mode 100644
index 0000000000..208754c497
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h
@@ -0,0 +1,5 @@
+#include_next <bits/sigstack.h>
+
+#ifndef _ISOMAC
+# define CONSTANT_MINSIGSTKSZ 0
+#endif
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
index 6496512a0d..dfeca31967 100644
--- a/sysdeps/x86/cpu-features.c
+++ b/sysdeps/x86/cpu-features.c
@@ -21,6 +21,7 @@
#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 *)
@@ -362,6 +363,8 @@ get_common_indices (struct cpu_features *cpu_features,
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
diff --git a/sysdeps/x86/dl-minsigstacksize.h b/sysdeps/x86/dl-minsigstacksize.h
new file mode 100644
index 0000000000..959871c970
--- /dev/null
+++ b/sysdeps/x86/dl-minsigstacksize.h
@@ -0,0 +1,27 @@
+/* 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;
+}
--
2.29.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: V10 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
2021-01-22 19:41 ` V10 " H.J. Lu
@ 2021-01-25 13:31 ` Carlos O'Donell
2021-01-25 13:57 ` H.J. Lu
2021-01-25 13:58 ` Carlos O'Donell
1 sibling, 1 reply; 13+ messages in thread
From: Carlos O'Donell @ 2021-01-25 13:31 UTC (permalink / raw)
To: H.J. Lu; +Cc: Florian Weimer, H.J. Lu via Libc-alpha, Dave Martin, Joseph Myers
On 1/22/21 2:41 PM, H.J. Lu wrote:
> Another rebase.
Just a note here that v10 does not apply with patchwork automation.
This makes things more difficult for my review and automated testing.
If possible could you please just resent via git send-email on a new thread?
e.g.
git format-patch -v 10 ...
git send-email ...
--
Cheers,
Carlos.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: V10 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
2021-01-25 13:31 ` Carlos O'Donell
@ 2021-01-25 13:57 ` H.J. Lu
2021-01-25 13:59 ` Carlos O'Donell
0 siblings, 1 reply; 13+ messages in thread
From: H.J. Lu @ 2021-01-25 13:57 UTC (permalink / raw)
To: Carlos O'Donell
Cc: Florian Weimer, H.J. Lu via Libc-alpha, Dave Martin, Joseph Myers
On Mon, Jan 25, 2021 at 5:32 AM Carlos O'Donell <carlos@redhat.com> wrote:
>
> On 1/22/21 2:41 PM, H.J. Lu wrote:
> > Another rebase.
>
> Just a note here that v10 does not apply with patchwork automation.
>
> This makes things more difficult for my review and automated testing.
>
> If possible could you please just resent via git send-email on a new thread?
>
> e.g.
>
> git format-patch -v 10 ...
> git send-email ...
>
Done.
--
H.J.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: V10 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
2021-01-25 13:57 ` H.J. Lu
@ 2021-01-25 13:59 ` Carlos O'Donell
0 siblings, 0 replies; 13+ messages in thread
From: Carlos O'Donell @ 2021-01-25 13:59 UTC (permalink / raw)
To: H.J. Lu; +Cc: Florian Weimer, H.J. Lu via Libc-alpha, Dave Martin, Joseph Myers
On 1/25/21 8:57 AM, H.J. Lu wrote:
> On Mon, Jan 25, 2021 at 5:32 AM Carlos O'Donell <carlos@redhat.com> wrote:
>>
>> On 1/22/21 2:41 PM, H.J. Lu wrote:
>>> Another rebase.
>>
>> Just a note here that v10 does not apply with patchwork automation.
>>
>> This makes things more difficult for my review and automated testing.
>>
>> If possible could you please just resent via git send-email on a new thread?
>>
>> e.g.
>>
>> git format-patch -v 10 ...
>> git send-email ...
>>
>
> Done.
>
Review of v10 is complete.
If in the future you keep using format-patch and send-email it should go
very smoothly. Particularly when we start adding try-bot to automatically
test patches against specification configurations.
--
Cheers,
Carlos.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: V10 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
2021-01-22 19:41 ` V10 " H.J. Lu
2021-01-25 13:31 ` Carlos O'Donell
@ 2021-01-25 13:58 ` Carlos O'Donell
2021-01-25 14:16 ` Florian Weimer
2021-01-25 14:34 ` Carlos O'Donell
1 sibling, 2 replies; 13+ messages in thread
From: Carlos O'Donell @ 2021-01-25 13:58 UTC (permalink / raw)
To: H.J. Lu; +Cc: Florian Weimer, H.J. Lu via Libc-alpha, Dave Martin, Joseph Myers
On 1/22/21 2:41 PM, H.J. Lu wrote:
> On Wed, Jan 20, 2021 at 7:05 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>>
>> On Wed, Jan 20, 2021 at 6:16 AM Carlos O'Donell <carlos@redhat.com> wrote:
>>>
>>> On 11/20/20 6:13 PM, H.J. Lu via Libc-alpha wrote:
>>>> On Fri, Nov 20, 2020 at 6:12 AM Florian Weimer <fw@deneb.enyo.de> wrote:
>>>>>
>>>>> * H. J. Lu:
>>>>>
>>>>>> Can we reach a consensus for _GNU_SOURCE vs _SC_SIGSTKSZ_SOURCE?
>>>>>>
>>>>>> How about we make _GNU_SOURCE to enable _SC_SIGSTKSZ_SOURCE and
>>>>>> check _SC_SIGSTKSZ_SOURCE != 0? If _GNU_SOURCE triggers compilation
>>>>>> error and source codes can't be changed, we can add
>>>>>> -D_SC_SIGSTKSZ_SOURCE=0 to disable _SC_SIGSTKSZ_SOURCE.
>>>>>
>>>>> I think the source code compatibility is much more obscure than the
>>>>> other things we broke quite recently, even without deprecation. Why
>>>>> do we add the complexity in this case? I feel it is disproportional.
>>>>
>>>> Here is the patch with _GNU_SOURCE. Any comments?
>>>
>>> (1) New version of patch.
>>>
>>> This patch no longer compiles due to __cpuid_count errors.
>>>
>>> Could you please update this and post a v9?
>>
>> Fixed.
>>
>>> This is ABI addition for the constants so I want to make sure I review
>>> something that works and is final from your end.
>>>
>>> (2) Kernel definition of constant for AT_MINSIGSTKSZ?
>>>
>>> We don't have a released kernel for x86 with this constant defined?
>>>
>>> The kernel patch was only just updated 5 days ago:
>>> https://sourceware.org/pipermail/libc-alpha/2021-January/121671.html
>>>
>>> Doesn't this mean this patch is inappropriate for glibc 2.33?
>>
>> The new glibc works with the older kernels. In many cases, we
>> use emulation for the older kernels. This patch only uses the
>> existing kernel interface. The kernel patch you referred doesn't
>> add any new interface. It simply uses the existing AT_MINSIGSTKSZ
>> for x86. My patch includes an emulation for the older kernels. I
>> think my patch is appropriate for glibc 2.33.
>>
>> Here is the updated patc.
>>
>> Thanks.
>
> Another rebase.
This change looks good to me.
We add two new constants _SC_MINSIGSTKSZ and _SC_SIGSTKSZ.
We document them as constants to sysconf().
We document _SC_SIGSTKSZ_SOURCE as the way to request this change.
We document this is part of _GNU_SOURCE.
This may break application builds and may need to be worked around if
the application expected static allocation and need to switch to dynamic
allocation of a constant at runtime. This kind of change may not always
be easy to architect, but should be possible with an early constructor.
Tested on i686 and x86_64 and all pass.
Tested-by: Carlos O'Donell <carlos@redhat.com>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
> From 9f040b4540feec52577b660cb151c79cdc2741a3 Mon Sep 17 00:00:00 2001
> From: "H.J. Lu" <hjl.tools@gmail.com>
> Date: Fri, 25 Sep 2020 13:10:08 -0700
> Subject: [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
>
> Add _SC_MINSIGSTKSZ for the minimum signal stack size derived from
> AT_MINSIGSTKSZ, which is the minimum number of bytes of free stack
> space required in order to gurantee successful, non-nested handling
s/gurantee/guarantee/g
> of a single signal whose handler is an empty function, and _SC_SIGSTKSZ
> which is the suggested minimum number of bytes of stack space required
> for a signal stack.
>
> If AT_MINSIGSTKSZ isn't available, sysconf (_SC_MINSIGSTKSZ) returns
> MINSIGSTKSZ. On Linux/x86 with XSAVE, the signal frame used by kernel
> is composed of the following areas and laid out as:
>
> ------------------------------
> | alignment padding |
> ------------------------------
> | xsave buffer |
> ------------------------------
> | fsave header (32-bit only) |
> ------------------------------
> | siginfo + ucontext |
> ------------------------------
>
> Compute AT_MINSIGSTKSZ value as size of xsave buffer + size of fsave
> header (32-bit only) + size of siginfo and ucontext + alignment padding.
>
> If _SC_SIGSTKSZ_SOURCE or _GNU_SOURCE are defined, MINSIGSTKSZ and SIGSTKSZ
> are redefined as
>
> /* 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
OK.
>
> Compilation will fail if the source assumes constant MINSIGSTKSZ or
> SIGSTKSZ.
OK.
>
> The reason for not simply increasing the kernel's MINSIGSTKSZ #define
> (apart from the fact that it is rarely used, due to glibc's shadowing
> definitions) was that userspace binaries will have baked in the old
> value of the constant and may be making assumptions about it.
OK. Yes, we need to stop baking this into applications. There may be
some teething pain if constant-sized objects need to switch to be
dynamically sized? This worries me a little bit, but the rare usage
of this constant means the impact will be low.
> For example, the type (char [MINSIGSTKSZ]) changes if this #define
> changes. This could be a problem if an newly built library tries to
> memcpy() or dump such an object defined by and old binary.
> Bounds-checking and the stack sizes passed to things like sigaltstack()
> and makecontext() could similarly go wrong.
OK. Correct. This is always the case and why it's ABI.
> ---
> NEWS | 5 ++
> bits/confname.h | 8 +-
> bits/sigstksz.h | 21 +++++
> elf/dl-support.c | 5 ++
> elf/dl-sysdep.c | 9 ++
> include/bits/sigstack.h | 5 ++
> include/bits/sigstksz.h | 7 ++
> include/features.h | 11 +++
> manual/conf.texi | 21 +++++
> manual/creature.texi | 6 ++
> posix/sysconf.c | 3 +
> signal/Makefile | 5 +-
> signal/signal.h | 1 +
> signal/tst-minsigstksz-5.c | 84 +++++++++++++++++++
> sysdeps/generic/ldsodefs.h | 3 +
> sysdeps/unix/sysv/linux/bits/sigstksz.h | 33 ++++++++
> .../unix/sysv/linux/ia64/sysconf-sigstksz.h | 27 ++++++
> sysdeps/unix/sysv/linux/sysconf-sigstksz.h | 38 +++++++++
> sysdeps/unix/sysv/linux/sysconf.c | 9 ++
> .../unix/sysv/linux/x86/dl-minsigstacksize.h | 83 ++++++++++++++++++
> .../sysv/linux/x86/include/bits/sigstack.h | 5 ++
> sysdeps/x86/cpu-features.c | 3 +
> sysdeps/x86/dl-minsigstacksize.h | 27 ++++++
> 23 files changed, 416 insertions(+), 3 deletions(-)
> create mode 100644 bits/sigstksz.h
> create mode 100644 include/bits/sigstack.h
> create mode 100644 include/bits/sigstksz.h
> create mode 100644 signal/tst-minsigstksz-5.c
> create mode 100644 sysdeps/unix/sysv/linux/bits/sigstksz.h
> create mode 100644 sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h
> create mode 100644 sysdeps/unix/sysv/linux/sysconf-sigstksz.h
> create mode 100644 sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h
> create mode 100644 sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h
> create mode 100644 sysdeps/x86/dl-minsigstacksize.h
>
> diff --git a/NEWS b/NEWS
> index d121f7df87..0758bb37e3 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -9,6 +9,11 @@ Version 2.33
>
> 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).
OK.
> +
> * 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).
> diff --git a/bits/confname.h b/bits/confname.h
> index 8068bda273..ec6cd07957 100644
> --- a/bits/confname.h
> +++ b/bits/confname.h
> @@ -525,8 +525,14 @@ enum
>
> _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
OK.
> +
> + _SC_SIGSTKSZ
> +#define _SC_SIGSTKSZ _SC_SIGSTKSZ
OK.
> };
>
> /* Values for the NAME argument to `confstr'. */
> diff --git a/bits/sigstksz.h b/bits/sigstksz.h
> new file mode 100644
> index 0000000000..5535d873b5
> --- /dev/null
> +++ b/bits/sigstksz.h
> @@ -0,0 +1,21 @@
> +/* Definition of MINSIGSTKSZ. Generic version.
> + Copyright (C) 2020 Free Software Foundation, Inc.
s/2020/2021/g
> + 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
> diff --git a/elf/dl-support.c b/elf/dl-support.c
> index 7abb65d8e3..7fc2ee78e2 100644
> --- a/elf/dl-support.c
> +++ b/elf/dl-support.c
> @@ -142,6 +142,8 @@ void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
>
> size_t _dl_pagesize = EXEC_PAGESIZE;
>
> +size_t _dl_minsigstacksize = CONSTANT_MINSIGSTKSZ;
OK. Constant default value.
> +
> int _dl_inhibit_cache;
>
> unsigned int _dl_osversion;
> @@ -307,6 +309,9 @@ _dl_aux_init (ElfW(auxv_t) *av)
> case AT_RANDOM:
> _dl_random = (void *) av->a_un.a_val;
> break;
> + case AT_MINSIGSTKSZ:
> + _dl_minsigstacksize = av->a_un.a_val;
OK. Fetch from the kernel.
> + break;
> DL_PLATFORM_AUXV
> }
> if (seen == 0xf)
> diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c
> index 0658c17da6..bd5066fe3b 100644
> --- a/elf/dl-sysdep.c
> +++ b/elf/dl-sysdep.c
> @@ -115,6 +115,11 @@ _dl_sysdep_start (void **start_argptr,
> 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;
OK.
> +
> for (av = GLRO(dl_auxv); av->a_type != AT_NULL; set_seen (av++))
> switch (av->a_type)
> {
> @@ -179,6 +184,9 @@ _dl_sysdep_start (void **start_argptr,
> case AT_RANDOM:
> _dl_random = (void *) av->a_un.a_val;
> break;
> + case AT_MINSIGSTKSZ:
> + GLRO(dl_minsigstacksize) = av->a_un.a_val;
> + break;
OK.
> DL_PLATFORM_AUXV
> }
>
> @@ -306,6 +314,7 @@ _dl_show_auxv (void)
> [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 },
OK.
> [AT_L1I_CACHESIZE - 2] = { "L1I_CACHESIZE: ", dec },
> [AT_L1I_CACHEGEOMETRY - 2] = { "L1I_CACHEGEOMETRY: 0x", hex },
> [AT_L1D_CACHESIZE - 2] = { "L1D_CACHESIZE: ", dec },
> diff --git a/include/bits/sigstack.h b/include/bits/sigstack.h
> new file mode 100644
> index 0000000000..eea939f59d
> --- /dev/null
> +++ b/include/bits/sigstack.h
> @@ -0,0 +1,5 @@
> +#include_next <bits/sigstack.h>
> +
> +#if !defined _ISOMAC && !defined CONSTANT_MINSIGSTKSZ
> +# define CONSTANT_MINSIGSTKSZ MINSIGSTKSZ
OK. Define constant to old MINSIGSTKSZ. Reasonable enough.
> +#endif
> diff --git a/include/bits/sigstksz.h b/include/bits/sigstksz.h
> new file mode 100644
> index 0000000000..2ca891e918
> --- /dev/null
> +++ b/include/bits/sigstksz.h
> @@ -0,0 +1,7 @@
> +/* 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
OK.
> diff --git a/include/features.h b/include/features.h
> index a71ac85af4..cc05a31ae1 100644
> --- a/include/features.h
> +++ b/include/features.h
> @@ -48,6 +48,8 @@
> _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.
OK. We could argue all day what to call this, and this name is sufficient
to indicate and document what it means.
> _GNU_SOURCE All of the above, plus GNU extensions.
> _DEFAULT_SOURCE The default set of features (taking precedence over
> __STRICT_ANSI__).
> @@ -94,6 +96,8 @@
> __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.
OK.
> __USE_GNU Define GNU extensions.
> __USE_FORTIFY_LEVEL Additional security measures used, according to level.
>
> @@ -137,6 +141,7 @@
> #undef __USE_FILE_OFFSET64
> #undef __USE_MISC
> #undef __USE_ATFILE
> +#undef __USE_SC_SIGSTKSZ
OK.
> #undef __USE_GNU
> #undef __USE_FORTIFY_LEVEL
> #undef __KERNEL_STRICT_NAMES
> @@ -213,6 +218,8 @@
> # define _DEFAULT_SOURCE 1
> # undef _ATFILE_SOURCE
> # define _ATFILE_SOURCE 1
> +# undef _SC_SIGSTKSZ_SOURCE
> +# define _SC_SIGSTKSZ_SOURCE 1
OK.
> #endif
>
> /* If nothing (other than _GNU_SOURCE and _DEFAULT_SOURCE) is defined,
> @@ -388,6 +395,10 @@
> # define __USE_ATFILE 1
> #endif
>
> +#ifdef _SC_SIGSTKSZ_SOURCE
> +# define __USE_SC_SIGSTKSZ 1
OK. Set __USE_* from top-level feature.
> +#endif
> +
> #ifdef _GNU_SOURCE
> # define __USE_GNU 1
> #endif
> diff --git a/manual/conf.texi b/manual/conf.texi
> index f959b00bb6..ba9847aaa4 100644
> --- a/manual/conf.texi
> +++ b/manual/conf.texi
> @@ -913,6 +913,27 @@ Inquire about the parameter corresponding to @code{NL_SETMAX}.
> @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.
OK.
> +
> +@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).
OK.
> +
> +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.
OK.
> @end vtable
>
> @node Examples of Sysconf
> diff --git a/manual/creature.texi b/manual/creature.texi
> index 31208ccb2b..5090735e4f 100644
> --- a/manual/creature.texi
> +++ b/manual/creature.texi
> @@ -258,6 +258,12 @@ checks are applied. If defined to @math{3}, @theglibc{} may also use
> 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.
OK.
> +@end defvr
> +
> @defvr Macro _REENTRANT
> @defvrx Macro _THREAD_SAFE
> @standards{Obsolete, (none)}
> diff --git a/posix/sysconf.c b/posix/sysconf.c
> index bb9e132e5c..67d17ca0f8 100644
> --- a/posix/sysconf.c
> +++ b/posix/sysconf.c
> @@ -266,6 +266,9 @@ __sysconf (int name)
> case _SC_XOPEN_REALTIME:
> case _SC_XOPEN_REALTIME_THREADS:
>
> + case _SC_MINSIGSTKSZ:
> + case _SC_SIGSTKSZ:
OK.
> +
> break;
> }
>
> diff --git a/signal/Makefile b/signal/Makefile
> index e89c308889..3d8cab1f50 100644
> --- a/signal/Makefile
> +++ b/signal/Makefile
> @@ -31,7 +31,8 @@ headers := signal.h sys/signal.h \
> 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
OK.
>
> routines := signal raise killpg \
> sigaction sigprocmask kill \
> @@ -48,7 +49,7 @@ routines := signal raise killpg \
> 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 \
OK.
> tst-sigisemptyset
>
> include ../Rules
> diff --git a/signal/signal.h b/signal/signal.h
> index 6463c98e11..b17203c99c 100644
> --- a/signal/signal.h
> +++ b/signal/signal.h
> @@ -312,6 +312,7 @@ extern int siginterrupt (int __sig, int __interrupt) __THROW
> __attribute_deprecated_msg__ ("Use sigaction with SA_RESTART instead");
>
> # include <bits/sigstack.h>
> +# include <bits/sigstksz.h>
OK.
> # include <bits/ss_flags.h>
>
> /* Alternate signal handler stack interface.
> diff --git a/signal/tst-minsigstksz-5.c b/signal/tst-minsigstksz-5.c
> new file mode 100644
> index 0000000000..d657d2f4e6
> --- /dev/null
> +++ b/signal/tst-minsigstksz-5.c
> @@ -0,0 +1,84 @@
> +/* Test of signal delivery on an alternate stack with MINSIGSTKSZ size.
> + Copyright (C) 2020 Free Software Foundation, Inc.
s/2020/2021/g
> + 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,
OK. All these references are sysconf-based now.
> + };
> + 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;
> +}
OK.
> +
> +#include <support/test-driver.c>
> diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
> index aab7245e93..9720a4e446 100644
> --- a/sysdeps/generic/ldsodefs.h
> +++ b/sysdeps/generic/ldsodefs.h
> @@ -536,6 +536,9 @@ struct rtld_global_ro
> /* Cached value of `getpagesize ()'. */
> EXTERN size_t _dl_pagesize;
>
> + /* Cached value of `sysconf (_SC_MINSIGSTKSZ)'. */
> + EXTERN size_t _dl_minsigstacksize;
OK.
> +
> /* Do we read from ld.so.cache? */
> EXTERN int _dl_inhibit_cache;
>
> diff --git a/sysdeps/unix/sysv/linux/bits/sigstksz.h b/sysdeps/unix/sysv/linux/bits/sigstksz.h
> new file mode 100644
> index 0000000000..926508f2b4
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/bits/sigstksz.h
> @@ -0,0 +1,33 @@
> +/* Definition of MINSIGSTKSZ and SIGSTKSZ. Linux version.
> + Copyright (C) 2020 Free Software Foundation, Inc.
s/2020/2021/g
> + 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
OK.
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h b/sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h
> new file mode 100644
> index 0000000000..7e5ceba151
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/ia64/sysconf-sigstksz.h
> @@ -0,0 +1,27 @@
> +/* sysconf_sigstksz (). Linux/ia64 version.
> + Copyright (C) 2020 Free Software Foundation, Inc.
s/2020/2021/g
> + 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;
OK.
> +}
> diff --git a/sysdeps/unix/sysv/linux/sysconf-sigstksz.h b/sysdeps/unix/sysv/linux/sysconf-sigstksz.h
> new file mode 100644
> index 0000000000..64d450b22c
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/sysconf-sigstksz.h
> @@ -0,0 +1,38 @@
> +/* 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. */
OK. Return the max of the constant or sysconf value times 4 to allow some
nested signals.
> + 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;
OK.
> +}
> diff --git a/sysdeps/unix/sysv/linux/sysconf.c b/sysdeps/unix/sysv/linux/sysconf.c
> index bfad5b6858..366fcef01e 100644
> --- a/sysdeps/unix/sysv/linux/sysconf.c
> +++ b/sysdeps/unix/sysv/linux/sysconf.c
> @@ -16,6 +16,7 @@
> 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>
> @@ -26,6 +27,7 @@
> #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. */
> @@ -75,6 +77,13 @@ __sysconf (int name)
> }
> break;
>
> + case _SC_MINSIGSTKSZ:
> + assert (GLRO(dl_minsigstacksize) != 0);
> + return GLRO(dl_minsigstacksize);
OK.
> +
> + case _SC_SIGSTKSZ:
> + return sysconf_sigstksz ();
OK.
> +
> default:
> break;
> }
> diff --git a/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h b/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h
> new file mode 100644
> index 0000000000..6088bbc99e
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/dl-minsigstacksize.h
> @@ -0,0 +1,83 @@
> +/* 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;
OK. Cached.
> +
> + 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;
OK.
> + }
> + else
> + {
> + /* NB: Default to a constant MINSIGSTKSZ. */
> + _Static_assert (__builtin_constant_p (MINSIGSTKSZ),
> + "MINSIGSTKSZ is constant");
> + GLRO(dl_minsigstacksize) = MINSIGSTKSZ;
OK.
> + }
> +}
> diff --git a/sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h b/sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h
> new file mode 100644
> index 0000000000..208754c497
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/x86/include/bits/sigstack.h
> @@ -0,0 +1,5 @@
> +#include_next <bits/sigstack.h>
> +
> +#ifndef _ISOMAC
> +# define CONSTANT_MINSIGSTKSZ 0
> +#endif
OK.
> diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
> index 6496512a0d..dfeca31967 100644
> --- a/sysdeps/x86/cpu-features.c
> +++ b/sysdeps/x86/cpu-features.c
> @@ -21,6 +21,7 @@
> #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 *)
> @@ -362,6 +363,8 @@ get_common_indices (struct cpu_features *cpu_features,
> 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);
OK.
> }
>
> _Static_assert (((index_arch_Fast_Unaligned_Load
> diff --git a/sysdeps/x86/dl-minsigstacksize.h b/sysdeps/x86/dl-minsigstacksize.h
> new file mode 100644
> index 0000000000..959871c970
> --- /dev/null
> +++ b/sysdeps/x86/dl-minsigstacksize.h
> @@ -0,0 +1,27 @@
> +/* 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;
OK.
> +}
> --
> 2.29.2
>
--
Cheers,
Carlos.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: V10 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
2021-01-25 13:58 ` Carlos O'Donell
@ 2021-01-25 14:16 ` Florian Weimer
2021-02-02 13:08 ` Carlos O'Donell
2021-01-25 14:34 ` Carlos O'Donell
1 sibling, 1 reply; 13+ messages in thread
From: Florian Weimer @ 2021-01-25 14:16 UTC (permalink / raw)
To: Carlos O'Donell via Libc-alpha
Cc: H.J. Lu, Carlos O'Donell, Florian Weimer, Dave Martin, Joseph Myers
* Carlos O'Donell via Libc-alpha:
> We document _SC_SIGSTKSZ_SOURCE as the way to request this change.
I have previously objected to _SC_SIGSTKSZ_SOURCE. I still it's wrong.
We haven't done anything like that in a long time. All other recent
features have been enabled by _GNU_SOURCE, even world-breaking ones,
like the math TS macros and functions.
Thanks,
Florian
--
Red Hat GmbH, https://de.redhat.com/ , Registered seat: Grasbrunn,
Commercial register: Amtsgericht Muenchen, HRB 153243,
Managing Directors: Charles Cachera, Brian Klemm, Laurie Krebs, Michael O'Neill
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: V10 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
2021-01-25 14:16 ` Florian Weimer
@ 2021-02-02 13:08 ` Carlos O'Donell
0 siblings, 0 replies; 13+ messages in thread
From: Carlos O'Donell @ 2021-02-02 13:08 UTC (permalink / raw)
To: Florian Weimer, Carlos O'Donell via Libc-alpha
Cc: H.J. Lu, Florian Weimer, Dave Martin, Joseph Myers
On 1/25/21 9:16 AM, Florian Weimer wrote:
> * Carlos O'Donell via Libc-alpha:
>
>> We document _SC_SIGSTKSZ_SOURCE as the way to request this change.
>
> I have previously objected to _SC_SIGSTKSZ_SOURCE. I still it's wrong.
> We haven't done anything like that in a long time. All other recent
> features have been enabled by _GNU_SOURCE, even world-breaking ones,
> like the math TS macros and functions.
I didn't see your objection during my review of the patch. Thank you
for stating it again.
I purposely moved this patch out of glibc 2.33 so we could have more
time to use this before the release.
Do you have a pointer to your original objection with notes about why
you object?
--
Cheers,
Carlos.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: V10 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305]
2021-01-25 13:58 ` Carlos O'Donell
2021-01-25 14:16 ` Florian Weimer
@ 2021-01-25 14:34 ` Carlos O'Donell
1 sibling, 0 replies; 13+ messages in thread
From: Carlos O'Donell @ 2021-01-25 14:34 UTC (permalink / raw)
To: H.J. Lu; +Cc: Florian Weimer, H.J. Lu via Libc-alpha, Dave Martin, Joseph Myers
On 1/25/21 8:58 AM, Carlos O'Donell wrote:
> On 1/22/21 2:41 PM, H.J. Lu wrote:
>> On Wed, Jan 20, 2021 at 7:05 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>>>
>>> On Wed, Jan 20, 2021 at 6:16 AM Carlos O'Donell <carlos@redhat.com> wrote:
>>>>
>>>> On 11/20/20 6:13 PM, H.J. Lu via Libc-alpha wrote:
>>>>> On Fri, Nov 20, 2020 at 6:12 AM Florian Weimer <fw@deneb.enyo.de> wrote:
>>>>>>
>>>>>> * H. J. Lu:
>>>>>>
>>>>>>> Can we reach a consensus for _GNU_SOURCE vs _SC_SIGSTKSZ_SOURCE?
>>>>>>>
>>>>>>> How about we make _GNU_SOURCE to enable _SC_SIGSTKSZ_SOURCE and
>>>>>>> check _SC_SIGSTKSZ_SOURCE != 0? If _GNU_SOURCE triggers compilation
>>>>>>> error and source codes can't be changed, we can add
>>>>>>> -D_SC_SIGSTKSZ_SOURCE=0 to disable _SC_SIGSTKSZ_SOURCE.
>>>>>>
>>>>>> I think the source code compatibility is much more obscure than the
>>>>>> other things we broke quite recently, even without deprecation. Why
>>>>>> do we add the complexity in this case? I feel it is disproportional.
>>>>>
>>>>> Here is the patch with _GNU_SOURCE. Any comments?
>>>>
>>>> (1) New version of patch.
>>>>
>>>> This patch no longer compiles due to __cpuid_count errors.
>>>>
>>>> Could you please update this and post a v9?
>>>
>>> Fixed.
>>>
>>>> This is ABI addition for the constants so I want to make sure I review
>>>> something that works and is final from your end.
>>>>
>>>> (2) Kernel definition of constant for AT_MINSIGSTKSZ?
>>>>
>>>> We don't have a released kernel for x86 with this constant defined?
>>>>
>>>> The kernel patch was only just updated 5 days ago:
>>>> https://sourceware.org/pipermail/libc-alpha/2021-January/121671.html
>>>>
>>>> Doesn't this mean this patch is inappropriate for glibc 2.33?
>>>
>>> The new glibc works with the older kernels. In many cases, we
>>> use emulation for the older kernels. This patch only uses the
>>> existing kernel interface. The kernel patch you referred doesn't
>>> add any new interface. It simply uses the existing AT_MINSIGSTKSZ
>>> for x86. My patch includes an emulation for the older kernels. I
>>> think my patch is appropriate for glibc 2.33.
>>>
>>> Here is the updated patc.
>>>
>>> Thanks.
>>
>> Another rebase.
>
> This change looks good to me.
>
> We add two new constants _SC_MINSIGSTKSZ and _SC_SIGSTKSZ.
>
> We document them as constants to sysconf().
>
> We document _SC_SIGSTKSZ_SOURCE as the way to request this change.
>
> We document this is part of _GNU_SOURCE.
>
> This may break application builds and may need to be worked around if
> the application expected static allocation and need to switch to dynamic
> allocation of a constant at runtime. This kind of change may not always
> be easy to architect, but should be possible with an early constructor.
>
> Tested on i686 and x86_64 and all pass.
>
> Tested-by: Carlos O'Donell <carlos@redhat.com>
> Reviewed-by: Carlos O'Donell <carlos@redhat.com>
This was discussed on the weekly patch review meeting.
HJ and I agreed we would delay this until 2.34 opens.
Likewise the deprecation.
I will add a NEWS item that we are going to do this deprecation.
--
Cheers,
Carlos.
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2021-07-19 21:06 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-25 13:53 V10 [PATCH] sysconf: Add _SC_MINSIGSTKSZ/_SC_SIGSTKSZ [BZ #20305] H.J. Lu
2021-07-19 10:10 ` Andreas Schwab
2021-07-19 21:06 ` Paul Eggert
2021-07-19 11:09 ` Andreas Schwab
2021-07-19 21:06 ` Paul Eggert
-- strict thread matches above, loose matches on Subject: below --
2020-11-04 16:50 PING: V7 " Dave Martin
2020-11-04 17:48 ` H.J. Lu
2020-11-18 14:13 ` H.J. Lu
2020-11-18 14:25 ` Zack Weinberg
2020-11-18 14:40 ` H.J. Lu
2020-11-18 15:12 ` Zack Weinberg
2020-11-18 15:17 ` H.J. Lu
2020-11-18 15:20 ` Florian Weimer
2020-11-18 17:04 ` Dave Martin
2020-11-18 17:35 ` Florian Weimer
2020-11-18 18:09 ` Dave Martin
2020-11-20 14:08 ` H.J. Lu
2020-11-20 14:11 ` Florian Weimer
2020-11-20 23:13 ` V8 " H.J. Lu
2021-01-20 14:16 ` Carlos O'Donell
2021-01-20 15:05 ` V9 " H.J. Lu
2021-01-22 19:41 ` V10 " H.J. Lu
2021-01-25 13:31 ` Carlos O'Donell
2021-01-25 13:57 ` H.J. Lu
2021-01-25 13:59 ` Carlos O'Donell
2021-01-25 13:58 ` Carlos O'Donell
2021-01-25 14:16 ` Florian Weimer
2021-02-02 13:08 ` Carlos O'Donell
2021-01-25 14:34 ` Carlos O'Donell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).