| |
@@ -0,0 +1,661 @@
|
| |
+ From 7c4f74761089177127c2cfe6685b7886aa231885 Mon Sep 17 00:00:00 2001
|
| |
+ From: Colin Ian King <colin.king@canonical.com>
|
| |
+ Date: Thu, 25 Feb 2021 00:33:17 +0000
|
| |
+ Subject: [PATCH] stack handling: use _SC_SIGSTKSZ and _SC_MINSIGSTKSZ
|
| |
+
|
| |
+ New versions of glibc will define SIGSTKSZ and MINSTKSZ
|
| |
+ on the sysconf values for _SC_SIGSTKSZ and _SC_MINSIGSTKSZ
|
| |
+ respectively. Define two helper functions to determine the
|
| |
+ stack sizes by trying to use cached sysconf values, fetching
|
| |
+ and caching the sysconf values or falling back to the
|
| |
+ traditional SIGSTKSZ or MINSTKSZ defined values, or hard
|
| |
+ coded 8K limits if all else fails.
|
| |
+
|
| |
+ Define STRESS_SIGSTKSZ and STRESS_MINSTKSZ that call the
|
| |
+ helper functions and hide the details. Since these sizes
|
| |
+ are dynamic, replace all statically allocated and stack
|
| |
+ allocated alternative stacks with mmap'd versions and add
|
| |
+ in allocation failure error handling.
|
| |
+
|
| |
+ Finally remove the MLOCKED_DATA macros now that the mlocked
|
| |
+ alt stacks are no longer used.
|
| |
+
|
| |
+ Signed-off-by: Colin Ian King <colin.king@canonical.com>
|
| |
+ ---
|
| |
+ core-helper.c | 85 +++++++++++++++++++++++++++++++++----------
|
| |
+ stress-bad-altstack.c | 39 ++++++++++----------
|
| |
+ stress-context.c | 19 +++++++---
|
| |
+ stress-ng.c | 3 --
|
| |
+ stress-ng.h | 10 ++++-
|
| |
+ stress-rlimit.c | 15 +++++++-
|
| |
+ stress-stack.c | 18 ++++-----
|
| |
+ stress-stackmmap.c | 70 ++++++++++++++++++++---------------
|
| |
+ stress-vforkmany.c | 14 +++++--
|
| |
+ 9 files changed, 180 insertions(+), 93 deletions(-)
|
| |
+
|
| |
+ diff --git a/core-helper.c b/core-helper.c
|
| |
+ index 2c009e53..bc9e4bea 100644
|
| |
+ --- a/core-helper.c
|
| |
+ +++ b/core-helper.c
|
| |
+ @@ -1338,12 +1338,12 @@ int stress_sigaltstack(const void *stack, const size_t size)
|
| |
+ #if defined(HAVE_SIGALTSTACK)
|
| |
+ stack_t ss;
|
| |
+
|
| |
+ - if (size < (size_t)MINSIGSTKSZ) {
|
| |
+ + if (size < (size_t)STRESS_MINSIGSTKSZ) {
|
| |
+ pr_err("sigaltstack stack size %zu must be more than %zuK\n",
|
| |
+ - size, (size_t)MINSIGSTKSZ / 1024);
|
| |
+ + size, (size_t)STRESS_MINSIGSTKSZ / 1024);
|
| |
+ return -1;
|
| |
+ }
|
| |
+ - ss.ss_sp = stress_align_address(stack, STACK_ALIGNMENT);
|
| |
+ + ss.ss_sp = (void *)stack;
|
| |
+ ss.ss_size = size;
|
| |
+ ss.ss_flags = 0;
|
| |
+ if (sigaltstack(&ss, NULL) < 0) {
|
| |
+ @@ -1370,22 +1370,23 @@ int stress_sighandler(
|
| |
+ {
|
| |
+ struct sigaction new_action;
|
| |
+ #if defined(HAVE_SIGALTSTACK)
|
| |
+ - static bool set_altstack = false;
|
| |
+ -
|
| |
+ - /*
|
| |
+ - * Signal handlers should really be using an alternative
|
| |
+ - * signal stack to be totally safe. For any new instance we
|
| |
+ - * should set this alternative signal stack before setting
|
| |
+ - * up any signal handler. We only need to do this once
|
| |
+ - * per process instance, so just do it on the first
|
| |
+ - * call to stress_sighandler.
|
| |
+ - */
|
| |
+ - if (!set_altstack) {
|
| |
+ - static uint8_t MLOCKED_DATA stack[SIGSTKSZ + STACK_ALIGNMENT];
|
| |
+ -
|
| |
+ - if (stress_sigaltstack(stack, SIGSTKSZ) < 0)
|
| |
+ - return -1;
|
| |
+ - set_altstack = true;
|
| |
+ + {
|
| |
+ + static uint8_t *stack = NULL;
|
| |
+ +
|
| |
+ + if (stack == NULL) {
|
| |
+ + /* Allocate stack, we currently leak this */
|
| |
+ + stack = mmap(NULL, STRESS_SIGSTKSZ, PROT_READ | PROT_WRITE,
|
| |
+ + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
| |
+ + if (stack == MAP_FAILED) {
|
| |
+ + pr_inf("%s: sigaction %s: cannot allocated signal stack, "
|
| |
+ + "errno = %d (%s)\n",
|
| |
+ + name, stress_strsignal(signum),
|
| |
+ + errno, strerror(errno));
|
| |
+ + return -1;
|
| |
+ + }
|
| |
+ + if (stress_sigaltstack(stack, STRESS_SIGSTKSZ) < 0)
|
| |
+ + return -1;
|
| |
+ + }
|
| |
+ }
|
| |
+ #endif
|
| |
+ (void)memset(&new_action, 0, sizeof new_action);
|
| |
+ @@ -2274,3 +2275,49 @@ size_t stress_hostname_length(void)
|
| |
+ return 255 + 1; /* SUSv2 */
|
| |
+ #endif
|
| |
+ }
|
| |
+ +
|
| |
+ +/*
|
| |
+ + * stress_sig_stack_size()
|
| |
+ + * wrapper for STRESS_SIGSTKSZ
|
| |
+ + */
|
| |
+ +size_t stress_sig_stack_size(void)
|
| |
+ +{
|
| |
+ +#if defined(_SC_SIGSTKSZ)
|
| |
+ + {
|
| |
+ + static long sz = -1;
|
| |
+ +
|
| |
+ + if (sz < 0)
|
| |
+ + sz = sysconf(_SC_SIGSTKSZ);
|
| |
+ + if (sz > 0)
|
| |
+ + return (size_t)sz;
|
| |
+ + }
|
| |
+ +#endif
|
| |
+ +#if defined(SIGSTKSZ)
|
| |
+ + return SIGSTKSZ;
|
| |
+ +#else
|
| |
+ + return (8192);
|
| |
+ +#endif
|
| |
+ +}
|
| |
+ +
|
| |
+ +/*
|
| |
+ + * stress_min_sig_stack_size()
|
| |
+ + * wrapper for STRESS_MINSIGSTKSZ
|
| |
+ + */
|
| |
+ +size_t stress_min_sig_stack_size(void)
|
| |
+ +{
|
| |
+ +#if defined(_SC_MINSIGSTKSZ)
|
| |
+ + {
|
| |
+ + static long sz = -1;
|
| |
+ +
|
| |
+ + if (sz < 0)
|
| |
+ + sz = sysconf(_SC_MINSIGSTKSZ);
|
| |
+ + if (sz > 0)
|
| |
+ + return (size_t)sz;
|
| |
+ + }
|
| |
+ +#endif
|
| |
+ +#if defined(MINSIGSTKSZ)
|
| |
+ + return MINSIGSTKSZ;
|
| |
+ +#else
|
| |
+ + return (8192);
|
| |
+ +#endif
|
| |
+ +}
|
| |
+ diff --git a/stress-bad-altstack.c b/stress-bad-altstack.c
|
| |
+ index e6509be8..e698c3bd 100644
|
| |
+ --- a/stress-bad-altstack.c
|
| |
+ +++ b/stress-bad-altstack.c
|
| |
+ @@ -41,7 +41,6 @@ static const stress_help_t help[] =
|
| |
+
|
| |
+ static void *stack;
|
| |
+ static void *zero_stack;
|
| |
+ -static const size_t stack_sz = MINSIGSTKSZ;
|
| |
+ static sigjmp_buf jmpbuf;
|
| |
+
|
| |
+ static inline void stress_bad_altstack_force_fault(uint8_t *stack_start)
|
| |
+ @@ -56,15 +55,15 @@ static inline void stress_bad_altstack_force_fault(uint8_t *stack_start)
|
| |
+
|
| |
+ static void MLOCKED_TEXT stress_segv_handler(int signum)
|
| |
+ {
|
| |
+ - uint8_t data[MINSIGSTKSZ * 2];
|
| |
+ + uint8_t data[STRESS_MINSIGSTKSZ * 2];
|
| |
+
|
| |
+ (void)signum;
|
| |
+ - (void)munmap(stack, stack_sz);
|
| |
+ + (void)munmap(stack, STRESS_MINSIGSTKSZ);
|
| |
+ (void)memset(data, 0xff, sizeof(data));
|
| |
+ stress_uint8_put(data[0]);
|
| |
+
|
| |
+ if (zero_stack != MAP_FAILED)
|
| |
+ - (void)munmap(zero_stack, stack_sz);
|
| |
+ + (void)munmap(zero_stack, STRESS_MINSIGSTKSZ);
|
| |
+
|
| |
+ /*
|
| |
+ * If we've not got this far we've not
|
| |
+ @@ -88,7 +87,7 @@ static int stress_bad_altstack(const stress_args_t *args)
|
| |
+ #endif
|
| |
+ int fd;
|
| |
+
|
| |
+ - stack = mmap(NULL, stack_sz, PROT_READ | PROT_WRITE,
|
| |
+ + stack = mmap(NULL, STRESS_MINSIGSTKSZ, PROT_READ | PROT_WRITE,
|
| |
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
| |
+ if (stack == MAP_FAILED) {
|
| |
+ pr_err("%s: cannot mmap signal handler stack, errno=%d (%s)\n",
|
| |
+ @@ -98,7 +97,7 @@ static int stress_bad_altstack(const stress_args_t *args)
|
| |
+
|
| |
+ fd = open("/dev/zero", O_RDONLY);
|
| |
+ if (fd >= 0) {
|
| |
+ - zero_stack = mmap(NULL, stack_sz, PROT_READ,
|
| |
+ + zero_stack = mmap(NULL, STRESS_MINSIGSTKSZ, PROT_READ,
|
| |
+ MAP_PRIVATE, fd, 0);
|
| |
+ (void)close(fd);
|
| |
+ } else {
|
| |
+ @@ -176,13 +175,13 @@ static int stress_bad_altstack(const stress_args_t *args)
|
| |
+
|
| |
+ /* Exercise disable SS_DISABLE */
|
| |
+ ss.ss_sp = stress_align_address(stack, STACK_ALIGNMENT);
|
| |
+ - ss.ss_size = MINSIGSTKSZ;
|
| |
+ + ss.ss_size = STRESS_MINSIGSTKSZ;
|
| |
+ ss.ss_flags = SS_DISABLE;
|
| |
+ (void)sigaltstack(&ss, NULL);
|
| |
+
|
| |
+ /* Exercise invalid flags */
|
| |
+ ss.ss_sp = stress_align_address(stack, STACK_ALIGNMENT);
|
| |
+ - ss.ss_size = MINSIGSTKSZ;
|
| |
+ + ss.ss_size = STRESS_MINSIGSTKSZ;
|
| |
+ ss.ss_flags = ~0;
|
| |
+ (void)sigaltstack(&ss, NULL);
|
| |
+
|
| |
+ @@ -191,7 +190,7 @@ static int stress_bad_altstack(const stress_args_t *args)
|
| |
+
|
| |
+ /* Exercise less than minimum allowed stack size, ENOMEM */
|
| |
+ ss.ss_sp = stress_align_address(stack, STACK_ALIGNMENT);
|
| |
+ - ss.ss_size = MINSIGSTKSZ - 1;
|
| |
+ + ss.ss_size = STRESS_MINSIGSTKSZ - 1;
|
| |
+ ss.ss_flags = 0;
|
| |
+ (void)sigaltstack(&ss, NULL);
|
| |
+
|
| |
+ @@ -199,7 +198,7 @@ static int stress_bad_altstack(const stress_args_t *args)
|
| |
+ return EXIT_FAILURE;
|
| |
+
|
| |
+ /* Set alternative stack for testing */
|
| |
+ - if (stress_sigaltstack(stack, stack_sz) < 0)
|
| |
+ + if (stress_sigaltstack(stack, STRESS_MINSIGSTKSZ) < 0)
|
| |
+ return EXIT_FAILURE;
|
| |
+
|
| |
+ /* Child */
|
| |
+ @@ -214,7 +213,7 @@ static int stress_bad_altstack(const stress_args_t *args)
|
| |
+ #if defined(HAVE_MPROTECT)
|
| |
+ case 1:
|
| |
+ /* Illegal stack with no protection */
|
| |
+ - ret = mprotect(stack, stack_sz, PROT_NONE);
|
| |
+ + ret = mprotect(stack, STRESS_MINSIGSTKSZ, PROT_NONE);
|
| |
+ if (ret == 0)
|
| |
+ stress_bad_altstack_force_fault(stack);
|
| |
+ if (!keep_stressing(args))
|
| |
+ @@ -222,7 +221,7 @@ static int stress_bad_altstack(const stress_args_t *args)
|
| |
+ CASE_FALLTHROUGH;
|
| |
+ case 2:
|
| |
+ /* Illegal read-only stack */
|
| |
+ - ret = mprotect(stack, stack_sz, PROT_READ);
|
| |
+ + ret = mprotect(stack, STRESS_MINSIGSTKSZ, PROT_READ);
|
| |
+ if (ret == 0)
|
| |
+ stress_bad_altstack_force_fault(stack);
|
| |
+ if (!keep_stressing(args))
|
| |
+ @@ -230,7 +229,7 @@ static int stress_bad_altstack(const stress_args_t *args)
|
| |
+ CASE_FALLTHROUGH;
|
| |
+ case 3:
|
| |
+ /* Illegal exec-only stack */
|
| |
+ - ret = mprotect(stack, stack_sz, PROT_EXEC);
|
| |
+ + ret = mprotect(stack, STRESS_MINSIGSTKSZ, PROT_EXEC);
|
| |
+ if (ret == 0)
|
| |
+ stress_bad_altstack_force_fault(stack);
|
| |
+ if (!keep_stressing(args))
|
| |
+ @@ -239,7 +238,7 @@ static int stress_bad_altstack(const stress_args_t *args)
|
| |
+ #endif
|
| |
+ case 4:
|
| |
+ /* Illegal NULL stack */
|
| |
+ - ret = stress_sigaltstack(NULL, SIGSTKSZ);
|
| |
+ + ret = stress_sigaltstack(NULL, STRESS_SIGSTKSZ);
|
| |
+ if (ret == 0)
|
| |
+ stress_bad_altstack_force_fault(stack);
|
| |
+ if (!keep_stressing(args))
|
| |
+ @@ -247,7 +246,7 @@ static int stress_bad_altstack(const stress_args_t *args)
|
| |
+ CASE_FALLTHROUGH;
|
| |
+ case 5:
|
| |
+ /* Illegal text segment stack */
|
| |
+ - ret = stress_sigaltstack(stress_segv_handler, SIGSTKSZ);
|
| |
+ + ret = stress_sigaltstack(stress_segv_handler, STRESS_SIGSTKSZ);
|
| |
+ if (ret == 0)
|
| |
+ stress_bad_altstack_force_fault(stack);
|
| |
+ if (!keep_stressing(args))
|
| |
+ @@ -260,7 +259,7 @@ static int stress_bad_altstack(const stress_args_t *args)
|
| |
+ case 7:
|
| |
+ #if defined(HAVE_VDSO_VIA_GETAUXVAL)
|
| |
+ /* Illegal stack on VDSO, otherwises NULL stack */
|
| |
+ - ret = stress_sigaltstack(vdso, SIGSTKSZ);
|
| |
+ + ret = stress_sigaltstack(vdso, STRESS_SIGSTKSZ);
|
| |
+ if (ret == 0)
|
| |
+ stress_bad_altstack_force_fault(stack);
|
| |
+ if (!keep_stressing(args))
|
| |
+ @@ -270,7 +269,7 @@ static int stress_bad_altstack(const stress_args_t *args)
|
| |
+ case 8:
|
| |
+ /* Illegal /dev/zero mapped stack */
|
| |
+ if (zero_stack != MAP_FAILED) {
|
| |
+ - ret = stress_sigaltstack(zero_stack, stack_sz);
|
| |
+ + ret = stress_sigaltstack(zero_stack, STRESS_MINSIGSTKSZ);
|
| |
+ if (ret == 0)
|
| |
+ stress_bad_altstack_force_fault(zero_stack);
|
| |
+ if (!keep_stressing(args))
|
| |
+ @@ -280,7 +279,7 @@ static int stress_bad_altstack(const stress_args_t *args)
|
| |
+ default:
|
| |
+ case 0:
|
| |
+ /* Illegal unmapped stack */
|
| |
+ - (void)munmap(stack, stack_sz);
|
| |
+ + (void)munmap(stack, STRESS_MINSIGSTKSZ);
|
| |
+ stress_bad_altstack_force_fault(NULL);
|
| |
+ break;
|
| |
+ }
|
| |
+ @@ -293,9 +292,9 @@ static int stress_bad_altstack(const stress_args_t *args)
|
| |
+ stress_set_proc_state(args->name, STRESS_STATE_DEINIT);
|
| |
+
|
| |
+ if (zero_stack != MAP_FAILED)
|
| |
+ - (void)munmap(zero_stack, stack_sz);
|
| |
+ + (void)munmap(zero_stack, STRESS_MINSIGSTKSZ);
|
| |
+ if (stack != MAP_FAILED)
|
| |
+ - (void)munmap(stack, stack_sz);
|
| |
+ + (void)munmap(stack, STRESS_MINSIGSTKSZ);
|
| |
+
|
| |
+ return EXIT_SUCCESS;
|
| |
+ }
|
| |
+ diff --git a/stress-context.c b/stress-context.c
|
| |
+ index fda48ba1..db4f69f3 100644
|
| |
+ --- a/stress-context.c
|
| |
+ +++ b/stress-context.c
|
| |
+ @@ -33,7 +33,7 @@ static stress_help_t help[] = {
|
| |
+ #if defined(HAVE_SWAPCONTEXT) && \
|
| |
+ defined(HAVE_UCONTEXT_H)
|
| |
+
|
| |
+ -#define STACK_SIZE (16384)
|
| |
+ +#define CONTEXT_STACK_SIZE (16384)
|
| |
+
|
| |
+ typedef struct {
|
| |
+ uint32_t check0; /* memory clobbering check canary */
|
| |
+ @@ -48,7 +48,7 @@ typedef struct {
|
| |
+
|
| |
+ typedef struct {
|
| |
+ chk_ucontext_t cu; /* check ucontext */
|
| |
+ - uint8_t stack[SIGSTKSZ + STACK_ALIGNMENT]; /* stack */
|
| |
+ + uint8_t stack[CONTEXT_STACK_SIZE + STACK_ALIGNMENT]; /* stack */
|
| |
+ chk_canary_t canary; /* copy of canary */
|
| |
+ } context_info_t;
|
| |
+
|
| |
+ @@ -103,7 +103,7 @@ static int stress_context_init(
|
| |
+ context_info->cu.check1 = context_info->canary.check1;
|
| |
+ context_info->cu.uctx.uc_stack.ss_sp =
|
| |
+ (void *)stress_align_address(context_info->stack, STACK_ALIGNMENT);
|
| |
+ - context_info->cu.uctx.uc_stack.ss_size = STACK_SIZE;
|
| |
+ + context_info->cu.uctx.uc_stack.ss_size = CONTEXT_STACK_SIZE;
|
| |
+ context_info->cu.uctx.uc_link = uctx_link;
|
| |
+ makecontext(&context_info->cu.uctx, func, 0);
|
| |
+
|
| |
+ @@ -116,10 +116,18 @@ static int stress_context_init(
|
| |
+ */
|
| |
+ static int stress_context(const stress_args_t *args)
|
| |
+ {
|
| |
+ - static uint8_t stack_sig[SIGSTKSZ + STACK_ALIGNMENT];
|
| |
+ + uint8_t *stack_sig;
|
| |
+ size_t i;
|
| |
+
|
| |
+ - if (stress_sigaltstack(stack_sig, SIGSTKSZ) < 0)
|
| |
+ + stack_sig = mmap(NULL, STRESS_SIGSTKSZ, PROT_READ | PROT_WRITE,
|
| |
+ + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
| |
+ + if (stack_sig == MAP_FAILED) {
|
| |
+ + pr_inf("%s: cannot allocate signal stack, errno=%d (%s)\n",
|
| |
+ + args->name, errno, strerror(errno));
|
| |
+ + return EXIT_NO_RESOURCE;
|
| |
+ + }
|
| |
+ +
|
| |
+ + if (stress_sigaltstack(stack_sig, STRESS_SIGSTKSZ) < 0)
|
| |
+ return EXIT_FAILURE;
|
| |
+
|
| |
+ __counter = 0;
|
| |
+ @@ -155,6 +163,7 @@ static int stress_context(const stress_args_t *args)
|
| |
+ }
|
| |
+ }
|
| |
+ stress_set_proc_state(args->name, STRESS_STATE_DEINIT);
|
| |
+ + (void)munmap((void *)stack_sig, STRESS_SIGSTKSZ);
|
| |
+
|
| |
+ return EXIT_SUCCESS;
|
| |
+ }
|
| |
+ diff --git a/stress-ng.c b/stress-ng.c
|
| |
+ index 08d9bcc1..820de3c6 100644
|
| |
+ --- a/stress-ng.c
|
| |
+ +++ b/stress-ng.c
|
| |
+ @@ -3108,11 +3108,8 @@ static inline void stress_mlock_executable(void)
|
| |
+ #if defined(MLOCKED_SECTION)
|
| |
+ extern void *__start_mlocked_text;
|
| |
+ extern void *__stop_mlocked_text;
|
| |
+ - extern void *__start_mlocked_data;
|
| |
+ - extern void *__stop_mlocked_data;
|
| |
+
|
| |
+ stress_mlock_region(&__start_mlocked_text, &__stop_mlocked_text);
|
| |
+ - stress_mlock_region(&__start_mlocked_data, &__stop_mlocked_data);
|
| |
+ #endif
|
| |
+ }
|
| |
+
|
| |
+ diff --git a/stress-ng.h b/stress-ng.h
|
| |
+ index 1128750f..48f39b79 100644
|
| |
+ --- a/stress-ng.h
|
| |
+ +++ b/stress-ng.h
|
| |
+ @@ -1250,11 +1250,11 @@ typedef struct { /* vmstat column */
|
| |
+ NEED_GNUC(4,6,0) && \
|
| |
+ !defined(__sun__) && \
|
| |
+ !defined(BUILD_STATIC)
|
| |
+ -#define MLOCKED_DATA __attribute__((__section__("mlocked_data")))
|
| |
+ +//#define MLOCKED_DATA __attribute__((__section__("mlocked_data")))
|
| |
+ #define MLOCKED_TEXT __attribute__((__section__("mlocked_text")))
|
| |
+ #define MLOCKED_SECTION 1
|
| |
+ #else
|
| |
+ -#define MLOCKED_DATA
|
| |
+ +//#define MLOCKED_DATA
|
| |
+ #define MLOCKED_TEXT
|
| |
+ #endif
|
| |
+
|
| |
+ @@ -3927,6 +3927,12 @@ extern WARN_UNUSED int32_t stress_get_opt_sched(const char *const str);
|
| |
+ extern WARN_UNUSED int32_t stress_get_opt_ionice_class(const char *const str);
|
| |
+
|
| |
+ /* Misc helper funcs */
|
| |
+ +extern WARN_UNUSED size_t stress_sig_stack_size(void);
|
| |
+ +extern WARN_UNUSED size_t stress_min_sig_stack_size(void);
|
| |
+ +
|
| |
+ +#define STRESS_SIGSTKSZ (stress_sig_stack_size())
|
| |
+ +#define STRESS_MINSIGSTKSZ (stress_min_sig_stack_size())
|
| |
+ +
|
| |
+ extern void stress_unmap_shared(void);
|
| |
+ extern void stress_log_system_mem_info(void);
|
| |
+ extern WARN_UNUSED char *stress_munge_underscore(const char *str);
|
| |
+ diff --git a/stress-rlimit.c b/stress-rlimit.c
|
| |
+ index 4fb4d09a..c6c674a8 100644
|
| |
+ --- a/stress-rlimit.c
|
| |
+ +++ b/stress-rlimit.c
|
| |
+ @@ -147,10 +147,20 @@ static void MLOCKED_TEXT stress_rlimit_handler(int signum)
|
| |
+ static int stress_rlimit_child(const stress_args_t *args, void *ctxt)
|
| |
+ {
|
| |
+ stress_rlimit_context_t *context = (stress_rlimit_context_t *)ctxt;
|
| |
+ - static unsigned char stack[MINSIGSTKSZ];
|
| |
+ + uint8_t *stack;
|
| |
+
|
| |
+ - if (stress_sigaltstack(stack, MINSIGSTKSZ) < 0)
|
| |
+ + stack = mmap(NULL, STRESS_MINSIGSTKSZ, PROT_READ | PROT_WRITE,
|
| |
+ + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
| |
+ + if (stack == MAP_FAILED) {
|
| |
+ + pr_inf("%s: cannot allocate signal stack: %d (%s)\n",
|
| |
+ + args->name, errno, strerror(errno));
|
| |
+ return EXIT_NO_RESOURCE;
|
| |
+ + }
|
| |
+ +
|
| |
+ + if (stress_sigaltstack(stack, STRESS_MINSIGSTKSZ) < 0) {
|
| |
+ + (void)munmap((void *)stack, STRESS_MINSIGSTKSZ);
|
| |
+ + return EXIT_NO_RESOURCE;
|
| |
+ + }
|
| |
+
|
| |
+ stress_set_proc_state(args->name, STRESS_STATE_RUN);
|
| |
+
|
| |
+ @@ -261,6 +271,7 @@ static int stress_rlimit_child(const stress_args_t *args, void *ctxt)
|
| |
+ stress_set_proc_state(args->name, STRESS_STATE_DEINIT);
|
| |
+
|
| |
+ (void)close(context->fd);
|
| |
+ + (void)munmap((void *)stack, STRESS_MINSIGSTKSZ);
|
| |
+
|
| |
+ return EXIT_SUCCESS;
|
| |
+ }
|
| |
+ diff --git a/stress-stack.c b/stress-stack.c
|
| |
+ index 644af726..06d12670 100644
|
| |
+ --- a/stress-stack.c
|
| |
+ +++ b/stress-stack.c
|
| |
+ @@ -132,9 +132,6 @@ static int stress_stack_child(const stress_args_t *args, void *context)
|
| |
+ {
|
| |
+ char *start_ptr = shim_sbrk(0);
|
| |
+ void *altstack;
|
| |
+ - ssize_t altstack_size = (SIGSTKSZ +
|
| |
+ - STACK_ALIGNMENT +
|
| |
+ - args->page_size) & ~(args->page_size -1);
|
| |
+ bool stack_fill = false;
|
| |
+ bool stack_mlock = false;
|
| |
+
|
| |
+ @@ -149,11 +146,14 @@ static int stress_stack_child(const stress_args_t *args, void *context)
|
| |
+ * if there is no memory to back it later. Stack
|
| |
+ * must be privately mapped.
|
| |
+ */
|
| |
+ - altstack = mmap(NULL, altstack_size, PROT_READ | PROT_WRITE,
|
| |
+ + altstack = mmap(NULL, STRESS_SIGSTKSZ, PROT_READ | PROT_WRITE,
|
| |
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
| |
+ - if (altstack == MAP_FAILED)
|
| |
+ + if (altstack == MAP_FAILED) {
|
| |
+ + pr_inf("%s: cannot allocate signal stack: errno = %d (%s)\n",
|
| |
+ + args->name, errno, strerror(errno));
|
| |
+ return EXIT_NO_RESOURCE;
|
| |
+ - (void)stress_mincore_touch_pages(altstack, altstack_size);
|
| |
+ + }
|
| |
+ + (void)stress_mincore_touch_pages(altstack, STRESS_SIGSTKSZ);
|
| |
+
|
| |
+ /*
|
| |
+ * We need to create an alternative signal
|
| |
+ @@ -162,8 +162,8 @@ static int stress_stack_child(const stress_args_t *args, void *context)
|
| |
+ * than try to push onto an already overflowed
|
| |
+ * stack
|
| |
+ */
|
| |
+ - if (stress_sigaltstack(altstack, SIGSTKSZ) < 0) {
|
| |
+ - (void)munmap(altstack, altstack_size);
|
| |
+ + if (stress_sigaltstack(altstack, STRESS_SIGSTKSZ) < 0) {
|
| |
+ + (void)munmap(altstack, STRESS_SIGSTKSZ);
|
| |
+ return EXIT_NO_RESOURCE;
|
| |
+ }
|
| |
+
|
| |
+ @@ -221,7 +221,7 @@ static int stress_stack_child(const stress_args_t *args, void *context)
|
| |
+ }
|
| |
+ stress_set_proc_state(args->name, STRESS_STATE_DEINIT);
|
| |
+
|
| |
+ - (void)munmap(altstack, altstack_size);
|
| |
+ + (void)munmap((void *)altstack, STRESS_SIGSTKSZ);
|
| |
+
|
| |
+ return EXIT_SUCCESS;
|
| |
+ }
|
| |
+ diff --git a/stress-stackmmap.c b/stress-stackmmap.c
|
| |
+ index 2f90aaae..0cdc2019 100644
|
| |
+ --- a/stress-stackmmap.c
|
| |
+ +++ b/stress-stackmmap.c
|
| |
+ @@ -86,32 +86,6 @@ static void stress_stackmmap_push_msync(void)
|
| |
+ */
|
| |
+ static void stress_stackmmap_push_start(void)
|
| |
+ {
|
| |
+ - /* stack for SEGV handler must not be on the stack */
|
| |
+ - static uint8_t stack_sig[SIGSTKSZ + STACK_ALIGNMENT];
|
| |
+ - struct sigaction new_action;
|
| |
+ -
|
| |
+ - /*
|
| |
+ - * We need to handle SEGV signals when we
|
| |
+ - * hit the end of the mmap'd stack; however
|
| |
+ - * an alternative signal handling stack
|
| |
+ - * is required because we ran out of stack
|
| |
+ - */
|
| |
+ - (void)memset(&new_action, 0, sizeof new_action);
|
| |
+ - new_action.sa_handler = stress_segvhandler;
|
| |
+ - (void)sigemptyset(&new_action.sa_mask);
|
| |
+ - new_action.sa_flags = SA_ONSTACK;
|
| |
+ - if (sigaction(SIGSEGV, &new_action, NULL) < 0)
|
| |
+ - return;
|
| |
+ -
|
| |
+ - /*
|
| |
+ - * We need an alternative signal stack
|
| |
+ - * to handle segfaults on an overrun
|
| |
+ - * mmap'd stack
|
| |
+ - */
|
| |
+ - (void)memset(stack_sig, 0, sizeof(stack_sig));
|
| |
+ - if (stress_sigaltstack(stack_sig, SIGSTKSZ) < 0)
|
| |
+ - return;
|
| |
+ -
|
| |
+ stress_stackmmap_push_msync();
|
| |
+ }
|
| |
+
|
| |
+ @@ -124,6 +98,8 @@ static int stress_stackmmap(const stress_args_t *args)
|
| |
+ int fd, ret;
|
| |
+ volatile int rc = EXIT_FAILURE; /* could be clobbered */
|
| |
+ char filename[PATH_MAX];
|
| |
+ + uint8_t *stack_sig;
|
| |
+ + struct sigaction new_action;
|
| |
+
|
| |
+ page_size = args->page_size;
|
| |
+ page_mask = ~(page_size - 1);
|
| |
+ @@ -148,20 +124,31 @@ static int stress_stackmmap(const stress_args_t *args)
|
| |
+ (void)close(fd);
|
| |
+ goto tidy_dir;
|
| |
+ }
|
| |
+ - stack_mmap = (uint8_t *)mmap(NULL, MMAPSTACK_SIZE, PROT_READ | PROT_WRITE,
|
| |
+ - MAP_SHARED, fd, 0);
|
| |
+ + stack_sig = (uint8_t *)mmap(NULL, STRESS_SIGSTKSZ,
|
| |
+ + PROT_READ | PROT_WRITE, MAP_SHARED, -1, 0);
|
| |
+ + if (stack_sig == MAP_FAILED) {
|
| |
+ + pr_inf("%s: skipping stressor, cannot mmap signal stack, "
|
| |
+ + "errno=%d (%s)\n",
|
| |
+ + args->name, errno, strerror(errno));
|
| |
+ + rc = EXIT_NO_RESOURCE;
|
| |
+ + (void)close(fd);
|
| |
+ + goto tidy_dir;
|
| |
+ + }
|
| |
+ +
|
| |
+ + stack_mmap = (uint8_t *)mmap(NULL, MMAPSTACK_SIZE,
|
| |
+ + PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
| |
+ if (stack_mmap == MAP_FAILED) {
|
| |
+ if (errno == ENXIO) {
|
| |
+ pr_inf("%s: skipping stressor, mmap not possible on file %s\n",
|
| |
+ args->name, filename);
|
| |
+ rc = EXIT_NO_RESOURCE;
|
| |
+ (void)close(fd);
|
| |
+ - goto tidy_dir;
|
| |
+ + goto tidy_stack_sig;
|
| |
+ }
|
| |
+ pr_fail("%s: mmap failed, errno=%d (%s)\n",
|
| |
+ args->name, errno, strerror(errno));
|
| |
+ (void)close(fd);
|
| |
+ - goto tidy_dir;
|
| |
+ + goto tidy_stack_sig;
|
| |
+ }
|
| |
+ (void)close(fd);
|
| |
+
|
| |
+ @@ -231,6 +218,27 @@ static int stress_stackmmap(const stress_args_t *args)
|
| |
+ /* Make sure this is killable by OOM killer */
|
| |
+ stress_set_oom_adjustment(args->name, true);
|
| |
+
|
| |
+ + /*
|
| |
+ + * We need to handle SEGV signals when we
|
| |
+ + * hit the end of the mmap'd stack; however
|
| |
+ + * an alternative signal handling stack
|
| |
+ + * is required because we ran out of stack
|
| |
+ + */
|
| |
+ + (void)memset(&new_action, 0, sizeof new_action);
|
| |
+ + new_action.sa_handler = stress_segvhandler;
|
| |
+ + (void)sigemptyset(&new_action.sa_mask);
|
| |
+ + new_action.sa_flags = SA_ONSTACK;
|
| |
+ + if (sigaction(SIGSEGV, &new_action, NULL) < 0)
|
| |
+ + _exit(EXIT_FAILURE);
|
| |
+ +
|
| |
+ + /*
|
| |
+ + * We need an alternative signal stack
|
| |
+ + * to handle segfaults on an overrun
|
| |
+ + * mmap'd stack
|
| |
+ + */
|
| |
+ + if (stress_sigaltstack(stack_sig, STRESS_SIGSTKSZ) < 0)
|
| |
+ + _exit(EXIT_FAILURE);
|
| |
+ +
|
| |
+ (void)makecontext(&c_test, stress_stackmmap_push_start, 0);
|
| |
+ (void)swapcontext(&c_main, &c_test);
|
| |
+
|
| |
+ @@ -244,6 +252,8 @@ static int stress_stackmmap(const stress_args_t *args)
|
| |
+ tidy_mmap:
|
| |
+ stress_set_proc_state(args->name, STRESS_STATE_DEINIT);
|
| |
+ (void)munmap((void *)stack_mmap, MMAPSTACK_SIZE);
|
| |
+ +tidy_stack_sig:
|
| |
+ + (void)munmap((void *)stack_sig, STRESS_SIGSTKSZ);
|
| |
+ tidy_dir:
|
| |
+ stress_set_proc_state(args->name, STRESS_STATE_DEINIT);
|
| |
+ (void)stress_temp_dir_rm_args(args);
|
| |
+ diff --git a/stress-vforkmany.c b/stress-vforkmany.c
|
| |
+ index 852bde2e..6d7f7807 100644
|
| |
+ --- a/stress-vforkmany.c
|
| |
+ +++ b/stress-vforkmany.c
|
| |
+ @@ -79,13 +79,20 @@ static int stress_vforkmany(const stress_args_t *args)
|
| |
+ {
|
| |
+ static pid_t chpid;
|
| |
+ static volatile int instance = 0;
|
| |
+ - static uint8_t stack_sig[SIGSTKSZ + SIGSTKSZ];
|
| |
+ + static uint8_t *stack_sig;
|
| |
+ static volatile bool *terminate;
|
| |
+ static bool *terminate_mmap;
|
| |
+
|
| |
+ /* We should use an alternative signal stack */
|
| |
+ - (void)memset(stack_sig, 0, sizeof(stack_sig));
|
| |
+ - if (stress_sigaltstack(stack_sig, SIGSTKSZ) < 0)
|
| |
+ + stack_sig = mmap(NULL, STRESS_SIGSTKSZ, PROT_READ | PROT_WRITE,
|
| |
+ + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
| |
+ + if (stack_sig == MAP_FAILED) {
|
| |
+ + pr_inf("%s: skipping stressor, cannot allocate signal stack,"
|
| |
+ + " errno=%d (%s)\n",
|
| |
+ + args->name, errno, strerror(errno));
|
| |
+ + return EXIT_NO_RESOURCE;
|
| |
+ + }
|
| |
+ + if (stress_sigaltstack(stack_sig, STRESS_SIGSTKSZ) < 0)
|
| |
+ return EXIT_FAILURE;
|
| |
+
|
| |
+ terminate = terminate_mmap =
|
| |
+ @@ -219,6 +226,7 @@ static int stress_vforkmany(const stress_args_t *args)
|
| |
+ stress_set_proc_state(args->name, STRESS_STATE_DEINIT);
|
| |
+
|
| |
+ (void)munmap((void *)terminate_mmap, args->page_size);
|
| |
+ + (void)munmap((void *)stack_sig, STRESS_SIGSTKSZ);
|
| |
+ return EXIT_SUCCESS;
|
| |
+ }
|
| |
+
|
| |
This is upstream's response to the compile issue in rawhide:
https://github.com/ColinIanKing/stress-ng/issues/107
This does NOT need to be merged into any stable branches.