Skip to content

Commit

Permalink
Merge branch 'siginfo-linus' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/git/ebiederm/user-namespace

Pull siginfo updates from Eric Biederman:
 "This set of changes close the known issues with setting si_code to an
  invalid value, and with not fully initializing struct siginfo. There
  remains work to do on nds32, arc, unicore32, powerpc, arm, arm64, ia64
  and x86 to get the code that generates siginfo into a simpler and more
  maintainable state. Most of that work involves refactoring the signal
  handling code and thus careful code review.

  Also not included is the work to shrink the in kernel version of
  struct siginfo. That depends on getting the number of places that
  directly manipulate struct siginfo under control, as it requires the
  introduction of struct kernel_siginfo for the in kernel things.

  Overall this set of changes looks like it is making good progress, and
  with a little luck I will be wrapping up the siginfo work next
  development cycle"

* 'siginfo-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: (46 commits)
  signal/sh: Stop gcc warning about an impossible case in do_divide_error
  signal/mips: Report FPE_FLTUNK for undiagnosed floating point exceptions
  signal/um: More carefully relay signals in relay_signal.
  signal: Extend siginfo_layout with SIL_FAULT_{MCEERR|BNDERR|PKUERR}
  signal: Remove unncessary #ifdef SEGV_PKUERR in 32bit compat code
  signal/signalfd: Add support for SIGSYS
  signal/signalfd: Remove __put_user from signalfd_copyinfo
  signal/xtensa: Use force_sig_fault where appropriate
  signal/xtensa: Consistenly use SIGBUS in do_unaligned_user
  signal/um: Use force_sig_fault where appropriate
  signal/sparc: Use force_sig_fault where appropriate
  signal/sparc: Use send_sig_fault where appropriate
  signal/sh: Use force_sig_fault where appropriate
  signal/s390: Use force_sig_fault where appropriate
  signal/riscv: Replace do_trap_siginfo with force_sig_fault
  signal/riscv: Use force_sig_fault where appropriate
  signal/parisc: Use force_sig_fault where appropriate
  signal/parisc: Use force_sig_mceerr where appropriate
  signal/openrisc: Use force_sig_fault where appropriate
  signal/nios2: Use force_sig_fault where appropriate
  ...
  • Loading branch information
torvalds committed Jun 4, 2018
2 parents d8aed84 + 26da350 commit 93e95fa
Show file tree
Hide file tree
Showing 83 changed files with 493 additions and 1,066 deletions.
14 changes: 0 additions & 14 deletions arch/alpha/include/uapi/asm/siginfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,4 @@

#include <asm-generic/siginfo.h>

/*
* SIGFPE si_codes
*/
#ifdef __KERNEL__
#define FPE_FIXME 0 /* Broken dup of SI_USER */
#endif /* __KERNEL__ */

/*
* SIGTRAP si_codes
*/
#ifdef __KERNEL__
#define TRAP_FIXME 0 /* Broken dup of SI_USER */
#endif /* __KERNEL__ */

#endif
11 changes: 4 additions & 7 deletions arch/alpha/kernel/osf_sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -871,8 +871,7 @@ SYSCALL_DEFINE5(osf_setsysinfo, unsigned long, op, void __user *, buffer,
send a signal. Old exceptions are not signaled. */
fex = (exc >> IEEE_STATUS_TO_EXCSUM_SHIFT) & swcr;
if (fex) {
siginfo_t info;
int si_code = 0;
int si_code = FPE_FLTUNK;

if (fex & IEEE_TRAP_ENABLE_DNO) si_code = FPE_FLTUND;
if (fex & IEEE_TRAP_ENABLE_INE) si_code = FPE_FLTRES;
Expand All @@ -881,11 +880,9 @@ SYSCALL_DEFINE5(osf_setsysinfo, unsigned long, op, void __user *, buffer,
if (fex & IEEE_TRAP_ENABLE_DZE) si_code = FPE_FLTDIV;
if (fex & IEEE_TRAP_ENABLE_INV) si_code = FPE_FLTINV;

info.si_signo = SIGFPE;
info.si_errno = 0;
info.si_code = si_code;
info.si_addr = NULL; /* FIXME */
send_sig_info(SIGFPE, &info, current);
send_sig_fault(SIGFPE, si_code,
(void __user *)NULL, /* FIXME */
0, current);
}
return 0;
}
Expand Down
20 changes: 4 additions & 16 deletions arch/alpha/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,14 +219,8 @@ do_sigreturn(struct sigcontext __user *sc)

/* Send SIGTRAP if we're single-stepping: */
if (ptrace_cancel_bpt (current)) {
siginfo_t info;

info.si_signo = SIGTRAP;
info.si_errno = 0;
info.si_code = TRAP_BRKPT;
info.si_addr = (void __user *) regs->pc;
info.si_trapno = 0;
send_sig_info(SIGTRAP, &info, current);
send_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *) regs->pc, 0,
current);
}
return;

Expand All @@ -253,14 +247,8 @@ do_rt_sigreturn(struct rt_sigframe __user *frame)

/* Send SIGTRAP if we're single-stepping: */
if (ptrace_cancel_bpt (current)) {
siginfo_t info;

info.si_signo = SIGTRAP;
info.si_errno = 0;
info.si_code = TRAP_BRKPT;
info.si_addr = (void __user *) regs->pc;
info.si_trapno = 0;
send_sig_info(SIGTRAP, &info, current);
send_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *) regs->pc, 0,
current);
}
return;

Expand Down
79 changes: 20 additions & 59 deletions arch/alpha/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,6 @@ do_entArith(unsigned long summary, unsigned long write_mask,
struct pt_regs *regs)
{
long si_code = FPE_FLTINV;
siginfo_t info;

if (summary & 1) {
/* Software-completion summary bit is set, so try to
Expand All @@ -228,17 +227,12 @@ do_entArith(unsigned long summary, unsigned long write_mask,
}
die_if_kernel("Arithmetic fault", regs, 0, NULL);

info.si_signo = SIGFPE;
info.si_errno = 0;
info.si_code = si_code;
info.si_addr = (void __user *) regs->pc;
send_sig_info(SIGFPE, &info, current);
send_sig_fault(SIGFPE, si_code, (void __user *) regs->pc, 0, current);
}

asmlinkage void
do_entIF(unsigned long type, struct pt_regs *regs)
{
siginfo_t info;
int signo, code;

if ((regs->ps & ~IPL_MAX) == 0) {
Expand Down Expand Up @@ -270,31 +264,20 @@ do_entIF(unsigned long type, struct pt_regs *regs)

switch (type) {
case 0: /* breakpoint */
info.si_signo = SIGTRAP;
info.si_errno = 0;
info.si_code = TRAP_BRKPT;
info.si_trapno = 0;
info.si_addr = (void __user *) regs->pc;

if (ptrace_cancel_bpt(current)) {
regs->pc -= 4; /* make pc point to former bpt */
}

send_sig_info(SIGTRAP, &info, current);
send_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->pc, 0,
current);
return;

case 1: /* bugcheck */
info.si_signo = SIGTRAP;
info.si_errno = 0;
info.si_code = TRAP_FIXME;
info.si_addr = (void __user *) regs->pc;
info.si_trapno = 0;
send_sig_info(SIGTRAP, &info, current);
send_sig_fault(SIGTRAP, TRAP_UNK, (void __user *) regs->pc, 0,
current);
return;

case 2: /* gentrap */
info.si_addr = (void __user *) regs->pc;
info.si_trapno = regs->r16;
switch ((long) regs->r16) {
case GEN_INTOVF:
signo = SIGFPE;
Expand Down Expand Up @@ -326,7 +309,7 @@ do_entIF(unsigned long type, struct pt_regs *regs)
break;
case GEN_ROPRAND:
signo = SIGFPE;
code = FPE_FIXME;
code = FPE_FLTUNK;
break;

case GEN_DECOVF:
Expand All @@ -348,15 +331,12 @@ do_entIF(unsigned long type, struct pt_regs *regs)
case GEN_SUBRNG7:
default:
signo = SIGTRAP;
code = TRAP_FIXME;
code = TRAP_UNK;
break;
}

info.si_signo = signo;
info.si_errno = 0;
info.si_code = code;
info.si_addr = (void __user *) regs->pc;
send_sig_info(signo, &info, current);
send_sig_fault(signo, code, (void __user *) regs->pc, regs->r16,
current);
return;

case 4: /* opDEC */
Expand All @@ -380,11 +360,9 @@ do_entIF(unsigned long type, struct pt_regs *regs)
if (si_code == 0)
return;
if (si_code > 0) {
info.si_signo = SIGFPE;
info.si_errno = 0;
info.si_code = si_code;
info.si_addr = (void __user *) regs->pc;
send_sig_info(SIGFPE, &info, current);
send_sig_fault(SIGFPE, si_code,
(void __user *) regs->pc, 0,
current);
return;
}
}
Expand All @@ -409,11 +387,7 @@ do_entIF(unsigned long type, struct pt_regs *regs)
;
}

info.si_signo = SIGILL;
info.si_errno = 0;
info.si_code = ILL_ILLOPC;
info.si_addr = (void __user *) regs->pc;
send_sig_info(SIGILL, &info, current);
send_sig_fault(SIGILL, ILL_ILLOPC, (void __user *)regs->pc, 0, current);
}

/* There is an ifdef in the PALcode in MILO that enables a
Expand All @@ -426,15 +400,9 @@ do_entIF(unsigned long type, struct pt_regs *regs)
asmlinkage void
do_entDbg(struct pt_regs *regs)
{
siginfo_t info;

die_if_kernel("Instruction fault", regs, 0, NULL);

info.si_signo = SIGILL;
info.si_errno = 0;
info.si_code = ILL_ILLOPC;
info.si_addr = (void __user *) regs->pc;
force_sig_info(SIGILL, &info, current);
force_sig_fault(SIGILL, ILL_ILLOPC, (void __user *)regs->pc, 0, current);
}


Expand Down Expand Up @@ -758,7 +726,7 @@ do_entUnaUser(void __user * va, unsigned long opcode,

unsigned long tmp1, tmp2, tmp3, tmp4;
unsigned long fake_reg, *reg_addr = &fake_reg;
siginfo_t info;
int si_code;
long error;

/* Check the UAC bits to decide what the user wants us to do
Expand Down Expand Up @@ -981,34 +949,27 @@ do_entUnaUser(void __user * va, unsigned long opcode,

give_sigsegv:
regs->pc -= 4; /* make pc point to faulting insn */
info.si_signo = SIGSEGV;
info.si_errno = 0;

/* We need to replicate some of the logic in mm/fault.c,
since we don't have access to the fault code in the
exception handling return path. */
if ((unsigned long)va >= TASK_SIZE)
info.si_code = SEGV_ACCERR;
si_code = SEGV_ACCERR;
else {
struct mm_struct *mm = current->mm;
down_read(&mm->mmap_sem);
if (find_vma(mm, (unsigned long)va))
info.si_code = SEGV_ACCERR;
si_code = SEGV_ACCERR;
else
info.si_code = SEGV_MAPERR;
si_code = SEGV_MAPERR;
up_read(&mm->mmap_sem);
}
info.si_addr = va;
send_sig_info(SIGSEGV, &info, current);
send_sig_fault(SIGSEGV, si_code, va, 0, current);
return;

give_sigbus:
regs->pc -= 4;
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = BUS_ADRALN;
info.si_addr = va;
send_sig_info(SIGBUS, &info, current);
send_sig_fault(SIGBUS, BUS_ADRALN, va, 0, current);
return;
}

Expand Down
13 changes: 2 additions & 11 deletions arch/alpha/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
struct mm_struct *mm = current->mm;
const struct exception_table_entry *fixup;
int fault, si_code = SEGV_MAPERR;
siginfo_t info;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;

/* As of EV6, a load into $31/$f31 is a prefetch, and never faults
Expand Down Expand Up @@ -221,21 +220,13 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
up_read(&mm->mmap_sem);
/* Send a sigbus, regardless of whether we were in kernel
or user mode. */
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = BUS_ADRERR;
info.si_addr = (void __user *) address;
force_sig_info(SIGBUS, &info, current);
force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *) address, 0, current);
if (!user_mode(regs))
goto no_context;
return;

do_sigsegv:
info.si_signo = SIGSEGV;
info.si_errno = 0;
info.si_code = si_code;
info.si_addr = (void __user *) address;
force_sig_info(SIGSEGV, &info, current);
force_sig_fault(SIGSEGV, si_code, (void __user *) address, 0, current);
return;

#ifdef CONFIG_ALPHA_LARGE_VMALLOC
Expand Down
2 changes: 2 additions & 0 deletions arch/arc/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ void do_page_fault(unsigned long address, struct pt_regs *regs)
int write = regs->ecr_cause & ECR_C_PROTV_STORE; /* ST/EX */
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;

clear_siginfo(&info);

/*
* We fault-in kernel-space virtual memory on-demand. The
* 'reference' page table is init_mm.pgd.
Expand Down
1 change: 1 addition & 0 deletions arch/arm/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ void ptrace_break(struct task_struct *tsk, struct pt_regs *regs)
{
siginfo_t info;

clear_siginfo(&info);
info.si_signo = SIGTRAP;
info.si_errno = 0;
info.si_code = TRAP_BRKPT;
Expand Down
1 change: 1 addition & 0 deletions arch/arm/kernel/swp_emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ static void set_segfault(struct pt_regs *regs, unsigned long addr)
{
siginfo_t info;

clear_siginfo(&info);
down_read(&current->mm->mmap_sem);
if (find_vma(current->mm, addr) == NULL)
info.si_code = SEGV_MAPERR;
Expand Down
5 changes: 5 additions & 0 deletions arch/arm/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ asmlinkage void do_undefinstr(struct pt_regs *regs)
siginfo_t info;
void __user *pc;

clear_siginfo(&info);
pc = (void __user *)instruction_pointer(regs);

if (processor_mode(regs) == SVC_MODE) {
Expand Down Expand Up @@ -540,6 +541,7 @@ static int bad_syscall(int n, struct pt_regs *regs)
{
siginfo_t info;

clear_siginfo(&info);
if ((current->personality & PER_MASK) != PER_LINUX) {
send_sig(SIGSEGV, current, 1);
return regs->ARM_r0;
Expand Down Expand Up @@ -607,6 +609,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
{
siginfo_t info;

clear_siginfo(&info);
if ((no >> 16) != (__ARM_NR_BASE>> 16))
return bad_syscall(no, regs);

Expand Down Expand Up @@ -743,6 +746,8 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs)
unsigned long addr = instruction_pointer(regs);
siginfo_t info;

clear_siginfo(&info);

#ifdef CONFIG_DEBUG_USER
if (user_debug & UDBG_BADABORT) {
pr_err("[%d] %s: bad data abort: code %d instr 0x%08lx\n",
Expand Down
1 change: 1 addition & 0 deletions arch/arm/mm/alignment.c
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
if (ai_usermode & UM_SIGNAL) {
siginfo_t si;

clear_siginfo(&si);
si.si_signo = SIGBUS;
si.si_errno = 0;
si.si_code = BUS_ADRALN;
Expand Down
4 changes: 4 additions & 0 deletions arch/arm/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr,
{
struct siginfo si;

clear_siginfo(&si);

#ifdef CONFIG_DEBUG_USER
if (((user_debug & UDBG_SEGV) && (sig == SIGSEGV)) ||
((user_debug & UDBG_BUS) && (sig == SIGBUS))) {
Expand Down Expand Up @@ -557,6 +559,7 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
inf->name, fsr, addr);
show_pte(current->mm, addr);

clear_siginfo(&info);
info.si_signo = inf->sig;
info.si_errno = 0;
info.si_code = inf->code;
Expand Down Expand Up @@ -589,6 +592,7 @@ do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
pr_alert("Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n",
inf->name, ifsr, addr);

clear_siginfo(&info);
info.si_signo = inf->sig;
info.si_errno = 0;
info.si_code = inf->code;
Expand Down
3 changes: 1 addition & 2 deletions arch/arm/vfp/vfpmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,7 @@ static void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs)
{
siginfo_t info;

memset(&info, 0, sizeof(info));

clear_siginfo(&info);
info.si_signo = SIGFPE;
info.si_code = sicode;
info.si_addr = (void __user *)(instruction_pointer(regs) - 4);
Expand Down
Loading

0 comments on commit 93e95fa

Please sign in to comment.