* Re: [PATCH 2.6.21-rc1] x86 signal number delivery fixes
@ 2007-02-25 23:03 Mikael Pettersson
0 siblings, 0 replies; 3+ messages in thread
From: Mikael Pettersson @ 2007-02-25 23:03 UTC (permalink / raw)
To: ak; +Cc: linux-kernel, torvalds
On Sun, 25 Feb 2007 23:39:48 +0100, Andi Kleen wrote:
> On Sunday 25 February 2007 12:47, Mikael Pettersson wrote:
> > The invokation of signal handlers on x86 has several bugs
> > in its treatment of the signal number parameter:
> >
> > - the i386 kernel passes the raw not the translated signal number
> > in EAX to non-SA_SIGINFO handlers compiled with -mregparm=3;
> > the value passed on the stack is correct, and SA_SIGINFO handlers
> > are also invoked correctly
> > - the x86-64 kernel's ia32 emulation for SA_SIGINFO handlers also
> > passes the wrong (untranslated) signal number in EAX; the value
> > on the stack is correct
> > - the x86-64 kernel's ia32 emulation for non-SA_SIGINFO handlers
> > passes the wrong (untranslated) signal number both on the stack
> > and in EAX
>
>
> Nobody should be using that signal translation code anymore. Certainly
> nothing in tree. Perhaps it would be better to just rip it out.
>
> If you have a user you should submit it.
The reason I noticed these issues was that I was studying the signal
delivery code for a virtualisation project, and these discrepancies
were immediately obvious just from reading the code.
I'm definitely not using that signal number translation feature; heck
I didn't even know it existed until a few days ago.
If it's dead as you say then it really ought to be removed. It currently
seems to make a mess in every arch's signal delivery code.
/Mikael
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH 2.6.21-rc1] x86 signal number delivery fixes
2007-02-25 11:47 Mikael Pettersson
@ 2007-02-25 22:39 ` Andi Kleen
0 siblings, 0 replies; 3+ messages in thread
From: Andi Kleen @ 2007-02-25 22:39 UTC (permalink / raw)
To: Mikael Pettersson; +Cc: torvalds, linux-kernel
On Sunday 25 February 2007 12:47, Mikael Pettersson wrote:
> The invokation of signal handlers on x86 has several bugs
> in its treatment of the signal number parameter:
>
> - the i386 kernel passes the raw not the translated signal number
> in EAX to non-SA_SIGINFO handlers compiled with -mregparm=3;
> the value passed on the stack is correct, and SA_SIGINFO handlers
> are also invoked correctly
> - the x86-64 kernel's ia32 emulation for SA_SIGINFO handlers also
> passes the wrong (untranslated) signal number in EAX; the value
> on the stack is correct
> - the x86-64 kernel's ia32 emulation for non-SA_SIGINFO handlers
> passes the wrong (untranslated) signal number both on the stack
> and in EAX
Nobody should be using that signal translation code anymore. Certainly
nothing in tree. Perhaps it would be better to just rip it out.
If you have a user you should submit it.
-Andi
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 2.6.21-rc1] x86 signal number delivery fixes
@ 2007-02-25 11:47 Mikael Pettersson
2007-02-25 22:39 ` Andi Kleen
0 siblings, 1 reply; 3+ messages in thread
From: Mikael Pettersson @ 2007-02-25 11:47 UTC (permalink / raw)
To: torvalds; +Cc: ak, linux-kernel
The invokation of signal handlers on x86 has several bugs
in its treatment of the signal number parameter:
- the i386 kernel passes the raw not the translated signal number
in EAX to non-SA_SIGINFO handlers compiled with -mregparm=3;
the value passed on the stack is correct, and SA_SIGINFO handlers
are also invoked correctly
- the x86-64 kernel's ia32 emulation for SA_SIGINFO handlers also
passes the wrong (untranslated) signal number in EAX; the value
on the stack is correct
- the x86-64 kernel's ia32 emulation for non-SA_SIGINFO handlers
passes the wrong (untranslated) signal number both on the stack
and in EAX
Also, the x86-64 kernel's ia32_setup_rt_frame() has duplicated code
for setting up -mregparm=3 parameters: it looks like the same patch
hunk was merged twice at some point.
Fixed by the following patch.
Signed-off-by: Mikael Pettersson <mikpe@it.uu.se>
---
The fix in ia32_setup_frame() is ugly, but follows the coding style
of ia32_setup_rt_frame().
arch/i386/kernel/signal.c | 2 +-
arch/x86_64/ia32/ia32_signal.c | 31 +++++++++++++++++--------------
2 files changed, 18 insertions(+), 15 deletions(-)
diff -rupN linux-2.6.21-rc1/arch/i386/kernel/signal.c linux-2.6.21-rc1.x86-signals-usig-fixes/arch/i386/kernel/signal.c
--- linux-2.6.21-rc1/arch/i386/kernel/signal.c 2007-02-24 22:32:42.000000000 +0100
+++ linux-2.6.21-rc1.x86-signals-usig-fixes/arch/i386/kernel/signal.c 2007-02-25 11:09:24.000000000 +0100
@@ -377,7 +377,7 @@ static int setup_frame(int sig, struct k
/* Set up registers for signal handler */
regs->esp = (unsigned long) frame;
regs->eip = (unsigned long) ka->sa.sa_handler;
- regs->eax = (unsigned long) sig;
+ regs->eax = (unsigned long) usig;
regs->edx = (unsigned long) 0;
regs->ecx = (unsigned long) 0;
diff -rupN linux-2.6.21-rc1/arch/x86_64/ia32/ia32_signal.c linux-2.6.21-rc1.x86-signals-usig-fixes/arch/x86_64/ia32/ia32_signal.c
--- linux-2.6.21-rc1/arch/x86_64/ia32/ia32_signal.c 2007-02-24 22:32:42.000000000 +0100
+++ linux-2.6.21-rc1.x86-signals-usig-fixes/arch/x86_64/ia32/ia32_signal.c 2007-02-25 11:09:24.000000000 +0100
@@ -426,13 +426,21 @@ int ia32_setup_frame(int sig, struct k_s
{
struct sigframe __user *frame;
int err = 0;
+ int usig;
frame = get_sigframe(ka, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
- err |= __put_user(sig, &frame->sig);
+ {
+ struct exec_domain *ed = current_thread_info()->exec_domain;
+ if (ed && ed->signal_invmap && sig < 32)
+ usig = ed->signal_invmap[sig];
+ else
+ usig = sig;
+ err |= __put_user(usig, &frame->sig);
+ }
if (err)
goto give_sigsegv;
@@ -484,7 +492,7 @@ int ia32_setup_frame(int sig, struct k_s
regs->rip = (unsigned long) ka->sa.sa_handler;
/* Make -mregparm=3 work */
- regs->rax = sig;
+ regs->rax = usig;
regs->rdx = 0;
regs->rcx = 0;
@@ -516,6 +524,7 @@ int ia32_setup_rt_frame(int sig, struct
{
struct rt_sigframe __user *frame;
int err = 0;
+ int usig;
frame = get_sigframe(ka, regs, sizeof(*frame));
@@ -524,12 +533,11 @@ int ia32_setup_rt_frame(int sig, struct
{
struct exec_domain *ed = current_thread_info()->exec_domain;
- err |= __put_user((ed
- && ed->signal_invmap
- && sig < 32
- ? ed->signal_invmap[sig]
- : sig),
- &frame->sig);
+ if (ed && ed->signal_invmap && sig < 32)
+ usig = ed->signal_invmap[sig];
+ else
+ usig = sig;
+ err |= __put_user(usig, &frame->sig);
}
err |= __put_user(ptr_to_compat(&frame->info), &frame->pinfo);
err |= __put_user(ptr_to_compat(&frame->uc), &frame->puc);
@@ -585,12 +593,7 @@ int ia32_setup_rt_frame(int sig, struct
regs->rip = (unsigned long) ka->sa.sa_handler;
/* Make -mregparm=3 work */
- regs->rax = sig;
- regs->rdx = (unsigned long) &frame->info;
- regs->rcx = (unsigned long) &frame->uc;
-
- /* Make -mregparm=3 work */
- regs->rax = sig;
+ regs->rax = usig;
regs->rdx = (unsigned long) &frame->info;
regs->rcx = (unsigned long) &frame->uc;
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2007-02-25 23:04 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-02-25 23:03 [PATCH 2.6.21-rc1] x86 signal number delivery fixes Mikael Pettersson
-- strict thread matches above, loose matches on Subject: below --
2007-02-25 11:47 Mikael Pettersson
2007-02-25 22:39 ` Andi Kleen
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.