public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: "Markus F.X.J. Oberhumer" <markus@oberhumer.com>
To: linux-kernel@vger.kernel.org
Cc: Linus Torvalds <torvalds@osdl.org>, Andi Kleen <ak@suse.de>
Subject: [PATCH] i386: fix stack alignment for signal handlers
Date: Tue, 13 Sep 2005 22:55:15 +0200	[thread overview]
Message-ID: <43273CB3.7090200@oberhumer.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 772 bytes --]

[PATCH] i386: fix stack alignment for signal handlers

It seems that the current signal code always sets up a stack frame so that
signal handlers are run with a somewhat mis-aligned stack, i.e. (esp % 8 == 4).

While this is not an i386 ABI requirement we really would like to have at
least a 8-byte alignment (e.g. when using doubles or other floating point
stuff). Furthermore, as recent gcc versions default to
-mpreferred-stack-boundary=4, this patch assures a 16-byte alignment.

Signed-off-by: Markus F.X.J. Oberhumer <markus@oberhumer.com>


Please try the small attached user-space test program and please also
carefully review the patch below - I don't do much kernel hacking...

~Markus

-- 
Markus Oberhumer, <markus@oberhumer.com>, http://www.oberhumer.com/



[-- Attachment #2: test_sigframe_alignment.c --]
[-- Type: text/plain, Size: 1220 bytes --]

/* test signal stack alignment (sigframe) */
/* Markus F.X.J. Oberhumer <markus@oberhumer.com> */

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

volatile unsigned long signal_sp = 0;

#if defined(__x86_64__)
/* amd64: signal stack is properly aligned */
asm(
    ".text\n .align 16\n"
"my_sighandler:\n"
    "lea 8(%rsp),%rax\n"
    "movq %rax,(signal_sp)\n"
    "retq\n"
);
#elif defined(__i386__)
/* i386: signal stack is always mis-aligned to 4-bytes */
asm(
    ".text\n .align 16\n"
"my_sighandler:\n"
    "lea 4(%esp),%eax\n"
    "movl %eax,(signal_sp)\n"
    "ret\n"
);
#else
#error "arch not supported - please insert your code here"
#endif


#if defined(__cplusplus)
extern "C"
#endif
void my_sighandler(int);


int main()
{
    int signo = SIGUSR1;

#if 1
    /* randomize stack */
    void * volatile dummy = NULL;
    srand((unsigned)clock() % RAND_MAX);
    dummy = __builtin_alloca(rand() % 2048ul);
#endif

    signal_sp = 0;
    signal(signo, my_sighandler);
    raise(signo);
    printf("sp = 0x%lx  alignment = %lu\n", signal_sp, signal_sp & 15);
    if (signal_sp & 15)
        printf("  error: signal stack not aligned\n");

    return 0;
}


/* vim:set ts=4 et: */



[-- Attachment #3: i386-align_sigframe.patch --]
[-- Type: text/x-patch, Size: 2447 bytes --]

[PATCH] i386: fix stack alignment for signal handlers

It seems that the current signal code always sets up a stack frame
so that signal handlers are run with a somewhat mis-aligned stack,
i.e. (esp % 8 == 4).

While this is not an i386 ABI requirement we really would like to have
at least a 8-byte alignment (e.g. when using doubles or other floating
point stuff). Furthermore, as recent gcc versions default to
-mpreferred-stack-boundary=4, this patch assures a 16-byte alignment.

Signed-off-by: Markus F.X.J. Oberhumer <markus@oberhumer.com>


Index: linux-2.6.git/arch/i386/kernel/signal.c
===================================================================
--- linux-2.6.git.orig/arch/i386/kernel/signal.c
+++ linux-2.6.git/arch/i386/kernel/signal.c
@@ -338,7 +338,7 @@
 		esp = (unsigned long) ka->sa.sa_restorer;
 	}
 
-	return (void __user *)((esp - frame_size) & -8ul);
+	return (void __user *)((esp - frame_size) & -16ul);
 }
 
 /* These symbols are defined with the addresses in the vsyscall page.
@@ -354,7 +354,7 @@
 	int err = 0;
 	int usig;
 
-	frame = get_sigframe(ka, regs, sizeof(*frame));
+	frame = get_sigframe(ka, regs, sizeof(*frame)) - 4;
 
 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 		goto give_sigsegv;
@@ -444,7 +444,7 @@
 	int err = 0;
 	int usig;
 
-	frame = get_sigframe(ka, regs, sizeof(*frame));
+	frame = get_sigframe(ka, regs, sizeof(*frame)) - 4;
 
 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 		goto give_sigsegv;
Index: linux-2.6.git/arch/x86_64/ia32/ia32_signal.c
===================================================================
--- linux-2.6.git.orig/arch/x86_64/ia32/ia32_signal.c
+++ linux-2.6.git/arch/x86_64/ia32/ia32_signal.c
@@ -425,7 +425,7 @@
 		rsp = (unsigned long) ka->sa.sa_restorer;
 	}
 
-	return (void __user *)((rsp - frame_size) & -8UL);
+	return (void __user *)((rsp - frame_size) & -16UL);
 }
 
 int ia32_setup_frame(int sig, struct k_sigaction *ka,
@@ -434,7 +434,7 @@
 	struct sigframe __user *frame;
 	int err = 0;
 
-	frame = get_sigframe(ka, regs, sizeof(*frame));
+	frame = get_sigframe(ka, regs, sizeof(*frame)) - 4;
 
 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 		goto give_sigsegv;
@@ -527,7 +527,7 @@
 	struct rt_sigframe __user *frame;
 	int err = 0;
 
-	frame = get_sigframe(ka, regs, sizeof(*frame));
+	frame = get_sigframe(ka, regs, sizeof(*frame)) - 4;
 
 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 		goto give_sigsegv;



             reply	other threads:[~2005-09-13 20:48 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-09-13 20:55 Markus F.X.J. Oberhumer [this message]
2005-09-13 22:53 ` [PATCH] i386: fix stack alignment for signal handlers Linus Torvalds
2005-09-13 23:30   ` Markus F.X.J. Oberhumer
2005-09-13 23:52     ` Linus Torvalds
2005-09-14  1:39       ` Markus F.X.J. Oberhumer
2005-09-14  4:54       ` Andi Kleen
2005-09-14 14:22       ` Daniel Jacobowitz
2005-09-14 14:55         ` Linus Torvalds
2005-09-14 15:44           ` Andi Kleen
2005-10-09 16:54             ` Markus F.X.J. Oberhumer
2005-10-09 16:57               ` Andi Kleen
2005-10-09 17:06                 ` Markus F.X.J. Oberhumer
2005-10-11  0:23                 ` Markus F.X.J. Oberhumer
2005-09-14 20:11     ` J.A. Magallon

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=43273CB3.7090200@oberhumer.com \
    --to=markus@oberhumer.com \
    --cc=ak@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@osdl.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