* Re: [PATCH 9/11] - UML - fix signal mask on delivery error
[not found] <200411130201.iAD210pT005889@ccure.user-mode-linux.org>
@ 2004-11-13 0:34 ` Andrew Morton
2004-11-14 22:13 ` Jeff Dike
0 siblings, 1 reply; 11+ messages in thread
From: Andrew Morton @ 2004-11-13 0:34 UTC (permalink / raw)
To: Jeff Dike; +Cc: blaisorblade_spam, bstroesser, linux-arch
(removed linux-kernel, added linux-arch)
Jeff Dike <jdike@addtoit.com> wrote:
>
> >From Bodo Stroesser - If the user stack limit is reached or the
> signal stack assigned with sigaltstack() is invalid when a user signal
> handler with SA_ONSTACK has to be started, the signal mask of the
> interrupted user program is modified. This happens because the mask,
> that should be used with the handler only, is written to
> "current->blocked" even if the handler could not be started. But
> without a handler, no rewrite of the original mask at sys_sigreturn
> will be done. A slightly different case is sys_sigsuspend(), where the
> mask is already modified when kern_do_signal() is started. "*oldset" and
> "current->blocked" are not equal here and thus current->blocked has to
> be set to *oldset, if an error occurs in handle_signal().
> For both cases I've written small tests, and with the patch the result
> is OK.
> This issue is relevant for other architectures too (e.g. i386, I've
> seen).
Could you send one of the test apps? This is something which the arch
maintainers might want to look into fixing, thanks.
> Signed-off-by: Jeff Dike <jdike@addtoit.com>
>
> Index: 2.6.9/arch/um/kernel/signal_kern.c
> ===================================================================
> --- 2.6.9.orig/arch/um/kernel/signal_kern.c 2004-11-12 16:24:18.000000000 -0500
> +++ 2.6.9/arch/um/kernel/signal_kern.c 2004-11-12 18:05:26.000000000 -0500
> @@ -79,7 +79,14 @@
> else
> err = setup_signal_stack_sc(sp, signr, ka, regs, oldset);
>
> - if (!err && !(ka->sa.sa_flags & SA_NODEFER)) {
> + if(err){
> + spin_lock_irq(¤t->sighand->siglock);
> + current->blocked = *oldset;
> + recalc_sigpending();
> + spin_unlock_irq(¤t->sighand->siglock);
> + force_sigsegv(signr, current);
> + }
> + else if(!(ka->sa.sa_flags & SA_NODEFER)){
> spin_lock_irq(¤t->sighand->siglock);
> sigorsets(¤t->blocked, ¤t->blocked,
> &ka->sa.sa_mask);
> @@ -87,9 +94,6 @@
> recalc_sigpending();
> spin_unlock_irq(¤t->sighand->siglock);
> }
> -
> - if(err)
> - force_sigsegv(signr, current);
> }
>
> static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset)
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 9/11] - UML - fix signal mask on delivery error
2004-11-13 0:34 ` [PATCH 9/11] - UML - fix signal mask on delivery error Andrew Morton
@ 2004-11-14 22:13 ` Jeff Dike
2004-11-15 8:35 ` David Woodhouse
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Jeff Dike @ 2004-11-14 22:13 UTC (permalink / raw)
To: Andrew Morton; +Cc: blaisorblade_spam, bstroesser, linux-arch, jdike
[-- Attachment #1: Type: text/plain, Size: 898 bytes --]
akpm@osdl.org said:
> Could you send one of the test apps? This is something which the arch
> maintainers might want to look into fixing, thanks.
Attached...
Included are
breakout.c - UML-specific breakouts, fixed in 2.6 and 2.4 now, but
please don't popularize these :-)
step_sighdlr.c - PTRACE_SINGLESTEPs into a signal handler, if I'm
reading the code right, fails on i386
interrupted_syscall.c - counts signals and system calls during
interrupted system calls, under ptrace and not. Fails on x86 under ptrace.
kernel_restorer.c - I can't get this to compile because it's too
intimate with the libc headers, expecting to get a k_sigaction from them.
sigmasking.c - Makes sure that when a signal is (not) delivered to
a bogus stack, that a segfault is delivered then, and not after returning
to userspace. This is the test relevant to the patch that Andrew replied
to.
Jeff
[-- Attachment #2: testtools-bodo-2004-10-29.tar --]
[-- Type: application/x-tar , Size: 40960 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 9/11] - UML - fix signal mask on delivery error
2004-11-14 22:13 ` Jeff Dike
@ 2004-11-15 8:35 ` David Woodhouse
2004-11-22 15:30 ` David Woodhouse
2004-11-15 11:40 ` Bodo Stroesser
2004-11-30 14:59 ` David Woodhouse
2 siblings, 1 reply; 11+ messages in thread
From: David Woodhouse @ 2004-11-15 8:35 UTC (permalink / raw)
To: Jeff Dike, paulus
Cc: Andrew Morton, blaisorblade_spam, bstroesser, linux-arch, jdike
On Sun, 2004-11-14 at 17:13 -0500, Jeff Dike wrote:
> step_sighdlr.c - PTRACE_SINGLESTEPs into a signal handler, if I'm
> reading the code right, fails on i386
I haven't looked at this particular test but given the description I
think it'll fail on ppc64 too. This ought to fix it for 2.6, along with
single-stepping over syscalls and single-stepping over sigreturn (which
is a special case).
The 2.4 kernel also has these problems on most arches -- the fixes for
this are around, but weren't pushed to Marcelo because they weren't
considered a really necessary fix. Was that wrong? Should I dig them out
and send them on?
--- linux-2.6.9/arch/ppc64/kernel/signal.c.sstep 2004-10-18 22:53:05.000000000 +0100
+++ linux-2.6.9/arch/ppc64/kernel/signal.c 2004-11-09 18:48:09.000000000 +0000
@@ -26,6 +26,7 @@
#include <linux/unistd.h>
#include <linux/stddef.h>
#include <linux/elf.h>
+#include <linux/ptrace.h>
#include <asm/sigcontext.h>
#include <asm/ucontext.h>
#include <asm/uaccess.h>
@@ -439,6 +440,9 @@ static void setup_rt_frame(int signr, st
if (err)
goto badframe;
+ if (test_thread_flag(TIF_SINGLESTEP))
+ ptrace_notify(SIGTRAP);
+
return;
badframe:
--- linux-2.6.9/arch/ppc64/kernel/entry.S.sstep 2004-10-18 22:53:06.000000000 +0100
+++ linux-2.6.9/arch/ppc64/kernel/entry.S 2004-11-09 18:32:30.000000000 +0000
@@ -162,7 +162,7 @@ syscall_error_cont:
/* check for syscall tracing or audit */
ld r9,TI_FLAGS(r12)
- andi. r0,r9,_TIF_SYSCALL_T_OR_A
+ andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
bne- syscall_exit_trace
syscall_exit_trace_cont:
@@ -317,7 +317,7 @@ _GLOBAL(ppc64_rt_sigreturn)
blt syscall_exit
clrrdi r4,r1,THREAD_SHIFT
ld r4,TI_FLAGS(r4)
- andi. r4,r4,_TIF_SYSCALL_T_OR_A
+ andi. r4,r4,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
beq+ 81f
bl .do_syscall_trace_leave
81: b .ret_from_except
--- linux-2.6.9/arch/ppc64/kernel/ptrace.c.sstep 2004-10-18 22:54:55.000000000 +0100
+++ linux-2.6.9/arch/ppc64/kernel/ptrace.c 2004-11-09 18:17:29.000000000 +0000
@@ -318,7 +318,8 @@ void do_syscall_trace_leave(void)
if (unlikely(current->audit_context))
audit_syscall_exit(current, 0); /* FIXME: pass pt_regs */
- if (test_thread_flag(TIF_SYSCALL_TRACE)
+ if ((test_thread_flag(TIF_SYSCALL_TRACE)
+ || test_thread_flag(TIF_SINGLESTEP))
&& (current->ptrace & PT_PTRACED))
do_syscall_trace();
}
--- linux-2.6.9/arch/ppc64/kernel/signal32.c.sstep 2004-10-18 22:55:07.000000000 +0100
+++ linux-2.6.9/arch/ppc64/kernel/signal32.c 2004-11-09 18:48:39.000000000 +0000
@@ -25,6 +25,7 @@
#include <linux/errno.h>
#include <linux/elf.h>
#include <linux/compat.h>
+#include <linux/ptrace.h>
#include <asm/ppc32.h>
#include <asm/uaccess.h>
#include <asm/ppcdebug.h>
@@ -696,6 +697,9 @@ static void handle_rt_signal32(unsigned
regs->trap = 0;
regs->result = 0;
+ if (test_thread_flag(TIF_SINGLESTEP))
+ ptrace_notify(SIGTRAP);
+
return;
badframe:
@@ -859,6 +863,9 @@ static void handle_signal32(unsigned lon
regs->trap = 0;
regs->result = 0;
+ if (test_thread_flag(TIF_SINGLESTEP))
+ ptrace_notify(SIGTRAP);
+
return;
badframe:
--- linux-2.6.9/include/asm-ppc64/ptrace-common.h.sstep 2004-10-18 22:54:37.000000000 +0100
+++ linux-2.6.9/include/asm-ppc64/ptrace-common.h 2004-11-09 18:45:29.000000000 +0000
@@ -58,6 +58,7 @@ static inline void set_single_step(struc
struct pt_regs *regs = task->thread.regs;
if (regs != NULL)
regs->msr |= MSR_SE;
+ set_ti_thread_flag(task->thread_info, TIF_SINGLESTEP);
}
static inline void clear_single_step(struct task_struct *task)
@@ -65,6 +66,7 @@ static inline void clear_single_step(str
struct pt_regs *regs = task->thread.regs;
if (regs != NULL)
regs->msr &= ~MSR_SE;
+ clear_ti_thread_flag(task->thread_info, TIF_SINGLESTEP);
}
#endif /* _PPC64_PTRACE_COMMON_H */
--- linux-2.6.9/include/asm-ppc64/thread_info.h.sstep 2004-10-18 22:53:21.000000000 +0100
+++ linux-2.6.9/include/asm-ppc64/thread_info.h 2004-11-09 18:25:59.000000000 +0000
@@ -97,6 +97,7 @@ static inline struct thread_info *curren
#define TIF_RUN_LIGHT 6 /* iSeries run light */
#define TIF_ABI_PENDING 7 /* 32/64 bit switch needed */
#define TIF_SYSCALL_AUDIT 8 /* syscall auditing active */
+#define TIF_SINGLESTEP 9 /* singlestepping active */
/* as above, but as bit values */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
@@ -108,6 +109,7 @@ static inline struct thread_info *curren
#define _TIF_RUN_LIGHT (1<<TIF_RUN_LIGHT)
#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING)
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
+#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
#define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
#define _TIF_USER_WORK_MASK (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \
--
dwmw2
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 9/11] - UML - fix signal mask on delivery error
2004-11-14 22:13 ` Jeff Dike
2004-11-15 8:35 ` David Woodhouse
@ 2004-11-15 11:40 ` Bodo Stroesser
2004-11-15 17:18 ` Jeff Dike
2004-11-30 14:59 ` David Woodhouse
2 siblings, 1 reply; 11+ messages in thread
From: Bodo Stroesser @ 2004-11-15 11:40 UTC (permalink / raw)
To: Jeff Dike; +Cc: Andrew Morton, blaisorblade_spam, linux-arch, jdike
Jeff Dike wrote:
> akpm@osdl.org said:
>
>>Could you send one of the test apps? This is something which the arch
>>maintainers might want to look into fixing, thanks.
>
>
> Attached...
>
> Included are
> breakout.c - UML-specific breakouts, fixed in 2.6 and 2.4 now, but
> please don't popularize these :-)
>
> step_sighdlr.c - PTRACE_SINGLESTEPs into a signal handler, if I'm
> reading the code right, fails on i386
I guess, you are notb using i386 2.6.9. On a 2.6.9-vanilla i386 the test
doesn't fail! In 2.6.9 some enhancement of singlestepping syscalls and
singlestepping signal handlers is included. The test checks, whether
UML 2.6.9 is compatible to 2.6.9-i386. With my patchset, it is.
>
> interrupted_syscall.c - counts signals and system calls during
> interrupted system calls, under ptrace and not. Fails on x86 under ptrace.
On my 2.6.7 and 2.6.9 kernels, the test doesn't fail. What kerenel are you
using? Could you please send me a listing of the messages from the test?
>
> kernel_restorer.c - I can't get this to compile because it's too
> intimate with the libc headers, expecting to get a k_sigaction from them.
On my SuSE 9 system, k_sigaction comes from /usr/include/asm/signal.h. This
again comes from glibc-devel-2.3.3-98.28, SuSE supplies. I had to write a
"#define __KERNEL__" into the test to have k_sigaction included. If your
system lacks a k_sigaction in the includes, please copy a definition from
the kernel sources to my test. Yes, that's dirty, but it's a test only!
k_sigaction is needed to call sys_sigaction directly, bypassing the lib.
This was the only way to test the kernels restorer-stub, since the lib
always inserted its own stub, if I used "NULL".
>
> sigmasking.c - Makes sure that when a signal is (not) delivered to
> a bogus stack, that a segfault is delivered then, and not after returning
> to userspace. This is the test relevant to the patch that Andrew replied
> to.
Yes. This should be the only test, that shows differences between i386
2.6.9-vanilla and UML 2.6.9 with my patches.
>
> Jeff
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 9/11] - UML - fix signal mask on delivery error
2004-11-15 11:40 ` Bodo Stroesser
@ 2004-11-15 17:18 ` Jeff Dike
2004-11-16 9:39 ` Bodo Stroesser
0 siblings, 1 reply; 11+ messages in thread
From: Jeff Dike @ 2004-11-15 17:18 UTC (permalink / raw)
To: Bodo Stroesser; +Cc: Andrew Morton, blaisorblade_spam, linux-arch
bstroesser@fujitsu-siemens.com said:
> I guess, you are notb using i386 2.6.9. On a 2.6.9-vanilla i386 the
> test doesn't fail!
Sorry, I should have mentioned that this host was running 2.4 (stock 2.4.26).
Jeff
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 9/11] - UML - fix signal mask on delivery error
2004-11-15 17:18 ` Jeff Dike
@ 2004-11-16 9:39 ` Bodo Stroesser
0 siblings, 0 replies; 11+ messages in thread
From: Bodo Stroesser @ 2004-11-16 9:39 UTC (permalink / raw)
To: Jeff Dike; +Cc: Andrew Morton, blaisorblade_spam, linux-arch
Jeff Dike wrote:
> bstroesser@fujitsu-siemens.com said:
>
>>I guess, you are notb using i386 2.6.9. On a 2.6.9-vanilla i386 the
>>test doesn't fail!
>
>
> Sorry, I should have mentioned that this host was running 2.4 (stock 2.4.26).
>
> Jeff
>
Yes. That makes sense. There are substantial changes in syscall restarting
between 2.4 and 2.6 (e.g ERESTART_RESTARTBLOCK added). Please run the tests on
2.6.9-i386 to get the correct result: all tests are OK, but sigmasking.
Bodo
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 9/11] - UML - fix signal mask on delivery error
2004-11-15 8:35 ` David Woodhouse
@ 2004-11-22 15:30 ` David Woodhouse
0 siblings, 0 replies; 11+ messages in thread
From: David Woodhouse @ 2004-11-22 15:30 UTC (permalink / raw)
To: Jeff Dike; +Cc: paulus, Andrew Morton, linux-arch, cagney
On Mon, 2004-11-15 at 08:35 +0000, David Woodhouse wrote:
> On Sun, 2004-11-14 at 17:13 -0500, Jeff Dike wrote:
> > step_sighdlr.c - PTRACE_SINGLESTEPs into a signal handler, if I'm
> > reading the code right, fails on i386
>
> I haven't looked at this particular test but given the description I
> think it'll fail on ppc64 too. This ought to fix it for 2.6, along with
> single-stepping over syscalls and single-stepping over sigreturn (which
> is a special case).
I fixed it too hard -- we don't need to stop _twice_ at the same
instruction on entry to a signal handler; once will suffice...
--- linux-2.6.9/arch/ppc64/kernel/entry.S.sstep 2004-10-18 22:53:06.000000000 +0100
+++ linux-2.6.9/arch/ppc64/kernel/entry.S 2004-11-09 18:32:30.000000000 +0000
@@ -162,7 +162,7 @@ syscall_error_cont:
/* check for syscall tracing or audit */
ld r9,TI_FLAGS(r12)
- andi. r0,r9,_TIF_SYSCALL_T_OR_A
+ andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
bne- syscall_exit_trace
syscall_exit_trace_cont:
@@ -317,7 +317,7 @@ _GLOBAL(ppc64_rt_sigreturn)
blt syscall_exit
clrrdi r4,r1,THREAD_SHIFT
ld r4,TI_FLAGS(r4)
- andi. r4,r4,_TIF_SYSCALL_T_OR_A
+ andi. r4,r4,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
beq+ 81f
bl .do_syscall_trace_leave
81: b .ret_from_except
--- linux-2.6.9/arch/ppc64/kernel/ptrace.c.sstep 2004-10-18 22:54:55.000000000 +0100
+++ linux-2.6.9/arch/ppc64/kernel/ptrace.c 2004-11-09 18:17:29.000000000 +0000
@@ -318,7 +318,8 @@ void do_syscall_trace_leave(void)
if (unlikely(current->audit_context))
audit_syscall_exit(current, 0); /* FIXME: pass pt_regs */
- if (test_thread_flag(TIF_SYSCALL_TRACE)
+ if ((test_thread_flag(TIF_SYSCALL_TRACE)
+ || test_thread_flag(TIF_SINGLESTEP))
&& (current->ptrace & PT_PTRACED))
do_syscall_trace();
}
--- linux-2.6.9/include/asm-ppc64/ptrace-common.h.sstep 2004-10-18 22:54:37.000000000 +0100
+++ linux-2.6.9/include/asm-ppc64/ptrace-common.h 2004-11-09 18:45:29.000000000 +0000
@@ -58,6 +58,7 @@ static inline void set_single_step(struc
struct pt_regs *regs = task->thread.regs;
if (regs != NULL)
regs->msr |= MSR_SE;
+ set_ti_thread_flag(task->thread_info, TIF_SINGLESTEP);
}
static inline void clear_single_step(struct task_struct *task)
@@ -65,6 +66,7 @@ static inline void clear_single_step(str
struct pt_regs *regs = task->thread.regs;
if (regs != NULL)
regs->msr &= ~MSR_SE;
+ clear_ti_thread_flag(task->thread_info, TIF_SINGLESTEP);
}
#endif /* _PPC64_PTRACE_COMMON_H */
--- linux-2.6.9/include/asm-ppc64/thread_info.h.sstep 2004-10-18 22:53:21.000000000 +0100
+++ linux-2.6.9/include/asm-ppc64/thread_info.h 2004-11-09 18:25:59.000000000 +0000
@@ -97,6 +97,7 @@ static inline struct thread_info *curren
#define TIF_RUN_LIGHT 6 /* iSeries run light */
#define TIF_ABI_PENDING 7 /* 32/64 bit switch needed */
#define TIF_SYSCALL_AUDIT 8 /* syscall auditing active */
+#define TIF_SINGLESTEP 9 /* singlestepping active */
/* as above, but as bit values */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
@@ -108,6 +109,7 @@ static inline struct thread_info *curren
#define _TIF_RUN_LIGHT (1<<TIF_RUN_LIGHT)
#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING)
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
+#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
#define _TIF_SYSCALL_T_OR_A (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
#define _TIF_USER_WORK_MASK (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \
--
dwmw2
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 9/11] - UML - fix signal mask on delivery error
2004-11-14 22:13 ` Jeff Dike
2004-11-15 8:35 ` David Woodhouse
2004-11-15 11:40 ` Bodo Stroesser
@ 2004-11-30 14:59 ` David Woodhouse
2004-12-02 9:55 ` Bodo Stroesser
2 siblings, 1 reply; 11+ messages in thread
From: David Woodhouse @ 2004-11-30 14:59 UTC (permalink / raw)
To: Jeff Dike; +Cc: Andrew Morton, blaisorblade_spam, bstroesser, linux-arch, jdike
[-- Attachment #1: Type: text/plain, Size: 380 bytes --]
On Sun, 2004-11-14 at 17:13 -0500, Jeff Dike wrote:
> sigmasking.c - Makes sure that when a signal is (not) delivered to
> a bogus stack, that a segfault is delivered then, and not after returning
> to userspace. This is the test relevant to the patch that Andrew replied
> to.
Corresponding patch for ppc64. Are we actually going to fix this for all
architectures?
--
dwmw2
[-- Attachment #2: linux-2.6.10-ppc64-sigmasking.patch --]
[-- Type: text/x-patch, Size: 4353 bytes --]
===== arch/ppc64/kernel/signal.c 1.44 vs edited =====
--- 1.44/arch/ppc64/kernel/signal.c 2004-10-28 08:39:49 +01:00
+++ edited/arch/ppc64/kernel/signal.c 2004-11-26 14:13:18 +00:00
@@ -387,7 +387,7 @@
return 0;
}
-static void setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
+static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
sigset_t *set, struct pt_regs *regs)
{
/* Handler is *really* a pointer to the function descriptor for
@@ -452,7 +452,7 @@
if (err)
goto badframe;
- return;
+ return 0;
badframe:
#if DEBUG_SIG
@@ -460,17 +460,19 @@
regs, frame, newsp);
#endif
force_sigsegv(signr, current);
+ return -1;
}
/*
* OK, we're invoking a handler
*/
-static void handle_signal(unsigned long sig, struct k_sigaction *ka,
- siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
+static int handle_signal(unsigned long sig, struct k_sigaction *ka,
+ siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
{
/* Set up Signal Frame */
- setup_rt_frame(sig, ka, info, oldset, regs);
+ if (setup_rt_frame(sig, ka, info, oldset, regs))
+ return 0;
if (!(ka->sa.sa_flags & SA_NODEFER)) {
spin_lock_irq(¤t->sighand->siglock);
@@ -479,6 +481,8 @@
recalc_sigpending();
spin_unlock_irq(¤t->sighand->siglock);
}
+
+ return 1;
}
static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
@@ -538,8 +542,7 @@
/* Whee! Actually deliver the signal. */
if (TRAP(regs) == 0x0C00)
syscall_restart(regs, &ka);
- handle_signal(signr, &ka, &info, oldset, regs);
- return 1;
+ return handle_signal(signr, &ka, &info, oldset, regs);
}
if (TRAP(regs) == 0x0C00) { /* System Call! */
===== arch/ppc64/kernel/signal32.c 1.61 vs edited =====
--- 1.61/arch/ppc64/kernel/signal32.c 2004-10-28 08:39:49 +01:00
+++ edited/arch/ppc64/kernel/signal32.c 2004-11-26 14:13:18 +00:00
@@ -653,9 +653,9 @@
* Set up a signal frame for a "real-time" signal handler
* (one which gets siginfo).
*/
-static void handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
- siginfo_t *info, sigset_t *oldset,
- struct pt_regs * regs, unsigned long newsp)
+static int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
+ siginfo_t *info, sigset_t *oldset,
+ struct pt_regs * regs, unsigned long newsp)
{
struct rt_sigframe32 __user *rt_sf;
struct mcontext32 __user *frame;
@@ -704,14 +704,14 @@
regs->trap = 0;
regs->result = 0;
- return;
+ return 1;
badframe:
#if DEBUG_SIG
printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n",
regs, frame, newsp);
#endif
- force_sigsegv(sig, current);
+ return 0;
}
static long do_setcontext32(struct ucontext32 __user *ucp, struct pt_regs *regs, int sig)
@@ -822,7 +822,7 @@
/*
* OK, we're invoking a handler
*/
-static void handle_signal32(unsigned long sig, struct k_sigaction *ka,
+static int handle_signal32(unsigned long sig, struct k_sigaction *ka,
siginfo_t *info, sigset_t *oldset,
struct pt_regs * regs, unsigned long newsp)
{
@@ -867,14 +867,14 @@
regs->trap = 0;
regs->result = 0;
- return;
+ return 1;
badframe:
#if DEBUG_SIG
printk("badframe in handle_signal, regs=%p frame=%x newsp=%x\n",
regs, frame, *newspp);
#endif
- force_sigsegv(sig, current);
+ return 0;
}
/*
@@ -984,11 +984,20 @@
/* Whee! Actually deliver the signal. */
if (ka.sa.sa_flags & SA_SIGINFO)
- handle_rt_signal32(signr, &ka, &info, oldset, regs, newsp);
+ ret = handle_rt_signal32(signr, &ka, &info, oldset, regs, newsp);
else
- handle_signal32(signr, &ka, &info, oldset, regs, newsp);
+ ret = handle_signal32(signr, &ka, &info, oldset, regs, newsp);
- if (!(ka.sa.sa_flags & SA_NODEFER)) {
+ if (!ret) {
+ /* Setting up the stack frame failed, but if we came here
+ from sigsuspend we may already have masked signals.
+ Put back the old sigmask before forcing SEGV. */
+ spin_lock_irq(¤t->sighand->siglock);
+ current->blocked = *oldset;
+ recalc_sigpending();
+ spin_unlock_irq(¤t->sighand->siglock);
+ force_sigsegv(signr, current);
+ } else if (!(ka.sa.sa_flags & SA_NODEFER)) {
spin_lock_irq(¤t->sighand->siglock);
sigorsets(¤t->blocked, ¤t->blocked,
&ka.sa.sa_mask);
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 9/11] - UML - fix signal mask on delivery error
2004-11-30 14:59 ` David Woodhouse
@ 2004-12-02 9:55 ` Bodo Stroesser
2004-12-02 11:25 ` Paul Mackerras
0 siblings, 1 reply; 11+ messages in thread
From: Bodo Stroesser @ 2004-12-02 9:55 UTC (permalink / raw)
To: David Woodhouse
Cc: Jeff Dike, Andrew Morton, blaisorblade_spam, linux-arch, jdike
David Woodhouse wrote:
> On Sun, 2004-11-14 at 17:13 -0500, Jeff Dike wrote:
>
>> sigmasking.c - Makes sure that when a signal is (not) delivered to
>>a bogus stack, that a segfault is delivered then, and not after returning
>>to userspace. This is the test relevant to the patch that Andrew replied
>>to.
I don't know much about ppc64 and also don't have a machine to test.
So, I'm commenting the code only. If I've missed something, sorry for that.
The changes we did in UML, fiy two major issues:
1) they correct the sigmask after a segfault that happened in signal-delivery
2) they immediately deliver that SIGSEGV, before returning to user.
AFAICS, the patch seems to cover the first, but not the second.
If a SIGSEGV is forced since the stackframe/sigcontext for a signal-handler
could not be created, this SIGSEGV is queued only. To deliver it, do_signal()
must be called again, which normally won't happen (with the exception of
sys_sigretrun/sys_rt_sigreturn). Thus, SIGSEGV stays in the queue until the
next interrupt or syscall happens. IMHO this behavior is bad.
So, in UML we changed (kern_)do_signal, to loop over get_signal_to_deliver
and handle_signal, until a signal is delivered correctly or the task exits.
Bodo
>
>
> Corresponding patch for ppc64. Are we actually going to fix this for all
> architectures?
>
>
>
> ------------------------------------------------------------------------
>
> ===== arch/ppc64/kernel/signal.c 1.44 vs edited =====
> --- 1.44/arch/ppc64/kernel/signal.c 2004-10-28 08:39:49 +01:00
> +++ edited/arch/ppc64/kernel/signal.c 2004-11-26 14:13:18 +00:00
> @@ -387,7 +387,7 @@
> return 0;
> }
>
> -static void setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
> +static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
> sigset_t *set, struct pt_regs *regs)
> {
> /* Handler is *really* a pointer to the function descriptor for
> @@ -452,7 +452,7 @@
> if (err)
> goto badframe;
>
> - return;
> + return 0;
>
> badframe:
> #if DEBUG_SIG
> @@ -460,17 +460,19 @@
> regs, frame, newsp);
> #endif
> force_sigsegv(signr, current);
> + return -1;
> }
>
>
> /*
> * OK, we're invoking a handler
> */
> -static void handle_signal(unsigned long sig, struct k_sigaction *ka,
> - siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
> +static int handle_signal(unsigned long sig, struct k_sigaction *ka,
> + siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
> {
> /* Set up Signal Frame */
> - setup_rt_frame(sig, ka, info, oldset, regs);
> + if (setup_rt_frame(sig, ka, info, oldset, regs))
> + return 0;
>
> if (!(ka->sa.sa_flags & SA_NODEFER)) {
> spin_lock_irq(¤t->sighand->siglock);
> @@ -479,6 +481,8 @@
> recalc_sigpending();
> spin_unlock_irq(¤t->sighand->siglock);
> }
> +
> + return 1;
> }
>
> static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
> @@ -538,8 +542,7 @@
> /* Whee! Actually deliver the signal. */
> if (TRAP(regs) == 0x0C00)
> syscall_restart(regs, &ka);
> - handle_signal(signr, &ka, &info, oldset, regs);
> - return 1;
> + return handle_signal(signr, &ka, &info, oldset, regs);
> }
>
> if (TRAP(regs) == 0x0C00) { /* System Call! */
> ===== arch/ppc64/kernel/signal32.c 1.61 vs edited =====
> --- 1.61/arch/ppc64/kernel/signal32.c 2004-10-28 08:39:49 +01:00
> +++ edited/arch/ppc64/kernel/signal32.c 2004-11-26 14:13:18 +00:00
> @@ -653,9 +653,9 @@
> * Set up a signal frame for a "real-time" signal handler
> * (one which gets siginfo).
> */
> -static void handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
> - siginfo_t *info, sigset_t *oldset,
> - struct pt_regs * regs, unsigned long newsp)
> +static int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
> + siginfo_t *info, sigset_t *oldset,
> + struct pt_regs * regs, unsigned long newsp)
> {
> struct rt_sigframe32 __user *rt_sf;
> struct mcontext32 __user *frame;
> @@ -704,14 +704,14 @@
> regs->trap = 0;
> regs->result = 0;
>
> - return;
> + return 1;
>
> badframe:
> #if DEBUG_SIG
> printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n",
> regs, frame, newsp);
> #endif
> - force_sigsegv(sig, current);
> + return 0;
> }
>
> static long do_setcontext32(struct ucontext32 __user *ucp, struct pt_regs *regs, int sig)
> @@ -822,7 +822,7 @@
> /*
> * OK, we're invoking a handler
> */
> -static void handle_signal32(unsigned long sig, struct k_sigaction *ka,
> +static int handle_signal32(unsigned long sig, struct k_sigaction *ka,
> siginfo_t *info, sigset_t *oldset,
> struct pt_regs * regs, unsigned long newsp)
> {
> @@ -867,14 +867,14 @@
> regs->trap = 0;
> regs->result = 0;
>
> - return;
> + return 1;
>
> badframe:
> #if DEBUG_SIG
> printk("badframe in handle_signal, regs=%p frame=%x newsp=%x\n",
> regs, frame, *newspp);
> #endif
> - force_sigsegv(sig, current);
> + return 0;
> }
>
> /*
> @@ -984,11 +984,20 @@
>
> /* Whee! Actually deliver the signal. */
> if (ka.sa.sa_flags & SA_SIGINFO)
> - handle_rt_signal32(signr, &ka, &info, oldset, regs, newsp);
> + ret = handle_rt_signal32(signr, &ka, &info, oldset, regs, newsp);
> else
> - handle_signal32(signr, &ka, &info, oldset, regs, newsp);
> + ret = handle_signal32(signr, &ka, &info, oldset, regs, newsp);
>
> - if (!(ka.sa.sa_flags & SA_NODEFER)) {
> + if (!ret) {
> + /* Setting up the stack frame failed, but if we came here
> + from sigsuspend we may already have masked signals.
> + Put back the old sigmask before forcing SEGV. */
> + spin_lock_irq(¤t->sighand->siglock);
> + current->blocked = *oldset;
> + recalc_sigpending();
> + spin_unlock_irq(¤t->sighand->siglock);
> + force_sigsegv(signr, current);
> + } else if (!(ka.sa.sa_flags & SA_NODEFER)) {
> spin_lock_irq(¤t->sighand->siglock);
> sigorsets(¤t->blocked, ¤t->blocked,
> &ka.sa.sa_mask);
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 9/11] - UML - fix signal mask on delivery error
2004-12-02 9:55 ` Bodo Stroesser
@ 2004-12-02 11:25 ` Paul Mackerras
2004-12-02 11:40 ` Bodo Stroesser
0 siblings, 1 reply; 11+ messages in thread
From: Paul Mackerras @ 2004-12-02 11:25 UTC (permalink / raw)
To: Bodo Stroesser
Cc: David Woodhouse, Jeff Dike, Andrew Morton, blaisorblade_spam,
linux-arch, jdike
Bodo Stroesser writes:
> If a SIGSEGV is forced since the stackframe/sigcontext for a signal-handler
> could not be created, this SIGSEGV is queued only. To deliver it, do_signal()
> must be called again, which normally won't happen (with the exception of
> sys_sigretrun/sys_rt_sigreturn). Thus, SIGSEGV stays in the queue until the
We got this right on ppc/ppc64, I believe. After calling do_signal,
we loop around again (in the exception exit path in entry.S) and check
the signal pending and reschedule bits again (in the thread_info
flags). We only exit to usermode when they are both zero.
Paul.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 9/11] - UML - fix signal mask on delivery error
2004-12-02 11:25 ` Paul Mackerras
@ 2004-12-02 11:40 ` Bodo Stroesser
0 siblings, 0 replies; 11+ messages in thread
From: Bodo Stroesser @ 2004-12-02 11:40 UTC (permalink / raw)
To: Paul Mackerras
Cc: David Woodhouse, Jeff Dike, Andrew Morton, blaisorblade_spam,
linux-arch, jdike
Paul Mackerras wrote:
> Bodo Stroesser writes:
>
>
>>If a SIGSEGV is forced since the stackframe/sigcontext for a signal-handler
>>could not be created, this SIGSEGV is queued only. To deliver it, do_signal()
>>must be called again, which normally won't happen (with the exception of
>>sys_sigretrun/sys_rt_sigreturn). Thus, SIGSEGV stays in the queue until the
>
>
> We got this right on ppc/ppc64, I believe. After calling do_signal,
> we loop around again (in the exception exit path in entry.S) and check
> the signal pending and reschedule bits again (in the thread_info
> flags). We only exit to usermode when they are both zero.
>
> Paul.
Aha! Sorry, didn't recognize that loop.
Bodo
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2004-12-02 11:40 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <200411130201.iAD210pT005889@ccure.user-mode-linux.org>
2004-11-13 0:34 ` [PATCH 9/11] - UML - fix signal mask on delivery error Andrew Morton
2004-11-14 22:13 ` Jeff Dike
2004-11-15 8:35 ` David Woodhouse
2004-11-22 15:30 ` David Woodhouse
2004-11-15 11:40 ` Bodo Stroesser
2004-11-15 17:18 ` Jeff Dike
2004-11-16 9:39 ` Bodo Stroesser
2004-11-30 14:59 ` David Woodhouse
2004-12-02 9:55 ` Bodo Stroesser
2004-12-02 11:25 ` Paul Mackerras
2004-12-02 11:40 ` Bodo Stroesser
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox