m32r: fix rt_sigsuspend()
Subsystems (2)
PATCH 1/5 m32r: fix rt_sigsuspend()
do_signal() should know about saved_mask for it to work...
Signed-off-by Al Viro <[email protected]>
--- 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(-)
arch/m32r/include/asm/signal.h +0 -1
@@ -157,7 +157,6 @@ typedef struct sigaltstack {#undef __HAVE_ARCH_SIG_BITOPSstruct pt_regs ; -extern int do_signal (struct pt_regs *regs,sigset_t *oldset);#define ptrace_signal_deliver (regs, cookie) do { } while (0)
arch/m32r/include/asm/unistd.h +1 -0
@@ -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
arch/m32r/kernel/entry.S +1 -2
@@ -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
arch/m32r/kernel/signal.c +12 -36
95 lines not on this page · raw message
Signature · 1 line
1.5.6.5
PATCH 2/5 make m32r handle multiple pending signals
Signed-off-by Al Viro <[email protected]>
--- arch/m32r/kernel/entry.S | 4 ++-- arch/m32r/kernel/signal.c | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-)
arch/m32r/kernel/entry.S +2 -2
@@ -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
arch/m32r/kernel/signal.c +4 -2
@@ -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 )) {
Signature · 1 line
1.5.6.5
PATCH 3/5 m32r: don't block signals if sigframe setup has failed
In reply to Al ViroSigned-off-by Al Viro <[email protected]>
--- arch/m32r/kernel/signal.c | 23 +++++++++++++---------- 1 files changed, 13 insertions(+), 10 deletions(-)
arch/m32r/kernel/signal.c +13 -10
@@ -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 ; }/*
Signature · 1 line
1.5.6.5
PATCH 4/5 m32r: hole in shifting pc back
In reply to Al ViroIt'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 <[email protected]>
--- arch/m32r/kernel/signal.c | 38 +++++++++++++++++--------------------- 1 files changed, 17 insertions(+), 21 deletions(-)
arch/m32r/kernel/signal.c +17 -21
@@ -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 )) {
Signature · 1 line
1.5.6.5
PATCH 5/5 m32r: fix breakage from "m32r: use generic ptrace_resume code"
In reply to Al ViroSigned-off-by Al Viro <[email protected]>
--- arch/m32r/kernel/ptrace.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-)
arch/m32r/kernel/ptrace.c +4 -3
@@ -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)
Signature · 1 line
1.5.6.5