mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Alexander Moch <mail@alexmoch.com>
To: Josh Poimboeuf <jpoimboe@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@kernel.org>,
	linux-kernel@vger.kernel.org, Alexander Moch <mail@alexmoch.com>
Subject: [PATCH] objtool: Use AT_MINSIGSTKSZ to size the sigaltstack
Date: Sun, 20 Sep 2026 16:38:15 +0200	[thread overview]
Message-ID: <20260920143815.32426-1-mail@alexmoch.com> (raw)

init_signal_handler() allocates its alternate signal stack with SIGSTKSZ.
Built against musl on x86-64 that is a compile-time 8192, whatever the CPU
it ends up running on turns out to need.

The C library refuses a stack below its own minimum, and that minimum
follows the kernel: musl's sigaltstack() rejects anything smaller than
sysconf(_SC_MINSIGSTKSZ), which it derives from AT_MINSIGSTKSZ, and the
kernel grows that figure with the xsave area.  On a machine with AMX it is
11952, so the 8192 objtool asks for is refused and objtool exits before
doing any work:

  error: objtool [signal.c:118]: init_signal_handler: sigaltstack failed: Out of memory

Ask the kernel instead of assuming.  It publishes the size a signal frame
needs as AT_MINSIGSTKSZ, and the handler still has to run in what is left
above that, so add SIGSTKSZ on top, which is what
tools/testing/selftests/x86/sigaltstack.c already does.  Where the auxv
entry is absent, before v5.14, getauxval() returns 0 and the result is
SIGSTKSZ, as today.

Fixes: 799647ddb4c0 ("objtool: Add more robust signal error handling, detect and warn about stack overflows")
Signed-off-by: Alexander Moch <mail@alexmoch.com>
---
Found on an Alpine Linux (musl) runner in the OpenZFS CI on GitHub Actions,
where configure reported CONFIG_MODULES as unset on a kernel that has it
set to y.

I have no AMX hardware, so to confirm the fix I ran a separate experiment
on GitHub Actions, one that builds no OpenZFS at all: forty runners each
fetched this tree, built objtool twice -- once unmodified, once with this
patch -- and ran both.  Four of them reported an AT_MINSIGSTKSZ of 11952,
on three Intel Xeon 6973P-C and one Platinum 8573C under Linux 6.18.35.  On
every one of those four the unmodified binary failed where the patched one
started:

Unpatched:
  error: objtool [signal.c:118]: init_signal_handler: sigaltstack failed: Out of memory

Patched:
   Usage: objtool <actions> [<options>] file.o

There the patch asks for 11952 + 8192 = 20144 bytes, and that is accepted.
The other thirty-six runners reported an AT_MINSIGSTKSZ of 1776, 3376 or
3632, each below the 8192 objtool asks for unpatched, so both binaries ran
on those.  The model name does not decide which you get: three further
Platinum 8573C runners in the same batch reported 3632, so an affected
fleet can fail a build and pass the retry.  Built with objtool's own
-Werror -Wall -Wextra.

 tools/objtool/signal.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/tools/objtool/signal.c b/tools/objtool/signal.c
index af5c65c0fb2d..8f86c79adbfb 100644
--- a/tools/objtool/signal.c
+++ b/tools/objtool/signal.c
@@ -9,11 +9,16 @@
 #include <signal.h>
 #include <unistd.h>
 #include <sys/resource.h>
+#include <sys/auxv.h>
 #include <string.h>
 
 #include <objtool/objtool.h>
 #include <objtool/warn.h>
 
+#ifndef AT_MINSIGSTKSZ
+#define AT_MINSIGSTKSZ	51
+#endif
+
 static unsigned long stack_limit;
 
 static bool is_stack_overflow(void *fault_addr)
@@ -101,17 +106,26 @@ int init_signal_handler(void)
 {
 	int signals[] = {SIGSEGV, SIGBUS, SIGILL, SIGABRT};
 	struct sigaction sa;
+	long stack_size;
 	stack_t ss;
 
 	if (read_stack_limit())
 		return -1;
 
-	ss.ss_sp = malloc(SIGSTKSZ);
+	/*
+	 * SIGSTKSZ is a compile-time constant here and can be smaller
+	 * than the signal frame on the running CPU.  Ask the kernel how
+	 * big that frame is, and leave SIGSTKSZ on top of it for the
+	 * handler.  Before v5.14 getauxval() returns 0, leaving SIGSTKSZ.
+	 */
+	stack_size = getauxval(AT_MINSIGSTKSZ) + SIGSTKSZ;
+
+	ss.ss_sp = malloc(stack_size);
 	if (!ss.ss_sp) {
 		ERROR_GLIBC("malloc");
 		return -1;
 	}
-	ss.ss_size = SIGSTKSZ;
+	ss.ss_size = stack_size;
 	ss.ss_flags = 0;
 
 	if (sigaltstack(&ss, NULL) == -1) {

base-commit: 73ae59e975966d24e32926247ddb45a537ebe184
-- 
2.55.0


                 reply	other threads:[~2026-09-20 14:38 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260920143815.32426-1-mail@alexmoch.com \
    --to=mail@alexmoch.com \
    --cc=jpoimboe@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®