Commit cf4674c4 authored by Eric W. Biederman's avatar Eric W. Biederman

signal/powerpc: Document conflicts with SI_USER and SIGFPE and SIGTRAP

Setting si_code to 0 results in a userspace seeing an si_code of 0.
This is the same si_code as SI_USER.  Posix and common sense requires
that SI_USER not be a signal specific si_code.  As such this use of 0
for the si_code is a pretty horribly broken ABI.

Further use of si_code == 0 guaranteed that copy_siginfo_to_user saw a
value of __SI_KILL and now sees a value of SIL_KILL with the result
that uid and pid fields are copied and which might copying the si_addr
field by accident but certainly not by design.  Making this a very
flakey implementation.

Utilizing FPE_FIXME and TRAP_FIXME, siginfo_layout() will now return
SIL_FAULT and the appropriate fields will be reliably copied.

Possible ABI fixes includee:
- Send the signal without siginfo
- Don't generate a signal
- Possibly assign and use an appropriate si_code
- Don't handle cases which can't happen
Cc: Paul Mackerras <paulus@samba.org>
Cc: Kumar Gala <kumar.gala@freescale.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc:  linuxppc-dev@lists.ozlabs.org
Ref: 9bad068c ("[PATCH] ppc32: support for e500 and 85xx")
Ref: 0ed70f61 ("PPC32: Provide proper siginfo information on various exceptions.")
History Tree: https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.gitSigned-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
parent b80328be
...@@ -18,4 +18,19 @@ ...@@ -18,4 +18,19 @@
#undef NSIGTRAP #undef NSIGTRAP
#define NSIGTRAP 4 #define NSIGTRAP 4
/*
* 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 /* _ASM_POWERPC_SIGINFO_H */ #endif /* _ASM_POWERPC_SIGINFO_H */
...@@ -917,7 +917,7 @@ void unknown_exception(struct pt_regs *regs) ...@@ -917,7 +917,7 @@ void unknown_exception(struct pt_regs *regs)
printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
regs->nip, regs->msr, regs->trap); regs->nip, regs->msr, regs->trap);
_exception(SIGTRAP, regs, 0, 0); _exception(SIGTRAP, regs, TRAP_FIXME, 0);
exception_exit(prev_state); exception_exit(prev_state);
} }
...@@ -939,7 +939,7 @@ void instruction_breakpoint_exception(struct pt_regs *regs) ...@@ -939,7 +939,7 @@ void instruction_breakpoint_exception(struct pt_regs *regs)
void RunModeException(struct pt_regs *regs) void RunModeException(struct pt_regs *regs)
{ {
_exception(SIGTRAP, regs, 0, 0); _exception(SIGTRAP, regs, TRAP_FIXME, 0);
} }
void single_step_exception(struct pt_regs *regs) void single_step_exception(struct pt_regs *regs)
...@@ -978,7 +978,7 @@ static void emulate_single_step(struct pt_regs *regs) ...@@ -978,7 +978,7 @@ static void emulate_single_step(struct pt_regs *regs)
static inline int __parse_fpscr(unsigned long fpscr) static inline int __parse_fpscr(unsigned long fpscr)
{ {
int ret = 0; int ret = FPE_FIXME;
/* Invalid operation */ /* Invalid operation */
if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX)) if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX))
...@@ -1929,7 +1929,7 @@ void SPEFloatingPointException(struct pt_regs *regs) ...@@ -1929,7 +1929,7 @@ void SPEFloatingPointException(struct pt_regs *regs)
extern int do_spe_mathemu(struct pt_regs *regs); extern int do_spe_mathemu(struct pt_regs *regs);
unsigned long spefscr; unsigned long spefscr;
int fpexc_mode; int fpexc_mode;
int code = 0; int code = FPE_FIXME;
int err; int err;
flush_spe_to_thread(current); flush_spe_to_thread(current);
...@@ -1998,7 +1998,7 @@ void SPEFloatingPointRoundException(struct pt_regs *regs) ...@@ -1998,7 +1998,7 @@ void SPEFloatingPointRoundException(struct pt_regs *regs)
printk(KERN_ERR "unrecognized spe instruction " printk(KERN_ERR "unrecognized spe instruction "
"in %s at %lx\n", current->comm, regs->nip); "in %s at %lx\n", current->comm, regs->nip);
} else { } else {
_exception(SIGFPE, regs, 0, regs->nip); _exception(SIGFPE, regs, FPE_FIXME, regs->nip);
return; return;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment