signal: Don't use structure initializers for struct siginfo

The siginfo structure has all manners of holes with the result that a
structure initializer is not guaranteed to initialize all of the bits.
As we have to copy the structure to userspace don't even try to use
a structure initializer.  Instead use clear_siginfo followed by initializing
selected fields.  This gives a guarantee that uninitialized kernel memory
is not copied to userspace.

Signed-off-by: "Eric W. Biederman" <[email protected]>
This commit is contained in:
Eric W. Biederman 2018-01-22 14:58:57 -06:00
commit 5f74972ce6
9 changed files with 89 additions and 60 deletions

View file

@ -699,11 +699,12 @@ static int simulate_sync(struct pt_regs *regs, unsigned int opcode)
asmlinkage void do_ov(struct pt_regs *regs)
{
enum ctx_state prev_state;
siginfo_t info = {
.si_signo = SIGFPE,
.si_code = FPE_INTOVF,
.si_addr = (void __user *)regs->cp0_epc,
};
siginfo_t info;
clear_siginfo(&info);
info.si_signo = SIGFPE;
info.si_code = FPE_INTOVF;
info.si_addr = (void __user *)regs->cp0_epc;
prev_state = exception_enter();
die_if_kernel("Integer overflow", regs);
@ -721,7 +722,11 @@ asmlinkage void do_ov(struct pt_regs *regs)
void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr,
struct task_struct *tsk)
{
struct siginfo si = { .si_addr = fault_addr, .si_signo = SIGFPE };
struct siginfo si;
clear_siginfo(&si);
si.si_addr = fault_addr;
si.si_signo = SIGFPE;
if (fcr31 & FPU_CSR_INV_X)
si.si_code = FPE_FLTINV;
@ -739,9 +744,10 @@ void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr,
int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcr31)
{
struct siginfo si = { 0 };
struct siginfo si;
struct vm_area_struct *vma;
clear_siginfo(&si);
switch (sig) {
case 0:
return 0;
@ -890,9 +896,10 @@ out:
void do_trap_or_bp(struct pt_regs *regs, unsigned int code, int si_code,
const char *str)
{
siginfo_t info = { 0 };
siginfo_t info;
char b[40];
clear_siginfo(&info);
#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
if (kgdb_ll_trap(DIE_TRAP, str, regs, code, current->thread.trap_nr,
SIGTRAP) == NOTIFY_STOP)
@ -1499,9 +1506,13 @@ asmlinkage void do_mdmx(struct pt_regs *regs)
*/
asmlinkage void do_watch(struct pt_regs *regs)
{
siginfo_t info = { .si_signo = SIGTRAP, .si_code = TRAP_HWBKPT };
siginfo_t info;
enum ctx_state prev_state;
clear_siginfo(&info);
info.si_signo = SIGTRAP;
info.si_code = TRAP_HWBKPT;
prev_state = exception_enter();
/*
* Clear WP (bit 22) bit of cause register so we don't loop