static int do_signal(struct pt_regs *regs) { sigset_t *oldset; siginfo_t info; int signr; struct k_sigaction ka; int ret; int is32 = is_32bit_task(); if (current_thread_info()->local_flags & _TLF_RESTORE_SIGMASK) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); check_syscall_restart(regs, &ka, signr > 0); if (signr <= 0) { struct thread_info *ti = current_thread_info(); if (ti->local_flags & _TLF_RESTORE_SIGMASK) { ti->local_flags &= ~_TLF_RESTORE_SIGMASK; sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } regs->trap = 0; return 0; } #ifndef CONFIG_PPC_ADV_DEBUG_REGS if (current->thread.dabr) set_dabr(current->thread.dabr); #endif thread_change_pc(current, regs); if (is32) { if (ka.sa.sa_flags & SA_SIGINFO) ret = handle_rt_signal32(signr, &ka, &info, oldset, regs); else ret = handle_signal32(signr, &ka, &info, oldset, regs); } else { ret = handle_rt_signal64(signr, &ka, &info, oldset, regs); } regs->trap = 0; if (ret) { block_sigmask(&ka, signr); current_thread_info()->local_flags &= ~_TLF_RESTORE_SIGMASK; tracehook_signal_handler(signr, &info, &ka, regs, test_thread_flag(TIF_SINGLESTEP)); } return ret; }
unsigned long arch_mmap_rnd(void) { unsigned long rnd; /* 8MB for 32bit, 1GB for 64bit */ if (is_32bit_task()) rnd = (unsigned long)get_random_int() % (1<<(23-PAGE_SHIFT)); else rnd = (unsigned long)get_random_int() % (1<<(30-PAGE_SHIFT)); if (current->flags & PF_RANDOMIZE) { /* 8MB for 32bit, 1GB for 64bit */ if (is_32bit_task()) rnd = get_random_long() % (1<<(23-PAGE_SHIFT)); else rnd = get_random_long() % (1UL<<(30-PAGE_SHIFT)); } return rnd << PAGE_SHIFT; }
static int do_signal(struct pt_regs *regs) { sigset_t *oldset = sigmask_to_save(); siginfo_t info; int signr; struct k_sigaction ka; int ret; int is32 = is_32bit_task(); signr = get_signal_to_deliver(&info, &ka, regs, NULL); /* Is there any syscall restart business here ? */ check_syscall_restart(regs, &ka, signr > 0); if (signr <= 0) { /* No signal to deliver -- put the saved sigmask back */ restore_saved_sigmask(); regs->trap = 0; return 0; /* no signals delivered */ } #ifndef CONFIG_PPC_ADV_DEBUG_REGS /* * Reenable the DABR before delivering the signal to * user space. The DABR will have been cleared if it * triggered inside the kernel. */ if (current->thread.hw_brk.address && current->thread.hw_brk.type) set_breakpoint(¤t->thread.hw_brk); #endif /* Re-enable the breakpoints for the signal stack */ thread_change_pc(current, regs); if (is32) { if (ka.sa.sa_flags & SA_SIGINFO) ret = handle_rt_signal32(signr, &ka, &info, oldset, regs); else ret = handle_signal32(signr, &ka, &info, oldset, regs); } else { ret = handle_rt_signal64(signr, &ka, &info, oldset, regs); } regs->trap = 0; if (ret) { signal_delivered(signr, &info, &ka, regs, test_thread_flag(TIF_SINGLESTEP)); } return ret; }
unsigned long arch_mmap_rnd(void) { unsigned long rnd; /* 8MB for 32bit, 1GB for 64bit */ if (is_32bit_task()) rnd = (unsigned long)get_random_int() % (1<<(23-PAGE_SHIFT)); else rnd = (unsigned long)get_random_int() % (1<<(30-PAGE_SHIFT)); return rnd << PAGE_SHIFT; }
/* * Since get_random_int() returns the same value within a 1 jiffy window, * we will almost always get the same randomisation for the stack and mmap * region. This will mean the relative distance between stack and mmap will * be the same. * * To avoid this we can shift the randomness by 1 bit. */ static unsigned long mmap_rnd(void) { unsigned long rnd = 0; if (current->flags & PF_RANDOMIZE) { /* 8MB for 32bit, 1GB for 64bit */ if (is_32bit_task()) rnd = (long)(get_random_int() % (1<<(22-PAGE_SHIFT))); else rnd = (long)(get_random_int() % (1<<(29-PAGE_SHIFT))); } return (rnd << PAGE_SHIFT) * 2; }
int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) { if (!vdso_enabled) return 0; #if defined CONFIG_COMPAT if (!(is_32bit_task())) return map_vdso(&vdso_image_64_builtin, &vdso_mapping64); else return map_vdso(&vdso_image_32_builtin, &vdso_mapping32); #else return map_vdso(&vdso_image_64_builtin, &vdso_mapping64); #endif }
static unsigned long mmap_rnd(void) { unsigned long rnd = 0; /* * 8 bits of randomness in 32bit mmaps, 20 address space bits * 28 bits of randomness in 64bit mmaps, 40 address space bits */ if (current->flags & PF_RANDOMIZE) { if (is_32bit_task()) rnd = get_random_int() % (1<<8); else rnd = get_random_int() % (1<<28); } return rnd << PAGE_SHIFT; }
void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth) { unsigned long sp = regs->gpr[1]; int first_frame = 1; /* We ditch the top stackframe so need to loop through an extra time */ depth += 1; if (!user_mode(regs)) { while (depth--) { sp = kernel_getsp(sp, first_frame); if (!sp) break; first_frame = 0; } } else { pagefault_disable(); #ifdef CONFIG_PPC64 if (!is_32bit_task()) { while (depth--) { sp = user_getsp64(sp, first_frame); if (!sp) break; first_frame = 0; } pagefault_enable(); return; } #endif while (depth--) { sp = user_getsp32(sp, first_frame); if (!sp) break; first_frame = 0; } pagefault_enable(); } }
int do_signal(sigset_t *oldset, struct pt_regs *regs) { siginfo_t info; int signr; struct k_sigaction ka; int ret; int is32 = is_32bit_task(); if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else if (!oldset) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); /* Is there any syscall restart business here ? */ check_syscall_restart(regs, &ka, signr > 0); if (signr <= 0) { /* No signal to deliver -- put the saved sigmask back */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) { clear_thread_flag(TIF_RESTORE_SIGMASK); sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } return 0; /* no signals delivered */ } /* * Reenable the DABR before delivering the signal to * user space. The DABR will have been cleared if it * triggered inside the kernel. */ if (current->thread.dabr) set_dabr(current->thread.dabr); if (is32) { if (ka.sa.sa_flags & SA_SIGINFO) ret = handle_rt_signal32(signr, &ka, &info, oldset, regs); else ret = handle_signal32(signr, &ka, &info, oldset, regs); } else { ret = handle_rt_signal64(signr, &ka, &info, oldset, regs); } if (ret) { spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked, ¤t->blocked, &ka.sa.sa_mask); if (!(ka.sa.sa_flags & SA_NODEFER)) sigaddset(¤t->blocked, signr); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); /* * A signal was successfully delivered; the saved sigmask is in * its frame, and we can clear the TIF_RESTORE_SIGMASK flag. */ if (test_thread_flag(TIF_RESTORE_SIGMASK)) clear_thread_flag(TIF_RESTORE_SIGMASK); } return ret; }
static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs) { siginfo_t info; int signr; struct k_sigaction ka; int ret; int is32 = is_32bit_task(); #ifdef CONFIG_PREEMPT_RT /* * Fully-preemptible kernel does not need interrupts disabled: */ local_irq_enable(); preempt_check_resched(); #endif if (current_thread_info()->local_flags & _TLF_RESTORE_SIGMASK) oldset = ¤t->saved_sigmask; else if (!oldset) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); /* Is there any syscall restart business here ? */ check_syscall_restart(regs, &ka, signr > 0); if (signr <= 0) { struct thread_info *ti = current_thread_info(); /* No signal to deliver -- put the saved sigmask back */ if (ti->local_flags & _TLF_RESTORE_SIGMASK) { ti->local_flags &= ~_TLF_RESTORE_SIGMASK; sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } return 0; /* no signals delivered */ } /* * Reenable the DABR before delivering the signal to * user space. The DABR will have been cleared if it * triggered inside the kernel. */ if (current->thread.dabr) { set_dabr(current->thread.dabr); #if defined(CONFIG_BOOKE) mtspr(SPRN_DBCR0, current->thread.dbcr0); #endif } if (is32) { if (ka.sa.sa_flags & SA_SIGINFO) ret = handle_rt_signal32(signr, &ka, &info, oldset, regs); else ret = handle_signal32(signr, &ka, &info, oldset, regs); } else { ret = handle_rt_signal64(signr, &ka, &info, oldset, regs); } if (ret) { spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked, ¤t->blocked, &ka.sa.sa_mask); if (!(ka.sa.sa_flags & SA_NODEFER)) sigaddset(¤t->blocked, signr); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); /* * A signal was successfully delivered; the saved sigmask is in * its frame, and we can clear the TLF_RESTORE_SIGMASK flag. */ current_thread_info()->local_flags &= ~_TLF_RESTORE_SIGMASK; /* * Let tracing know that we've done the handler setup. */ tracehook_signal_handler(signr, &info, &ka, regs, test_thread_flag(TIF_SINGLESTEP)); } return ret; }
static int do_signal(struct pt_regs *regs) { sigset_t *oldset; siginfo_t info; int signr; struct k_sigaction ka; int ret; int is32 = is_32bit_task(); if (current_thread_info()->local_flags & _TLF_RESTORE_SIGMASK) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); /* Is there any syscall restart business here ? */ check_syscall_restart(regs, &ka, signr > 0); if (signr <= 0) { struct thread_info *ti = current_thread_info(); /* No signal to deliver -- put the saved sigmask back */ if (ti->local_flags & _TLF_RESTORE_SIGMASK) { ti->local_flags &= ~_TLF_RESTORE_SIGMASK; sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } regs->trap = 0; return 0; /* no signals delivered */ } #ifndef CONFIG_PPC_ADV_DEBUG_REGS /* * Reenable the DABR before delivering the signal to * user space. The DABR will have been cleared if it * triggered inside the kernel. */ if (current->thread.dabr) set_dabr(current->thread.dabr); #endif /* Re-enable the breakpoints for the signal stack */ thread_change_pc(current, regs); if (is32) { if (ka.sa.sa_flags & SA_SIGINFO) ret = handle_rt_signal32(signr, &ka, &info, oldset, regs); else ret = handle_signal32(signr, &ka, &info, oldset, regs); } else { ret = handle_rt_signal64(signr, &ka, &info, oldset, regs); } regs->trap = 0; if (ret) { block_sigmask(&ka, signr); /* * A signal was successfully delivered; the saved sigmask is in * its frame, and we can clear the TLF_RESTORE_SIGMASK flag. */ current_thread_info()->local_flags &= ~_TLF_RESTORE_SIGMASK; /* * Let tracing know that we've done the handler setup. */ tracehook_signal_handler(signr, &info, &ka, regs, test_thread_flag(TIF_SINGLESTEP)); } return ret; }