* [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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).