diff options
Diffstat (limited to 'arch/m68k/kernel')
-rw-r--r-- | arch/m68k/kernel/signal.c | 75 | ||||
-rw-r--r-- | arch/m68k/kernel/sys_m68k.c | 21 | ||||
-rw-r--r-- | arch/m68k/kernel/syscalltable.S | 3 |
3 files changed, 42 insertions, 57 deletions
diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c index 57fd286e4b0..967a8b7e152 100644 --- a/arch/m68k/kernel/signal.c +++ b/arch/m68k/kernel/signal.c @@ -835,38 +835,30 @@ static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs * } static inline void __user * -get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) +get_sigframe(struct ksignal *ksig, size_t frame_size) { - unsigned long usp; - - /* Default to using normal stack. */ - usp = rdusp(); + unsigned long usp = sigsp(rdusp(), ksig); - /* This is the X/Open sanctioned signal stack switching. */ - if (ka->sa.sa_flags & SA_ONSTACK) { - if (!sas_ss_flags(usp)) - usp = current->sas_ss_sp + current->sas_ss_size; - } return (void __user *)((usp - frame_size) & -8UL); } -static int setup_frame (int sig, struct k_sigaction *ka, - sigset_t *set, struct pt_regs *regs) +static int setup_frame(struct ksignal *ksig, sigset_t *set, + struct pt_regs *regs) { struct sigframe __user *frame; int fsize = frame_extra_sizes(regs->format); struct sigcontext context; - int err = 0; + int err = 0, sig = ksig->sig; if (fsize < 0) { #ifdef DEBUG printk ("setup_frame: Unknown frame format %#x\n", regs->format); #endif - goto give_sigsegv; + return -EFAULT; } - frame = get_sigframe(ka, regs, sizeof(*frame) + fsize); + frame = get_sigframe(ksig, sizeof(*frame) + fsize); if (fsize) err |= copy_to_user (frame + 1, regs + 1, fsize); @@ -899,7 +891,7 @@ static int setup_frame (int sig, struct k_sigaction *ka, #endif if (err) - goto give_sigsegv; + return -EFAULT; push_cache ((unsigned long) &frame->retcode); @@ -908,7 +900,7 @@ static int setup_frame (int sig, struct k_sigaction *ka, * to destroy is successfully copied to sigframe. */ wrusp ((unsigned long) frame); - regs->pc = (unsigned long) ka->sa.sa_handler; + regs->pc = (unsigned long) ksig->ka.sa.sa_handler; adjustformat(regs); /* @@ -934,28 +926,24 @@ static int setup_frame (int sig, struct k_sigaction *ka, tregs->sr = regs->sr; } return 0; - -give_sigsegv: - force_sigsegv(sig, current); - return err; } -static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, - sigset_t *set, struct pt_regs *regs) +static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, + struct pt_regs *regs) { struct rt_sigframe __user *frame; int fsize = frame_extra_sizes(regs->format); - int err = 0; + int err = 0, sig = ksig->sig; if (fsize < 0) { #ifdef DEBUG printk ("setup_frame: Unknown frame format %#x\n", regs->format); #endif - goto give_sigsegv; + return -EFAULT; } - frame = get_sigframe(ka, regs, sizeof(*frame)); + frame = get_sigframe(ksig, sizeof(*frame)); if (fsize) err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize); @@ -968,7 +956,7 @@ static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, &frame->sig); err |= __put_user(&frame->info, &frame->pinfo); err |= __put_user(&frame->uc, &frame->puc); - err |= copy_siginfo_to_user(&frame->info, info); + err |= copy_siginfo_to_user(&frame->info, &ksig->info); /* Create the ucontext. */ err |= __put_user(0, &frame->uc.uc_flags); @@ -996,7 +984,7 @@ static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, #endif /* CONFIG_MMU */ if (err) - goto give_sigsegv; + return -EFAULT; push_cache ((unsigned long) &frame->retcode); @@ -1005,7 +993,7 @@ static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, * to destroy is successfully copied to sigframe. */ wrusp ((unsigned long) frame); - regs->pc = (unsigned long) ka->sa.sa_handler; + regs->pc = (unsigned long) ksig->ka.sa.sa_handler; adjustformat(regs); /* @@ -1031,10 +1019,6 @@ static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, tregs->sr = regs->sr; } return 0; - -give_sigsegv: - force_sigsegv(sig, current); - return err; } static inline void @@ -1074,26 +1058,22 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) * OK, we're invoking a handler */ static void -handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, - struct pt_regs *regs) +handle_signal(struct ksignal *ksig, struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); int err; /* are we from a system call? */ if (regs->orig_d0 >= 0) /* If so, check system call restarting.. */ - handle_restart(regs, ka, 1); + handle_restart(regs, &ksig->ka, 1); /* set up the stack frame */ - if (ka->sa.sa_flags & SA_SIGINFO) - err = setup_rt_frame(sig, ka, info, oldset, regs); + if (ksig->ka.sa.sa_flags & SA_SIGINFO) + err = setup_rt_frame(ksig, oldset, regs); else - err = setup_frame(sig, ka, oldset, regs); - - if (err) - return; + err = setup_frame(ksig, oldset, regs); - signal_delivered(sig, info, ka, regs, 0); + signal_setup_done(err, ksig, 0); if (test_thread_flag(TIF_DELAYED_TRACE)) { regs->sr &= ~0x8000; @@ -1108,16 +1088,13 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, */ static void do_signal(struct pt_regs *regs) { - siginfo_t info; - struct k_sigaction ka; - int signr; + struct ksignal ksig; current->thread.esp0 = (unsigned long) regs; - signr = get_signal_to_deliver(&info, &ka, regs, NULL); - if (signr > 0) { + if (get_signal(&ksig)) { /* Whee! Actually deliver the signal. */ - handle_signal(signr, &ka, &info, regs); + handle_signal(&ksig, regs); return; } diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c index 3a480b3df0d..9aa01adb407 100644 --- a/arch/m68k/kernel/sys_m68k.c +++ b/arch/m68k/kernel/sys_m68k.c @@ -376,7 +376,6 @@ cache_flush_060 (unsigned long addr, int scope, int cache, unsigned long len) asmlinkage int sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) { - struct vm_area_struct *vma; int ret = -EINVAL; if (scope < FLUSH_SCOPE_LINE || scope > FLUSH_SCOPE_ALL || @@ -389,17 +388,21 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) if (!capable(CAP_SYS_ADMIN)) goto out; } else { + struct vm_area_struct *vma; + + /* Check for overflow. */ + if (addr + len < addr) + goto out; + /* * Verify that the specified address region actually belongs * to this process. */ - vma = find_vma (current->mm, addr); ret = -EINVAL; - /* Check for overflow. */ - if (addr + len < addr) - goto out; - if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end) - goto out; + down_read(¤t->mm->mmap_sem); + vma = find_vma(current->mm, addr); + if (!vma || addr < vma->vm_start || addr + len > vma->vm_end) + goto out_unlock; } if (CPU_IS_020_OR_030) { @@ -429,7 +432,7 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) __asm__ __volatile__ ("movec %0, %%cacr" : : "r" (cacr)); } ret = 0; - goto out; + goto out_unlock; } else { /* * 040 or 060: don't blindly trust 'scope', someone could @@ -446,6 +449,8 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) ret = cache_flush_060 (addr, scope, cache, len); } } +out_unlock: + up_read(¤t->mm->mmap_sem); out: return ret; } diff --git a/arch/m68k/kernel/syscalltable.S b/arch/m68k/kernel/syscalltable.S index 501e1021278..2ca219e184c 100644 --- a/arch/m68k/kernel/syscalltable.S +++ b/arch/m68k/kernel/syscalltable.S @@ -372,4 +372,7 @@ ENTRY(sys_call_table) .long sys_sched_setattr .long sys_sched_getattr /* 350 */ .long sys_renameat2 + .long sys_getrandom + .long sys_memfd_create + .long sys_bpf |