* [PATCH 1/5] m32r: fix rt_sigsuspend()
@ 2010-09-24 5:20 Al Viro
2010-09-24 5:22 ` [PATCH 2/5] make m32r handle multiple pending signals Al Viro
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Al Viro @ 2010-09-24 5:20 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Hirokazu Takata, linux-kernel, linux-arch
do_signal() should know about saved_mask for it to work...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
arch/m32r/include/asm/signal.h | 1 -
arch/m32r/include/asm/unistd.h | 1 +
arch/m32r/kernel/entry.S | 3 +-
arch/m32r/kernel/signal.c | 48 ++++++++++------------------------------
4 files changed, 14 insertions(+), 39 deletions(-)
diff --git a/arch/m32r/include/asm/signal.h b/arch/m32r/include/asm/signal.h
index 9c1acb2..b2eeb0d 100644
--- a/arch/m32r/include/asm/signal.h
+++ b/arch/m32r/include/asm/signal.h
@@ -157,7 +157,6 @@ typedef struct sigaltstack {
#undef __HAVE_ARCH_SIG_BITOPS
struct pt_regs;
-extern int do_signal(struct pt_regs *regs, sigset_t *oldset);
#define ptrace_signal_deliver(regs, cookie) do { } while (0)
diff --git a/arch/m32r/include/asm/unistd.h b/arch/m32r/include/asm/unistd.h
index 7612577..c705456 100644
--- a/arch/m32r/include/asm/unistd.h
+++ b/arch/m32r/include/asm/unistd.h
@@ -351,6 +351,7 @@
#define __ARCH_WANT_SYS_OLD_GETRLIMIT /*will be unused*/
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_RT_SIGACTION
+#define __ARCH_WANT_SYS_RT_SIGSUSPEND
#define __IGNORE_lchown
#define __IGNORE_setuid
diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S
index 4038698..90149da 100644
--- a/arch/m32r/kernel/entry.S
+++ b/arch/m32r/kernel/entry.S
@@ -235,8 +235,7 @@ work_resched:
work_notifysig: ; deal with pending signals and
; notify-resume requests
mv r0, sp ; arg1 : struct pt_regs *regs
- ldi r1, #0 ; arg2 : sigset_t *oldset
- mv r2, r9 ; arg3 : __u32 thread_info_flags
+ ldi r1, r9 ; arg2 : __u32 thread_info_flags
bl do_notify_resume
bra restore_all
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
index 144b0f1..acd69f7 100644
--- a/arch/m32r/kernel/signal.c
+++ b/arch/m32r/kernel/signal.c
@@ -28,37 +28,6 @@
#define DEBUG_SIG 0
-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-
-int do_signal(struct pt_regs *, sigset_t *);
-
-asmlinkage int
-sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize,
- unsigned long r2, unsigned long r3, unsigned long r4,
- unsigned long r5, unsigned long r6, struct pt_regs *regs)
-{
- sigset_t newset;
-
- /* XXX: Don't preclude handling different sized sigset_t's. */
- if (sigsetsize != sizeof(sigset_t))
- return -EINVAL;
-
- if (copy_from_user(&newset, unewset, sizeof(newset)))
- return -EFAULT;
- sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP));
-
- spin_lock_irq(¤t->sighand->siglock);
- current->saved_sigmask = current->blocked;
- current->blocked = newset;
- recalc_sigpending();
- spin_unlock_irq(¤t->sighand->siglock);
-
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- set_thread_flag(TIF_RESTORE_SIGMASK);
- return -ERESTARTNOHAND;
-}
-
asmlinkage int
sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
unsigned long r2, unsigned long r3, unsigned long r4,
@@ -332,12 +301,13 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
* want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake.
*/
-int do_signal(struct pt_regs *regs, sigset_t *oldset)
+static int do_signal(struct pt_regs *regs)
{
siginfo_t info;
int signr;
struct k_sigaction ka;
unsigned short inst;
+ sigset_t *oldset;
/*
* We want the common case to go fast, which
@@ -351,7 +321,9 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
if (try_to_freeze())
goto no_signal;
- if (!oldset)
+ if (test_thread_flag(TIF_RESTORE_SIGMASK))
+ oldset = ¤t->saved_sigmask;
+ else
oldset = ¤t->blocked;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
@@ -364,6 +336,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
/* Whee! Actually deliver the signal. */
handle_signal(signr, &ka, &info, oldset, regs);
+ clear_thread_flag(TIF_RESTORE_SIGMASK);
return 1;
}
@@ -391,6 +364,10 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
regs->bpc -= 4;
}
}
+ if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+ clear_thread_flag(TIF_RESTORE_SIGMASK);
+ sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);
+ }
return 0;
}
@@ -398,8 +375,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
* notification of userspace execution resumption
* - triggered by current->work.notify_resume
*/
-void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,
- __u32 thread_info_flags)
+void do_notify_resume(struct pt_regs *regs, __u32 thread_info_flags)
{
/* Pending single-step? */
if (thread_info_flags & _TIF_SINGLESTEP)
@@ -407,7 +383,7 @@ void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,
/* deal with pending signal delivery */
if (thread_info_flags & _TIF_SIGPENDING)
- do_signal(regs,oldset);
+ do_signal(regs);
if (thread_info_flags & _TIF_NOTIFY_RESUME) {
clear_thread_flag(TIF_NOTIFY_RESUME);
--
1.5.6.5
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 2/5] make m32r handle multiple pending signals
2010-09-24 5:20 [PATCH 1/5] m32r: fix rt_sigsuspend() Al Viro
@ 2010-09-24 5:22 ` Al Viro
2010-09-24 5:23 ` [PATCH 3/5] m32r: don't block signals if sigframe setup has failed Al Viro
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Al Viro @ 2010-09-24 5:22 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Hirokazu Takata, linux-kernel, linux-arch
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
arch/m32r/kernel/entry.S | 4 ++--
arch/m32r/kernel/signal.c | 6 ++++--
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S
index 90149da..225412b 100644
--- a/arch/m32r/kernel/entry.S
+++ b/arch/m32r/kernel/entry.S
@@ -235,9 +235,9 @@ work_resched:
work_notifysig: ; deal with pending signals and
; notify-resume requests
mv r0, sp ; arg1 : struct pt_regs *regs
- ldi r1, r9 ; arg2 : __u32 thread_info_flags
+ mv r1, r9 ; arg2 : __u32 thread_info_flags
bl do_notify_resume
- bra restore_all
+ bra resume_userspace
; perform syscall exit tracing
ALIGN
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
index acd69f7..db15226 100644
--- a/arch/m32r/kernel/signal.c
+++ b/arch/m32r/kernel/signal.c
@@ -282,6 +282,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
regs->bpc -= 2;
else
regs->bpc -= 4;
+ regs->syscall_nr = -1;
}
}
@@ -353,8 +354,8 @@ static int do_signal(struct pt_regs *regs)
regs->bpc -= 2;
else
regs->bpc -= 4;
- }
- if (regs->r0 == -ERESTART_RESTARTBLOCK){
+ regs->syscall_nr = -1;
+ } else if (regs->r0 == -ERESTART_RESTARTBLOCK){
regs->r0 = regs->orig_r0;
regs->r7 = __NR_restart_syscall;
inst = *(unsigned short *)(regs->bpc - 2);
@@ -362,6 +363,7 @@ static int do_signal(struct pt_regs *regs)
regs->bpc -= 2;
else
regs->bpc -= 4;
+ regs->syscall_nr = -1;
}
}
if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
--
1.5.6.5
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 3/5] m32r: don't block signals if sigframe setup has failed
2010-09-24 5:20 [PATCH 1/5] m32r: fix rt_sigsuspend() Al Viro
2010-09-24 5:22 ` [PATCH 2/5] make m32r handle multiple pending signals Al Viro
@ 2010-09-24 5:23 ` Al Viro
2010-09-24 5:24 ` [PATCH 4/5] m32r: hole in shifting pc back Al Viro
2010-09-24 5:25 ` [PATCH 5/5] m32r: fix breakage from "m32r: use generic ptrace_resume code" Al Viro
3 siblings, 0 replies; 5+ messages in thread
From: Al Viro @ 2010-09-24 5:23 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Hirokazu Takata, linux-kernel, linux-arch
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
arch/m32r/kernel/signal.c | 23 +++++++++++++----------
1 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
index db15226..a56fcbd 100644
--- a/arch/m32r/kernel/signal.c
+++ b/arch/m32r/kernel/signal.c
@@ -187,7 +187,7 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
return (void __user *)((sp - frame_size) & -8ul);
}
-static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *set, struct pt_regs *regs)
{
struct rt_sigframe __user *frame;
@@ -244,17 +244,18 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
current->comm, current->pid, frame, regs->pc);
#endif
- return;
+ return 0;
give_sigsegv:
force_sigsegv(sig, current);
+ return -EFAULT;
}
/*
* OK, we're invoking a handler
*/
-static void
+static int
handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *oldset, struct pt_regs *regs)
{
@@ -287,7 +288,8 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
}
/* Set up the stack frame */
- setup_rt_frame(sig, ka, info, oldset, regs);
+ if (setup_rt_frame(sig, ka, info, oldset, regs))
+ return -EFAULT;
spin_lock_irq(¤t->sighand->siglock);
sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
@@ -295,6 +297,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
sigaddset(¤t->blocked,sig);
recalc_sigpending();
spin_unlock_irq(¤t->sighand->siglock);
+ return 0;
}
/*
@@ -302,7 +305,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
* want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake.
*/
-static int do_signal(struct pt_regs *regs)
+static void do_signal(struct pt_regs *regs)
{
siginfo_t info;
int signr;
@@ -317,7 +320,7 @@ static int do_signal(struct pt_regs *regs)
* if so.
*/
if (!user_mode(regs))
- return 1;
+ return;
if (try_to_freeze())
goto no_signal;
@@ -336,9 +339,10 @@ static int do_signal(struct pt_regs *regs)
*/
/* Whee! Actually deliver the signal. */
- handle_signal(signr, &ka, &info, oldset, regs);
- clear_thread_flag(TIF_RESTORE_SIGMASK);
- return 1;
+ if (handle_signal(signr, &ka, &info, oldset, regs) == 0)
+ clear_thread_flag(TIF_RESTORE_SIGMASK);
+
+ return;
}
no_signal:
@@ -370,7 +374,6 @@ static int do_signal(struct pt_regs *regs)
clear_thread_flag(TIF_RESTORE_SIGMASK);
sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);
}
- return 0;
}
/*
--
1.5.6.5
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 4/5] m32r: hole in shifting pc back
2010-09-24 5:20 [PATCH 1/5] m32r: fix rt_sigsuspend() Al Viro
2010-09-24 5:22 ` [PATCH 2/5] make m32r handle multiple pending signals Al Viro
2010-09-24 5:23 ` [PATCH 3/5] m32r: don't block signals if sigframe setup has failed Al Viro
@ 2010-09-24 5:24 ` Al Viro
2010-09-24 5:25 ` [PATCH 5/5] m32r: fix breakage from "m32r: use generic ptrace_resume code" Al Viro
3 siblings, 0 replies; 5+ messages in thread
From: Al Viro @ 2010-09-24 5:24 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Hirokazu Takata, linux-kernel, linux-arch
It's a userland pointer; worse, an untrustable one since ptrace
has just provided a chance to modify it.
X-Roothole-Covering-Cabal: TINRCC
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
arch/m32r/kernel/signal.c | 38 +++++++++++++++++---------------------
1 files changed, 17 insertions(+), 21 deletions(-)
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
index a56fcbd..7bbe386 100644
--- a/arch/m32r/kernel/signal.c
+++ b/arch/m32r/kernel/signal.c
@@ -251,6 +251,19 @@ give_sigsegv:
return -EFAULT;
}
+static int prev_insn(struct pt_regs *regs)
+{
+ u16 inst;
+ if (get_user(&inst, (u16 __user *)(regs->bpc - 2)))
+ return -EFAULT;
+ if ((inst & 0xfff0) == 0x10f0) /* trap ? */
+ regs->bpc -= 2;
+ else
+ regs->bpc -= 4;
+ regs->syscall_nr = -1;
+ return 0;
+}
+
/*
* OK, we're invoking a handler
*/
@@ -259,8 +272,6 @@ static int
handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *oldset, struct pt_regs *regs)
{
- unsigned short inst;
-
/* Are we from a system call? */
if (regs->syscall_nr >= 0) {
/* If so, check system call restarting.. */
@@ -278,12 +289,8 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
/* fallthrough */
case -ERESTARTNOINTR:
regs->r0 = regs->orig_r0;
- inst = *(unsigned short *)(regs->bpc - 2);
- if ((inst & 0xfff0) == 0x10f0) /* trap ? */
- regs->bpc -= 2;
- else
- regs->bpc -= 4;
- regs->syscall_nr = -1;
+ if (prev_insn(regs) < 0)
+ return -EFAULT;
}
}
@@ -310,7 +317,6 @@ static void do_signal(struct pt_regs *regs)
siginfo_t info;
int signr;
struct k_sigaction ka;
- unsigned short inst;
sigset_t *oldset;
/*
@@ -353,21 +359,11 @@ static void do_signal(struct pt_regs *regs)
regs->r0 == -ERESTARTSYS ||
regs->r0 == -ERESTARTNOINTR) {
regs->r0 = regs->orig_r0;
- inst = *(unsigned short *)(regs->bpc - 2);
- if ((inst & 0xfff0) == 0x10f0) /* trap ? */
- regs->bpc -= 2;
- else
- regs->bpc -= 4;
- regs->syscall_nr = -1;
+ prev_insn(regs);
} else if (regs->r0 == -ERESTART_RESTARTBLOCK){
regs->r0 = regs->orig_r0;
regs->r7 = __NR_restart_syscall;
- inst = *(unsigned short *)(regs->bpc - 2);
- if ((inst & 0xfff0) == 0x10f0) /* trap ? */
- regs->bpc -= 2;
- else
- regs->bpc -= 4;
- regs->syscall_nr = -1;
+ prev_insn(regs);
}
}
if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
--
1.5.6.5
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 5/5] m32r: fix breakage from "m32r: use generic ptrace_resume code"
2010-09-24 5:20 [PATCH 1/5] m32r: fix rt_sigsuspend() Al Viro
` (2 preceding siblings ...)
2010-09-24 5:24 ` [PATCH 4/5] m32r: hole in shifting pc back Al Viro
@ 2010-09-24 5:25 ` Al Viro
3 siblings, 0 replies; 5+ messages in thread
From: Al Viro @ 2010-09-24 5:25 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Hirokazu Takata, linux-kernel, linux-arch
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
arch/m32r/kernel/ptrace.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c
index e555091..0021ade 100644
--- a/arch/m32r/kernel/ptrace.c
+++ b/arch/m32r/kernel/ptrace.c
@@ -592,16 +592,17 @@ void user_enable_single_step(struct task_struct *child)
if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0)
!= sizeof(insn))
- break;
+ return -EIO;
compute_next_pc(insn, pc, &next_pc, child);
if (next_pc & 0x80000000)
- break;
+ return -EIO;
if (embed_debug_trap(child, next_pc))
- break;
+ return -EIO;
invalidate_cache();
+ return 0;
}
void user_disable_single_step(struct task_struct *child)
--
1.5.6.5
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2010-09-24 5:25 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-09-24 5:20 [PATCH 1/5] m32r: fix rt_sigsuspend() Al Viro
2010-09-24 5:22 ` [PATCH 2/5] make m32r handle multiple pending signals Al Viro
2010-09-24 5:23 ` [PATCH 3/5] m32r: don't block signals if sigframe setup has failed Al Viro
2010-09-24 5:24 ` [PATCH 4/5] m32r: hole in shifting pc back Al Viro
2010-09-24 5:25 ` [PATCH 5/5] m32r: fix breakage from "m32r: use generic ptrace_resume code" Al Viro
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.