linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [REVIEW][PATCH 00/17] siginfo bugfixes and cleanups
@ 2018-04-20  1:01 Eric W. Biederman
  2018-04-20  1:03 ` [REVIEW][PATCH 01/17] signal/alpha: Document a conflict with SI_USER for SIGFPE Eric W. Biederman
                   ` (17 more replies)
  0 siblings, 18 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20  1:01 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, linux-api, Helge Deller, Richard Henderson,
	Ivan Kokshaysky, Matt Turner, David Miller, Yoshinori Sato,
	Rich Felker, Paul Mundt, Vincent Chen, Greentime Hu,
	Arnd Bergmann, Tony Luck, Fenghua Yu, Paul Mackerras, Kumar Gala,
	Michael Ellerman, Benjamin Herrenschmidt, Guan Xuetao


Mostly this dealing with aliases of SI_USER, that make it impossible for
userspace to tell what kind of siginfo it has received.

Also in this series is the change to ensure we have siginfo initialized
so I can rip out the switch in copy_siginfo_to_user for better
performance, and to ensure better backwards compatibility as siginfo as
generated in the callers is passed to userspace.

There are also fixes for a few other siginfo bugs I have found.

There are cleanups of ifdefs on SEGV_BNDERR and BUS_MCERR_AX that are no
longer necessary.

I plan to merge these bug fixes through my siginfo tree, but if you
object to them or would prefer to have them go through your arch tree
please let me know.

The changes are avaiable as a totality at:
    git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace.git siginfo-review
    
Dmitry V. Levin (1):
      sparc: fix compat siginfo ABI regression

Eric W. Biederman (16):
      signal/alpha: Document a conflict with SI_USER for SIGFPE
      signal/sh: Use force_sig_fault in hw_breakpoint_handler
      signal/nds32: Use force_sig in unhandled_interruption and unhandled_exceptions
      signal/nds32: Use force_sig(SIGILL) in do_revisn
      signal: Ensure every siginfo we send has all bits initialized
      signal: Reduce copy_siginfo_to_user to just copy_to_user
      signal: Stop special casing TRAP_FIXME and FPE_FIXME in siginfo_layout
      signal: Remove SEGV_BNDERR ifdefs
      signal: Remove ifdefs for BUS_MCEERR_AR and BUS_MCEERR_AO
      signal/alpha: Replace FPE_FIXME with FPE_FLTUNK
      signal/ia64: Replace FPE_FIXME with FPE_FLTUNK
      signal/powerpc: Replace FPE_FIXME with FPE_FLTUNK
      signal/unicore32: Use FPE_FLTUNK instead of 0 in ucf64_raise_sigfpe
      signal: Add TRAP_UNK si_code for undiagnosted trap exceptions
      signal/alpha:  Replace TRAP_FIXME with TRAP_UNK
      signal/powerpc: Replace TRAP_FIXME with TRAP_UNK

 arch/alpha/include/uapi/asm/siginfo.h     |  14 ----
 arch/alpha/kernel/osf_sys.c               |   3 +-
 arch/alpha/kernel/signal.c                |   2 +
 arch/alpha/kernel/traps.c                 |  11 ++-
 arch/alpha/mm/fault.c                     |   2 +
 arch/arc/mm/fault.c                       |   2 +
 arch/arm/kernel/ptrace.c                  |   1 +
 arch/arm/kernel/swp_emulate.c             |   1 +
 arch/arm/kernel/traps.c                   |   5 ++
 arch/arm/mm/alignment.c                   |   1 +
 arch/arm/mm/fault.c                       |   4 +
 arch/arm/vfp/vfpmodule.c                  |   3 +-
 arch/arm64/kernel/fpsimd.c                |   2 +-
 arch/arm64/kernel/sys_compat.c            |   1 +
 arch/arm64/kernel/traps.c                 |   1 +
 arch/arm64/mm/fault.c                     |  18 +++--
 arch/c6x/kernel/traps.c                   |   1 +
 arch/hexagon/kernel/traps.c               |   1 +
 arch/hexagon/mm/vm_fault.c                |   1 +
 arch/ia64/include/uapi/asm/siginfo.h      |   7 --
 arch/ia64/kernel/brl_emu.c                |   1 +
 arch/ia64/kernel/signal.c                 |   2 +
 arch/ia64/kernel/traps.c                  |  31 ++++++--
 arch/ia64/kernel/unaligned.c              |   1 +
 arch/ia64/mm/fault.c                      |   4 +-
 arch/m68k/kernel/traps.c                  |   2 +
 arch/microblaze/kernel/exceptions.c       |   1 +
 arch/microblaze/mm/fault.c                |   4 +-
 arch/mips/mm/fault.c                      |   1 +
 arch/nds32/kernel/traps.c                 |  19 ++---
 arch/nds32/mm/fault.c                     |   1 +
 arch/nios2/kernel/traps.c                 |   1 +
 arch/openrisc/kernel/traps.c              |   5 +-
 arch/openrisc/mm/fault.c                  |   1 +
 arch/parisc/kernel/ptrace.c               |   1 +
 arch/parisc/kernel/traps.c                |   2 +
 arch/parisc/kernel/unaligned.c            |   1 +
 arch/parisc/math-emu/driver.c             |   1 +
 arch/parisc/mm/fault.c                    |   1 +
 arch/powerpc/include/uapi/asm/siginfo.h   |  15 ----
 arch/powerpc/kernel/process.c             |   1 +
 arch/powerpc/kernel/traps.c               |  13 ++--
 arch/powerpc/mm/fault.c                   |   1 +
 arch/powerpc/platforms/cell/spufs/fault.c |   2 +-
 arch/riscv/kernel/traps.c                 |   1 +
 arch/s390/kernel/traps.c                  |   5 +-
 arch/s390/mm/fault.c                      |   2 +
 arch/sh/kernel/hw_breakpoint.c            |   9 +--
 arch/sh/kernel/traps_32.c                 |   2 +
 arch/sh/math-emu/math.c                   |   1 +
 arch/sh/mm/fault.c                        |   1 +
 arch/sparc/include/uapi/asm/siginfo.h     |   7 --
 arch/sparc/kernel/process_64.c            |   1 +
 arch/sparc/kernel/sys_sparc_32.c          |   1 +
 arch/sparc/kernel/traps_32.c              |  12 ++-
 arch/sparc/kernel/traps_64.c              |  16 +++-
 arch/sparc/kernel/unaligned_32.c          |   1 +
 arch/sparc/mm/fault_32.c                  |   1 +
 arch/sparc/mm/fault_64.c                  |   1 +
 arch/um/kernel/trap.c                     |   2 +
 arch/unicore32/kernel/fpu-ucf64.c         |   8 +-
 arch/unicore32/mm/fault.c                 |   3 +
 arch/x86/entry/vsyscall/vsyscall_64.c     |   2 +-
 arch/x86/kernel/ptrace.c                  |   2 +-
 arch/x86/kernel/signal_compat.c           |   2 +-
 arch/x86/kernel/traps.c                   |   3 +
 arch/x86/kernel/umip.c                    |   1 +
 arch/x86/kvm/mmu.c                        |   1 +
 arch/x86/mm/fault.c                       |   1 +
 arch/xtensa/kernel/traps.c                |   1 +
 arch/xtensa/mm/fault.c                    |   1 +
 fs/signalfd.c                             |  15 +---
 include/linux/ptrace.h                    |   1 -
 include/linux/tracehook.h                 |   1 +
 include/uapi/asm-generic/siginfo.h        |   3 +-
 kernel/signal.c                           | 123 +++---------------------------
 virt/kvm/arm/mmu.c                        |   1 +
 77 files changed, 194 insertions(+), 231 deletions(-)


^ permalink raw reply	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 01/17] signal/alpha: Document a conflict with SI_USER for SIGFPE
  2018-04-20  1:01 [REVIEW][PATCH 00/17] siginfo bugfixes and cleanups Eric W. Biederman
@ 2018-04-20  1:03 ` Eric W. Biederman
  2018-04-20  1:03 ` [REVIEW][PATCH 02/17] sparc: fix compat siginfo ABI regression Eric W. Biederman
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20  1:03 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, linux-api, Eric W. Biederman, Helge Deller,
	Richard Henderson, Ivan Kokshaysky, Matt Turner, linux-alpha

Setting si_code to 0 is the same as setting si_code to SI_USER.  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.

Cc: Helge Deller <deller@gmx.de>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Matt Turner <mattst88@gmail.com>
Cc: linux-alpha@vger.kernel.org
History Tree: https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git
Ref: 0a635c7a84cf ("Fill in siginfo_t.")
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/alpha/kernel/osf_sys.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 89faa6f4de47..2e02aef5a334 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -872,7 +872,7 @@ SYSCALL_DEFINE5(osf_setsysinfo, unsigned long, op, void __user *, buffer,
 		fex = (exc >> IEEE_STATUS_TO_EXCSUM_SHIFT) & swcr;
  		if (fex) {
 			siginfo_t info;
-			int si_code = 0;
+			int si_code = FPE_FIXME;
 
 			if (fex & IEEE_TRAP_ENABLE_DNO) si_code = FPE_FLTUND;
 			if (fex & IEEE_TRAP_ENABLE_INE) si_code = FPE_FLTRES;
-- 
2.14.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 02/17] sparc: fix compat siginfo ABI regression
  2018-04-20  1:01 [REVIEW][PATCH 00/17] siginfo bugfixes and cleanups Eric W. Biederman
  2018-04-20  1:03 ` [REVIEW][PATCH 01/17] signal/alpha: Document a conflict with SI_USER for SIGFPE Eric W. Biederman
@ 2018-04-20  1:03 ` Eric W. Biederman
  2018-04-20  1:03 ` [REVIEW][PATCH 03/17] signal/sh: Use force_sig_fault in hw_breakpoint_handler Eric W. Biederman
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20  1:03 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, linux-api, Dmitry V. Levin, David Miller,
	sparclinux, Eric W . Biederman

From: "Dmitry V. Levin" <ldv@altlinux.org>

Starting with commit v4.14-rc1~60^2^2~1, a SIGFPE signal sent via kill
results to wrong values in si_pid and si_uid fields of compat siginfo_t.

This happens due to FPE_FIXME being defined to 0 for sparc, and at the
same time siginfo_layout() introduced by the same commit returns
SIL_FAULT for SIGFPE if si_code == SI_USER and FPE_FIXME is defined to 0.

Fix this regression by removing FPE_FIXME macro and changing all its users
to assign FPE_FLTUNK to si_code instead of FPE_FIXME.

Note that FPE_FLTUNK is a new macro introduced by commit
266da65e9156d93e1126e185259a4aae68188d0e.

Tested with commit v4.16-11958-g16e205cf42da.

This bug was found by strace test suite.

In the discussion about FPE_FLTUNK on sparc David Miller said:
> Eric, feel free to do something similar on Sparc.

Link: https://github.com/strace/strace/issues/21
Fixes: cc731525f26a ("signal: Remove kernel interal si_code magic")
Fixes: 2.3.41
Cc: David Miller <davem@davemloft.net>
Cc: sparclinux@vger.kernel.org
Conceptually-Acked-By: David Miller <davem@davemloft.net>
Thanks-to: Anatoly Pugachev <matorola@gmail.com>
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 arch/sparc/include/uapi/asm/siginfo.h | 7 -------
 arch/sparc/kernel/traps_32.c          | 2 +-
 arch/sparc/kernel/traps_64.c          | 2 +-
 3 files changed, 2 insertions(+), 9 deletions(-)

diff --git a/arch/sparc/include/uapi/asm/siginfo.h b/arch/sparc/include/uapi/asm/siginfo.h
index 896ce447d16a..e7049550ac82 100644
--- a/arch/sparc/include/uapi/asm/siginfo.h
+++ b/arch/sparc/include/uapi/asm/siginfo.h
@@ -17,13 +17,6 @@
 
 #define SI_NOINFO	32767		/* no information in siginfo_t */
 
-/*
- * SIGFPE si_codes
- */
-#ifdef __KERNEL__
-#define FPE_FIXME	0	/* Broken dup of SI_USER */
-#endif /* __KERNEL__ */
-
 /*
  * SIGEMT si_codes
  */
diff --git a/arch/sparc/kernel/traps_32.c b/arch/sparc/kernel/traps_32.c
index b1ed763e4787..33cd35bf3dc8 100644
--- a/arch/sparc/kernel/traps_32.c
+++ b/arch/sparc/kernel/traps_32.c
@@ -307,7 +307,7 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc,
 	info.si_errno = 0;
 	info.si_addr = (void __user *)pc;
 	info.si_trapno = 0;
-	info.si_code = FPE_FIXME;
+	info.si_code = FPE_FLTUNK;
 	if ((fsr & 0x1c000) == (1 << 14)) {
 		if (fsr & 0x10)
 			info.si_code = FPE_FLTINV;
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index 462a21abd105..e81072ac52c3 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -2372,7 +2372,7 @@ static void do_fpe_common(struct pt_regs *regs)
 		info.si_errno = 0;
 		info.si_addr = (void __user *)regs->tpc;
 		info.si_trapno = 0;
-		info.si_code = FPE_FIXME;
+		info.si_code = FPE_FLTUNK;
 		if ((fsr & 0x1c000) == (1 << 14)) {
 			if (fsr & 0x10)
 				info.si_code = FPE_FLTINV;
-- 
2.14.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 03/17] signal/sh: Use force_sig_fault in hw_breakpoint_handler
  2018-04-20  1:01 [REVIEW][PATCH 00/17] siginfo bugfixes and cleanups Eric W. Biederman
  2018-04-20  1:03 ` [REVIEW][PATCH 01/17] signal/alpha: Document a conflict with SI_USER for SIGFPE Eric W. Biederman
  2018-04-20  1:03 ` [REVIEW][PATCH 02/17] sparc: fix compat siginfo ABI regression Eric W. Biederman
@ 2018-04-20  1:03 ` Eric W. Biederman
  2018-04-20  1:03 ` [REVIEW][PATCH 04/17] signal/nds32: Use force_sig in unhandled_interruption and unhandled_exceptions Eric W. Biederman
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20  1:03 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, linux-api, Eric W. Biederman, Yoshinori Sato,
	Rich Felker, Paul Mundt, linux-sh

The call chain is:
breakpoint
  notify_die
    hw_breakpoint_exceptions_notify
      hw_breakpoint_handler

So the signal number can only be SIGTRAP.

In hw_breakpoint_handler rc is either NOTIFY_STOP or NOTIF_DONE
both of which notifier_to_errno converts to 0.  So si_errno is 0.

Historically si_addr was left unitialized in struct siginfo which is a
bug.  There appears to be no consensus among the various architectures
which value should be in si_addr.  So since no usable value has
been returned up to this point return NULL in si_addr.

Fixes: 4352fc1b12fa ("sh: Abstracted SH-4A UBC support on hw-breakpoint core.")
Fixes: 34d0b5af50a0 ("sh: Convert ptrace to hw_breakpoint API.")
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: Rich Felker <dalias@libc.org>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: linux-sh@vger.kernel.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/sh/kernel/hw_breakpoint.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/arch/sh/kernel/hw_breakpoint.c b/arch/sh/kernel/hw_breakpoint.c
index afe965712a69..8648ed05ccf0 100644
--- a/arch/sh/kernel/hw_breakpoint.c
+++ b/arch/sh/kernel/hw_breakpoint.c
@@ -347,13 +347,8 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args)
 
 		/* Deliver the signal to userspace */
 		if (!arch_check_bp_in_kernelspace(bp)) {
-			siginfo_t info;
-
-			info.si_signo = args->signr;
-			info.si_errno = notifier_to_errno(rc);
-			info.si_code = TRAP_HWBKPT;
-
-			force_sig_info(args->signr, &info, current);
+			force_sig_fault(SIGTRAP, TRAP_HWBKPT,
+					(void __user *)NULL, current);
 		}
 
 		rcu_read_unlock();
-- 
2.14.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 04/17] signal/nds32: Use force_sig in unhandled_interruption and unhandled_exceptions
  2018-04-20  1:01 [REVIEW][PATCH 00/17] siginfo bugfixes and cleanups Eric W. Biederman
                   ` (2 preceding siblings ...)
  2018-04-20  1:03 ` [REVIEW][PATCH 03/17] signal/sh: Use force_sig_fault in hw_breakpoint_handler Eric W. Biederman
@ 2018-04-20  1:03 ` Eric W. Biederman
  2018-04-25 12:14   ` Vincent Chen
  2018-04-20  1:03 ` [REVIEW][PATCH 05/17] signal/nds32: Use force_sig(SIGILL) in do_revisn Eric W. Biederman
                   ` (13 subsequent siblings)
  17 siblings, 1 reply; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20  1:03 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, linux-api, Eric W. Biederman, Vincent Chen,
	Greentime Hu, Arnd Bergmann

Neither unhandled_interrupt nor unhandled_exceptions fills in any of the
siginfo fields whend sending SIGKILL.  Further because it is SIGKILL
even if all of the fields were filled out appropriately it would be impossible
for the process to read any of the siginfo fields.  So simplfy things and
just use force_sig instead of force_sig_info.

Fixes: 2923f5ea7738 ("nds32: Exception handling")
Cc: Vincent Chen <vincentc@andestech.com>
Cc: Greentime Hu <greentime@andestech.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/nds32/kernel/traps.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/arch/nds32/kernel/traps.c b/arch/nds32/kernel/traps.c
index 6e34eb9824a4..65961bf91d64 100644
--- a/arch/nds32/kernel/traps.c
+++ b/arch/nds32/kernel/traps.c
@@ -318,29 +318,22 @@ void do_debug_trap(unsigned long entry, unsigned long addr,
 
 void unhandled_interruption(struct pt_regs *regs)
 {
-	siginfo_t si;
 	pr_emerg("unhandled_interruption\n");
 	show_regs(regs);
 	if (!user_mode(regs))
 		do_exit(SIGKILL);
-	si.si_signo = SIGKILL;
-	si.si_errno = 0;
-	force_sig_info(SIGKILL, &si, current);
+	force_sig(SIGKILL, current);
 }
 
 void unhandled_exceptions(unsigned long entry, unsigned long addr,
 			  unsigned long type, struct pt_regs *regs)
 {
-	siginfo_t si;
 	pr_emerg("Unhandled Exception: entry: %lx addr:%lx itype:%lx\n", entry,
 		 addr, type);
 	show_regs(regs);
 	if (!user_mode(regs))
 		do_exit(SIGKILL);
-	si.si_signo = SIGKILL;
-	si.si_errno = 0;
-	si.si_addr = (void *)addr;
-	force_sig_info(SIGKILL, &si, current);
+	force_sig(SIGKILL, current);
 }
 
 extern int do_page_fault(unsigned long entry, unsigned long addr,
-- 
2.14.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 05/17] signal/nds32: Use force_sig(SIGILL) in do_revisn
  2018-04-20  1:01 [REVIEW][PATCH 00/17] siginfo bugfixes and cleanups Eric W. Biederman
                   ` (3 preceding siblings ...)
  2018-04-20  1:03 ` [REVIEW][PATCH 04/17] signal/nds32: Use force_sig in unhandled_interruption and unhandled_exceptions Eric W. Biederman
@ 2018-04-20  1:03 ` Eric W. Biederman
  2018-04-25 12:10   ` Vincent Chen
  2018-04-20  1:03 ` [REVIEW][PATCH 06/17] signal: Ensure every siginfo we send has all bits initialized Eric W. Biederman
                   ` (12 subsequent siblings)
  17 siblings, 1 reply; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20  1:03 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, linux-api, Eric W. Biederman, Vincent Chen,
	Greentime Hu, Arnd Bergmann

As originally committed do_revisn would deliver a siginfo for SIGILL
with an si_code composed of random stack contents.  That makes no
sense and is not something userspace can depend on.  So simplify
the code and just use "force_sig(SIG_ILL, current)" instead.

Fixes: 2923f5ea7738 ("nds32: Exception handling")
Cc: Vincent Chen <vincentc@andestech.com>
Cc: Greentime Hu <greentime@andestech.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/nds32/kernel/traps.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/arch/nds32/kernel/traps.c b/arch/nds32/kernel/traps.c
index 65961bf91d64..8e9a5b1f6234 100644
--- a/arch/nds32/kernel/traps.c
+++ b/arch/nds32/kernel/traps.c
@@ -356,14 +356,11 @@ void do_dispatch_tlb_misc(unsigned long entry, unsigned long addr,
 
 void do_revinsn(struct pt_regs *regs)
 {
-	siginfo_t si;
 	pr_emerg("Reserved Instruction\n");
 	show_regs(regs);
 	if (!user_mode(regs))
 		do_exit(SIGILL);
-	si.si_signo = SIGILL;
-	si.si_errno = 0;
-	force_sig_info(SIGILL, &si, current);
+	force_sig(SIGILL, current);
 }
 
 #ifdef CONFIG_ALIGNMENT_TRAP
-- 
2.14.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 06/17] signal: Ensure every siginfo we send has all bits initialized
  2018-04-20  1:01 [REVIEW][PATCH 00/17] siginfo bugfixes and cleanups Eric W. Biederman
                   ` (4 preceding siblings ...)
  2018-04-20  1:03 ` [REVIEW][PATCH 05/17] signal/nds32: Use force_sig(SIGILL) in do_revisn Eric W. Biederman
@ 2018-04-20  1:03 ` Eric W. Biederman
  2018-04-20  1:03 ` [REVIEW][PATCH 07/17] signal: Reduce copy_siginfo_to_user to just copy_to_user Eric W. Biederman
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20  1:03 UTC (permalink / raw)
  To: linux-arch; +Cc: linux-kernel, linux-api, Eric W. Biederman

Call clear_siginfo to ensure every stack allocated siginfo is properly
initialized before being passed to the signal sending functions.

Note: It is not safe to depend on C initializers to initialize struct
siginfo on the stack because C is allowed to skip holes when
initializing a structure.

The initialization of struct siginfo in tracehook_report_syscall_exit
was moved from the helper user_single_step_siginfo into
tracehook_report_syscall_exit itself, to make it clear that the local
variable siginfo gets fully initialized.

In a few cases the scope of struct siginfo has been reduced to make it
clear that siginfo siginfo is not used on other paths in the function
in which it is declared.

Instances of using memset to initialize siginfo have been replaced
with calls clear_siginfo for clarity.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/alpha/kernel/osf_sys.c               |  1 +
 arch/alpha/kernel/signal.c                |  2 ++
 arch/alpha/kernel/traps.c                 |  5 +++++
 arch/alpha/mm/fault.c                     |  2 ++
 arch/arc/mm/fault.c                       |  2 ++
 arch/arm/kernel/ptrace.c                  |  1 +
 arch/arm/kernel/swp_emulate.c             |  1 +
 arch/arm/kernel/traps.c                   |  5 +++++
 arch/arm/mm/alignment.c                   |  1 +
 arch/arm/mm/fault.c                       |  4 ++++
 arch/arm/vfp/vfpmodule.c                  |  3 +--
 arch/arm64/kernel/fpsimd.c                |  2 +-
 arch/arm64/kernel/sys_compat.c            |  1 +
 arch/arm64/kernel/traps.c                 |  1 +
 arch/arm64/mm/fault.c                     | 18 ++++++++++++------
 arch/c6x/kernel/traps.c                   |  1 +
 arch/hexagon/kernel/traps.c               |  1 +
 arch/hexagon/mm/vm_fault.c                |  1 +
 arch/ia64/kernel/brl_emu.c                |  1 +
 arch/ia64/kernel/signal.c                 |  2 ++
 arch/ia64/kernel/traps.c                  | 27 ++++++++++++++++++++++++---
 arch/ia64/kernel/unaligned.c              |  1 +
 arch/ia64/mm/fault.c                      |  4 +++-
 arch/m68k/kernel/traps.c                  |  2 ++
 arch/microblaze/kernel/exceptions.c       |  1 +
 arch/microblaze/mm/fault.c                |  4 +++-
 arch/mips/mm/fault.c                      |  1 +
 arch/nds32/kernel/traps.c                 |  3 ++-
 arch/nds32/mm/fault.c                     |  1 +
 arch/nios2/kernel/traps.c                 |  1 +
 arch/openrisc/kernel/traps.c              |  5 ++++-
 arch/openrisc/mm/fault.c                  |  1 +
 arch/parisc/kernel/ptrace.c               |  1 +
 arch/parisc/kernel/traps.c                |  2 ++
 arch/parisc/kernel/unaligned.c            |  1 +
 arch/parisc/math-emu/driver.c             |  1 +
 arch/parisc/mm/fault.c                    |  1 +
 arch/powerpc/kernel/process.c             |  1 +
 arch/powerpc/kernel/traps.c               |  3 +--
 arch/powerpc/mm/fault.c                   |  1 +
 arch/powerpc/platforms/cell/spufs/fault.c |  2 +-
 arch/riscv/kernel/traps.c                 |  1 +
 arch/s390/kernel/traps.c                  |  5 ++++-
 arch/s390/mm/fault.c                      |  2 ++
 arch/sh/kernel/traps_32.c                 |  2 ++
 arch/sh/math-emu/math.c                   |  1 +
 arch/sh/mm/fault.c                        |  1 +
 arch/sparc/kernel/process_64.c            |  1 +
 arch/sparc/kernel/sys_sparc_32.c          |  1 +
 arch/sparc/kernel/traps_32.c              | 10 ++++++++++
 arch/sparc/kernel/traps_64.c              | 14 ++++++++++++++
 arch/sparc/kernel/unaligned_32.c          |  1 +
 arch/sparc/mm/fault_32.c                  |  1 +
 arch/sparc/mm/fault_64.c                  |  1 +
 arch/um/kernel/trap.c                     |  2 ++
 arch/unicore32/kernel/fpu-ucf64.c         |  2 +-
 arch/unicore32/mm/fault.c                 |  3 +++
 arch/x86/entry/vsyscall/vsyscall_64.c     |  2 +-
 arch/x86/kernel/ptrace.c                  |  2 +-
 arch/x86/kernel/traps.c                   |  3 +++
 arch/x86/kernel/umip.c                    |  1 +
 arch/x86/kvm/mmu.c                        |  1 +
 arch/x86/mm/fault.c                       |  1 +
 arch/xtensa/kernel/traps.c                |  1 +
 arch/xtensa/mm/fault.c                    |  1 +
 include/linux/ptrace.h                    |  1 -
 include/linux/tracehook.h                 |  1 +
 virt/kvm/arm/mmu.c                        |  1 +
 68 files changed, 158 insertions(+), 24 deletions(-)

diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 2e02aef5a334..f5f154942aab 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -881,6 +881,7 @@ 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;
 
+			clear_siginfo(&info);
 			info.si_signo = SIGFPE;
 			info.si_errno = 0;
 			info.si_code = si_code;
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
index 9ebb3bcbc626..cd306e602313 100644
--- a/arch/alpha/kernel/signal.c
+++ b/arch/alpha/kernel/signal.c
@@ -221,6 +221,7 @@ do_sigreturn(struct sigcontext __user *sc)
 	if (ptrace_cancel_bpt (current)) {
 		siginfo_t info;
 
+		clear_siginfo(&info);
 		info.si_signo = SIGTRAP;
 		info.si_errno = 0;
 		info.si_code = TRAP_BRKPT;
@@ -255,6 +256,7 @@ do_rt_sigreturn(struct rt_sigframe __user *frame)
 	if (ptrace_cancel_bpt (current)) {
 		siginfo_t info;
 
+		clear_siginfo(&info);
 		info.si_signo = SIGTRAP;
 		info.si_errno = 0;
 		info.si_code = TRAP_BRKPT;
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index f43bd05dede2..91636765dd6d 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -228,6 +228,7 @@ do_entArith(unsigned long summary, unsigned long write_mask,
 	}
 	die_if_kernel("Arithmetic fault", regs, 0, NULL);
 
+	clear_siginfo(&info);
 	info.si_signo = SIGFPE;
 	info.si_errno = 0;
 	info.si_code = si_code;
@@ -241,6 +242,7 @@ do_entIF(unsigned long type, struct pt_regs *regs)
 	siginfo_t info;
 	int signo, code;
 
+	clear_siginfo(&info);
 	if ((regs->ps & ~IPL_MAX) == 0) {
 		if (type == 1) {
 			const unsigned int *data
@@ -430,6 +432,7 @@ do_entDbg(struct pt_regs *regs)
 
 	die_if_kernel("Instruction fault", regs, 0, NULL);
 
+	clear_siginfo(&info);
 	info.si_signo = SIGILL;
 	info.si_errno = 0;
 	info.si_code = ILL_ILLOPC;
@@ -761,6 +764,8 @@ do_entUnaUser(void __user * va, unsigned long opcode,
 	siginfo_t info;
 	long error;
 
+	clear_siginfo(&info);
+
 	/* Check the UAC bits to decide what the user wants us to do
 	   with the unaliged access.  */
 
diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
index cd3c572ee912..7f2202a9f50a 100644
--- a/arch/alpha/mm/fault.c
+++ b/arch/alpha/mm/fault.c
@@ -91,6 +91,8 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
 	siginfo_t info;
 	unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
 
+	clear_siginfo(&info);
+
 	/* As of EV6, a load into $31/$f31 is a prefetch, and never faults
 	   (or is suppressed by the PALcode).  Support that for older CPUs
 	   by ignoring such an instruction.  */
diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c
index a0b7bd6d030d..b884bbd6f354 100644
--- a/arch/arc/mm/fault.c
+++ b/arch/arc/mm/fault.c
@@ -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.
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 7724b0f661b3..36718a424358 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -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;
diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c
index 3bda08bee674..dfcb456afadd 100644
--- a/arch/arm/kernel/swp_emulate.c
+++ b/arch/arm/kernel/swp_emulate.c
@@ -112,6 +112,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;
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 5e3633c24e63..2584f9066da3 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -439,6 +439,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) {
@@ -537,6 +538,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;
@@ -604,6 +606,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);
 
@@ -740,6 +743,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",
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index 2c96190e018b..bd2c739d8083 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -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;
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index b75eada23d0a..32034543f49c 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -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))) {
@@ -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;
@@ -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;
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 4c375e11ae95..adda3fc2dde8 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -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);
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 87a35364e750..4bcdd0318729 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -882,7 +882,7 @@ asmlinkage void do_fpsimd_exc(unsigned int esr, struct pt_regs *regs)
 			si_code = FPE_FLTRES;
 	}
 
-	memset(&info, 0, sizeof(info));
+	clear_siginfo(&info);
 	info.si_signo = SIGFPE;
 	info.si_code = si_code;
 	info.si_addr = (void __user *)instruction_pointer(regs);
diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c
index 93ab57dcfc14..a6109825eeb9 100644
--- a/arch/arm64/kernel/sys_compat.c
+++ b/arch/arm64/kernel/sys_compat.c
@@ -112,6 +112,7 @@ long compat_arm_syscall(struct pt_regs *regs)
 		break;
 	}
 
+	clear_siginfo(&info);
 	info.si_signo = SIGILL;
 	info.si_errno = 0;
 	info.si_code  = ILL_ILLTRP;
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index ba964da31a25..7f476586cacc 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -634,6 +634,7 @@ asmlinkage void bad_el0_sync(struct pt_regs *regs, int reason, unsigned int esr)
 	siginfo_t info;
 	void __user *pc = (void __user *)instruction_pointer(regs);
 
+	clear_siginfo(&info);
 	info.si_signo = SIGILL;
 	info.si_errno = 0;
 	info.si_code  = ILL_ILLOPC;
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 4165485e8b6e..91c53a7d2575 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -305,11 +305,12 @@ static void do_bad_area(unsigned long addr, unsigned int esr, struct pt_regs *re
 	 */
 	if (user_mode(regs)) {
 		const struct fault_info *inf = esr_to_fault_info(esr);
-		struct siginfo si = {
-			.si_signo	= inf->sig,
-			.si_code	= inf->code,
-			.si_addr	= (void __user *)addr,
-		};
+		struct siginfo si;
+
+		clear_siginfo(&si);
+		si.si_signo	= inf->sig;
+		si.si_code	= inf->code;
+		si.si_addr	= (void __user *)addr;
 
 		__do_user_fault(&si, esr);
 	} else {
@@ -583,6 +584,7 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
 			nmi_exit();
 	}
 
+	clear_siginfo(&info);
 	info.si_signo = inf->sig;
 	info.si_errno = 0;
 	info.si_code  = inf->code;
@@ -687,6 +689,7 @@ asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,
 		show_pte(addr);
 	}
 
+	clear_siginfo(&info);
 	info.si_signo = inf->sig;
 	info.si_errno = 0;
 	info.si_code  = inf->code;
@@ -729,6 +732,7 @@ asmlinkage void __exception do_sp_pc_abort(unsigned long addr,
 		local_irq_enable();
 	}
 
+	clear_siginfo(&info);
 	info.si_signo = SIGBUS;
 	info.si_errno = 0;
 	info.si_code  = BUS_ADRALN;
@@ -772,7 +776,6 @@ asmlinkage int __exception do_debug_exception(unsigned long addr,
 					      struct pt_regs *regs)
 {
 	const struct fault_info *inf = debug_fault_info + DBG_ESR_EVT(esr);
-	struct siginfo info;
 	int rv;
 
 	/*
@@ -788,6 +791,9 @@ asmlinkage int __exception do_debug_exception(unsigned long addr,
 	if (!inf->fn(addr, esr, regs)) {
 		rv = 1;
 	} else {
+		struct siginfo info;
+
+		clear_siginfo(&info);
 		info.si_signo = inf->sig;
 		info.si_errno = 0;
 		info.si_code  = inf->code;
diff --git a/arch/c6x/kernel/traps.c b/arch/c6x/kernel/traps.c
index 4c1d4b84dd2b..c5feee4542b0 100644
--- a/arch/c6x/kernel/traps.c
+++ b/arch/c6x/kernel/traps.c
@@ -246,6 +246,7 @@ static void do_trap(struct exception_info *except_info, struct pt_regs *regs)
 	unsigned long addr = instruction_pointer(regs);
 	siginfo_t info;
 
+	clear_siginfo(&info);
 	if (except_info->code != TRAP_BRKPT)
 		pr_err("TRAP: %s PC[0x%lx] signo[%d] code[%d]\n",
 		       except_info->kernel_str, regs->pc,
diff --git a/arch/hexagon/kernel/traps.c b/arch/hexagon/kernel/traps.c
index 2942a9204a9a..1ff6a6a7b97c 100644
--- a/arch/hexagon/kernel/traps.c
+++ b/arch/hexagon/kernel/traps.c
@@ -414,6 +414,7 @@ void do_trap0(struct pt_regs *regs)
 		if (user_mode(regs)) {
 			struct siginfo info;
 
+			clear_siginfo(&info);
 			info.si_signo = SIGTRAP;
 			info.si_errno = 0;
 			/*
diff --git a/arch/hexagon/mm/vm_fault.c b/arch/hexagon/mm/vm_fault.c
index 3eec33c5cfd7..2ad92edc877c 100644
--- a/arch/hexagon/mm/vm_fault.c
+++ b/arch/hexagon/mm/vm_fault.c
@@ -56,6 +56,7 @@ void do_page_fault(unsigned long address, long cause, struct pt_regs *regs)
 	const struct exception_table_entry *fixup;
 	unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
 
+	clear_siginfo(&info);
 	/*
 	 * If we're in an interrupt or have no user context,
 	 * then must not take the fault.
diff --git a/arch/ia64/kernel/brl_emu.c b/arch/ia64/kernel/brl_emu.c
index 9bcc908bc85e..a61f6c6a36f8 100644
--- a/arch/ia64/kernel/brl_emu.c
+++ b/arch/ia64/kernel/brl_emu.c
@@ -62,6 +62,7 @@ ia64_emulate_brl (struct pt_regs *regs, unsigned long ar_ec)
 	struct illegal_op_return rv;
 	long tmp_taken, unimplemented_address;
 
+	clear_siginfo(&siginfo);
 	rv.fkt = (unsigned long) -1;
 
 	/*
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 54547c7cf8a2..d1234a5ba4c5 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -153,6 +153,7 @@ ia64_rt_sigreturn (struct sigscratch *scr)
 	return retval;
 
   give_sigsegv:
+	clear_siginfo(&si);
 	si.si_signo = SIGSEGV;
 	si.si_errno = 0;
 	si.si_code = SI_KERNEL;
@@ -236,6 +237,7 @@ force_sigsegv_info (int sig, void __user *addr)
 	unsigned long flags;
 	struct siginfo si;
 
+	clear_siginfo(&si);
 	if (sig == SIGSEGV) {
 		/*
 		 * Acquiring siglock around the sa_handler-update is almost
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index 6d4e76a4267f..972873ed1ae5 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -104,6 +104,7 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
 	int sig, code;
 
 	/* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */
+	clear_siginfo(&siginfo);
 	siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
 	siginfo.si_imm = break_num;
 	siginfo.si_flags = 0;		/* clear __ISR_VALID */
@@ -293,7 +294,6 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr)
 {
 	long exception, bundle[2];
 	unsigned long fault_ip;
-	struct siginfo siginfo;
 
 	fault_ip = regs->cr_iip;
 	if (!fp_fault && (ia64_psr(regs)->ri == 0))
@@ -344,10 +344,13 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr)
 			printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n");
 			return -1;
 		} else {
+			struct siginfo siginfo;
+
 			/* is next instruction a trap? */
 			if (exception & 2) {
 				ia64_increment_ip(regs);
 			}
+			clear_siginfo(&siginfo);
 			siginfo.si_signo = SIGFPE;
 			siginfo.si_errno = 0;
 			siginfo.si_code = FPE_FIXME;	/* default code */
@@ -372,6 +375,9 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr)
 			return -1;
 		} else if (exception != 0) {
 			/* raise exception */
+			struct siginfo siginfo;
+
+			clear_siginfo(&siginfo);
 			siginfo.si_signo = SIGFPE;
 			siginfo.si_errno = 0;
 			siginfo.si_code = FPE_FIXME;	/* default code */
@@ -420,7 +426,7 @@ ia64_illegal_op_fault (unsigned long ec, long arg1, long arg2, long arg3,
 	if (die_if_kernel(buf, &regs, 0))
 		return rv;
 
-	memset(&si, 0, sizeof(si));
+	clear_siginfo(&si);
 	si.si_signo = SIGILL;
 	si.si_code = ILL_ILLOPC;
 	si.si_addr = (void __user *) (regs.cr_iip + ia64_psr(&regs)->ri);
@@ -434,7 +440,6 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
 	    long arg7, struct pt_regs regs)
 {
 	unsigned long code, error = isr, iip;
-	struct siginfo siginfo;
 	char buf[128];
 	int result, sig;
 	static const char *reason[] = {
@@ -485,6 +490,7 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
 
 	      case 26: /* NaT Consumption */
 		if (user_mode(&regs)) {
+			struct siginfo siginfo;
 			void __user *addr;
 
 			if (((isr >> 4) & 0xf) == 2) {
@@ -499,6 +505,7 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
 				addr = (void __user *) (regs.cr_iip
 							+ ia64_psr(&regs)->ri);
 			}
+			clear_siginfo(&siginfo);
 			siginfo.si_signo = sig;
 			siginfo.si_code = code;
 			siginfo.si_errno = 0;
@@ -515,6 +522,9 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
 
 	      case 31: /* Unsupported Data Reference */
 		if (user_mode(&regs)) {
+			struct siginfo siginfo;
+
+			clear_siginfo(&siginfo);
 			siginfo.si_signo = SIGILL;
 			siginfo.si_code = ILL_ILLOPN;
 			siginfo.si_errno = 0;
@@ -531,6 +541,10 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
 	      case 29: /* Debug */
 	      case 35: /* Taken Branch Trap */
 	      case 36: /* Single Step Trap */
+	      {
+		struct siginfo siginfo;
+
+		clear_siginfo(&siginfo);
 		if (fsys_mode(current, &regs)) {
 			extern char __kernel_syscall_via_break[];
 			/*
@@ -578,11 +592,15 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
 		siginfo.si_isr   = isr;
 		force_sig_info(SIGTRAP, &siginfo, current);
 		return;
+	      }
 
 	      case 32: /* fp fault */
 	      case 33: /* fp trap */
 		result = handle_fpu_swa((vector == 32) ? 1 : 0, &regs, isr);
 		if ((result < 0) || (current->thread.flags & IA64_THREAD_FPEMU_SIGFPE)) {
+			struct siginfo siginfo;
+
+			clear_siginfo(&siginfo);
 			siginfo.si_signo = SIGFPE;
 			siginfo.si_errno = 0;
 			siginfo.si_code = FPE_FLTINV;
@@ -616,6 +634,9 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
 		} else {
 			/* Unimplemented Instr. Address Trap */
 			if (user_mode(&regs)) {
+				struct siginfo siginfo;
+
+				clear_siginfo(&siginfo);
 				siginfo.si_signo = SIGILL;
 				siginfo.si_code = ILL_BADIADDR;
 				siginfo.si_errno = 0;
diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c
index 72e9b4242564..e309f9859acc 100644
--- a/arch/ia64/kernel/unaligned.c
+++ b/arch/ia64/kernel/unaligned.c
@@ -1537,6 +1537,7 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
 		/* NOT_REACHED */
 	}
   force_sigbus:
+	clear_siginfo(&si);
 	si.si_signo = SIGBUS;
 	si.si_errno = 0;
 	si.si_code = BUS_ADRALN;
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index dfdc152d6737..817fa120645f 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -85,7 +85,6 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
 	int signal = SIGSEGV, code = SEGV_MAPERR;
 	struct vm_area_struct *vma, *prev_vma;
 	struct mm_struct *mm = current->mm;
-	struct siginfo si;
 	unsigned long mask;
 	int fault;
 	unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
@@ -249,6 +248,9 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
 		return;
 	}
 	if (user_mode(regs)) {
+		struct siginfo si;
+
+		clear_siginfo(&si);
 		si.si_signo = signal;
 		si.si_errno = 0;
 		si.si_code = code;
diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c
index c1cc4e99aa94..0a00b476236d 100644
--- a/arch/m68k/kernel/traps.c
+++ b/arch/m68k/kernel/traps.c
@@ -1011,6 +1011,7 @@ asmlinkage void trap_c(struct frame *fp)
 	int vector = (fp->ptregs.vector >> 2) & 0xff;
 	siginfo_t info;
 
+	clear_siginfo(&info);
 	if (fp->ptregs.sr & PS_S) {
 		if (vector == VEC_TRACE) {
 			/* traced a trapping instruction on a 68020/30,
@@ -1163,6 +1164,7 @@ asmlinkage void fpemu_signal(int signal, int code, void *addr)
 {
 	siginfo_t info;
 
+	clear_siginfo(&info);
 	info.si_signo = signal;
 	info.si_errno = 0;
 	info.si_code = code;
diff --git a/arch/microblaze/kernel/exceptions.c b/arch/microblaze/kernel/exceptions.c
index e6f338d0496b..443ec1feacb4 100644
--- a/arch/microblaze/kernel/exceptions.c
+++ b/arch/microblaze/kernel/exceptions.c
@@ -65,6 +65,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
 	if (kernel_mode(regs))
 		die("Exception in kernel mode", regs, signr);
 
+	clear_siginfo(&info);
 	info.si_signo = signr;
 	info.si_errno = 0;
 	info.si_code = code;
diff --git a/arch/microblaze/mm/fault.c b/arch/microblaze/mm/fault.c
index f91b30f8aaa8..43d92167012a 100644
--- a/arch/microblaze/mm/fault.c
+++ b/arch/microblaze/mm/fault.c
@@ -88,7 +88,6 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
 {
 	struct vm_area_struct *vma;
 	struct mm_struct *mm = current->mm;
-	siginfo_t info;
 	int code = SEGV_MAPERR;
 	int is_write = error_code & ESR_S;
 	int fault;
@@ -295,6 +294,9 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
 do_sigbus:
 	up_read(&mm->mmap_sem);
 	if (user_mode(regs)) {
+		siginfo_t info;
+
+		clear_siginfo(&info);
 		info.si_signo = SIGBUS;
 		info.si_errno = 0;
 		info.si_code = BUS_ADRERR;
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index 4f8f5bf46977..75392becd933 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -63,6 +63,7 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
 		return;
 #endif
 
+	clear_siginfo(&info);
 	info.si_code = SEGV_MAPERR;
 
 	/*
diff --git a/arch/nds32/kernel/traps.c b/arch/nds32/kernel/traps.c
index 8e9a5b1f6234..46911768f4b5 100644
--- a/arch/nds32/kernel/traps.c
+++ b/arch/nds32/kernel/traps.c
@@ -229,6 +229,7 @@ int bad_syscall(int n, struct pt_regs *regs)
 		return regs->uregs[0];
 	}
 
+	clear_siginfo(&info);
 	info.si_signo = SIGILL;
 	info.si_errno = 0;
 	info.si_code = ILL_ILLTRP;
@@ -292,7 +293,7 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
 	tsk->thread.trap_no = ENTRY_DEBUG_RELATED;
 	tsk->thread.error_code = error_code;
 
-	memset(&info, 0, sizeof(info));
+	clear_siginfo(&info);
 	info.si_signo = SIGTRAP;
 	info.si_code = si_code;
 	info.si_addr = (void __user *)instruction_pointer(regs);
diff --git a/arch/nds32/mm/fault.c b/arch/nds32/mm/fault.c
index 3a246fb8098c..876ee01ff80a 100644
--- a/arch/nds32/mm/fault.c
+++ b/arch/nds32/mm/fault.c
@@ -77,6 +77,7 @@ void do_page_fault(unsigned long entry, unsigned long addr,
 	unsigned int mask = VM_READ | VM_WRITE | VM_EXEC;
 	unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
 
+	clear_siginfo(&info);
 	error_code = error_code & (ITYPE_mskINST | ITYPE_mskETYPE);
 	tsk = current;
 	mm = tsk->mm;
diff --git a/arch/nios2/kernel/traps.c b/arch/nios2/kernel/traps.c
index 8184e7d6b385..a69861d3e1a3 100644
--- a/arch/nios2/kernel/traps.c
+++ b/arch/nios2/kernel/traps.c
@@ -28,6 +28,7 @@ static void _send_sig(int signo, int code, unsigned long addr)
 {
 	siginfo_t info;
 
+	clear_siginfo(&info);
 	info.si_signo = signo;
 	info.si_errno = 0;
 	info.si_code = code;
diff --git a/arch/openrisc/kernel/traps.c b/arch/openrisc/kernel/traps.c
index 113c175fe469..1610b1d65a11 100644
--- a/arch/openrisc/kernel/traps.c
+++ b/arch/openrisc/kernel/traps.c
@@ -251,7 +251,7 @@ void __init trap_init(void)
 asmlinkage void do_trap(struct pt_regs *regs, unsigned long address)
 {
 	siginfo_t info;
-	memset(&info, 0, sizeof(info));
+	clear_siginfo(&info);
 	info.si_signo = SIGTRAP;
 	info.si_code = TRAP_TRACE;
 	info.si_addr = (void *)address;
@@ -266,6 +266,7 @@ asmlinkage void do_unaligned_access(struct pt_regs *regs, unsigned long address)
 
 	if (user_mode(regs)) {
 		/* Send a SIGBUS */
+		clear_siginfo(&info);
 		info.si_signo = SIGBUS;
 		info.si_errno = 0;
 		info.si_code = BUS_ADRALN;
@@ -285,6 +286,7 @@ asmlinkage void do_bus_fault(struct pt_regs *regs, unsigned long address)
 
 	if (user_mode(regs)) {
 		/* Send a SIGBUS */
+		clear_siginfo(&info);
 		info.si_signo = SIGBUS;
 		info.si_errno = 0;
 		info.si_code = BUS_ADRERR;
@@ -485,6 +487,7 @@ asmlinkage void do_illegal_instruction(struct pt_regs *regs,
 
 	if (user_mode(regs)) {
 		/* Send a SIGILL */
+		clear_siginfo(&info);
 		info.si_signo = SIGILL;
 		info.si_errno = 0;
 		info.si_code = ILL_ILLOPC;
diff --git a/arch/openrisc/mm/fault.c b/arch/openrisc/mm/fault.c
index d0021dfae20a..68be33e4ae17 100644
--- a/arch/openrisc/mm/fault.c
+++ b/arch/openrisc/mm/fault.c
@@ -56,6 +56,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long address,
 	int fault;
 	unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
 
+	clear_siginfo(&info);
 	tsk = current;
 
 	/*
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index 1a2be6e639b5..b1c12ceb1c88 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -90,6 +90,7 @@ void user_enable_single_step(struct task_struct *task)
 		ptrace_disable(task);
 		/* Don't wake up the task, but let the
 		   parent know something happened. */
+		clear_siginfo(&si);
 		si.si_code = TRAP_TRACE;
 		si.si_addr = (void __user *) (task_regs(task)->iaoq[0] & ~3);
 		si.si_signo = SIGTRAP;
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index 68e671a11987..98f9f2f85940 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -299,6 +299,7 @@ static void handle_gdb_break(struct pt_regs *regs, int wot)
 {
 	struct siginfo si;
 
+	clear_siginfo(&si);
 	si.si_signo = SIGTRAP;
 	si.si_errno = 0;
 	si.si_code = wot;
@@ -489,6 +490,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
 	unsigned long fault_space = 0;
 	struct siginfo si;
 
+	clear_siginfo(&si);
 	if (code == 1)
 	    pdc_console_restart();  /* switch back to pdc if HPMC */
 	else
diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c
index e36f7b75ab07..30b7c7f6c471 100644
--- a/arch/parisc/kernel/unaligned.c
+++ b/arch/parisc/kernel/unaligned.c
@@ -455,6 +455,7 @@ void handle_unaligned(struct pt_regs *regs)
 	struct siginfo si;
 	register int flop=0;	/* true if this is a flop */
 
+	clear_siginfo(&si);
 	__inc_irq_stat(irq_unaligned_count);
 
 	/* log a message with pacing */
diff --git a/arch/parisc/math-emu/driver.c b/arch/parisc/math-emu/driver.c
index 2fb59d2e2b29..0d10efb53361 100644
--- a/arch/parisc/math-emu/driver.c
+++ b/arch/parisc/math-emu/driver.c
@@ -93,6 +93,7 @@ handle_fpe(struct pt_regs *regs)
 	 */
 	__u64 frcopy[36];
 
+	clear_siginfo(&si);
 	memcpy(frcopy, regs->fr, sizeof regs->fr);
 	frcopy[32] = 0;
 
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
index e247edbca68e..657b35096bd8 100644
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c
@@ -356,6 +356,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
 		struct siginfo si;
 		unsigned int lsb = 0;
 
+		clear_siginfo(&si);
 		switch (code) {
 		case 15:	/* Data TLB miss fault/Data page fault */
 			/* send SIGSEGV when outside of vma */
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 1237f13fed51..26ea9793d290 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -632,6 +632,7 @@ void do_break (struct pt_regs *regs, unsigned long address,
 	hw_breakpoint_disable();
 
 	/* Deliver the signal to userspace */
+	clear_siginfo(&info);
 	info.si_signo = SIGTRAP;
 	info.si_errno = 0;
 	info.si_code = TRAP_HWBKPT;
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 0904492e7032..087855caf6a9 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -296,7 +296,6 @@ NOKPROBE_SYMBOL(die);
 void user_single_step_siginfo(struct task_struct *tsk,
 				struct pt_regs *regs, siginfo_t *info)
 {
-	memset(info, 0, sizeof(*info));
 	info->si_signo = SIGTRAP;
 	info->si_code = TRAP_TRACE;
 	info->si_addr = (void __user *)regs->nip;
@@ -334,7 +333,7 @@ void _exception_pkey(int signr, struct pt_regs *regs, int code,
 	 */
 	thread_pkey_regs_save(&current->thread);
 
-	memset(&info, 0, sizeof(info));
+	clear_siginfo(&info);
 	info.si_signo = signr;
 	info.si_code = code;
 	info.si_addr = (void __user *) addr;
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index c01d627e687a..ef268d5d9db7 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -168,6 +168,7 @@ static int do_sigbus(struct pt_regs *regs, unsigned long address,
 		return SIGBUS;
 
 	current->thread.trap_nr = BUS_ADRERR;
+	clear_siginfo(&info);
 	info.si_signo = SIGBUS;
 	info.si_errno = 0;
 	info.si_code = BUS_ADRERR;
diff --git a/arch/powerpc/platforms/cell/spufs/fault.c b/arch/powerpc/platforms/cell/spufs/fault.c
index 870c0a82d560..1e002e94d0f6 100644
--- a/arch/powerpc/platforms/cell/spufs/fault.c
+++ b/arch/powerpc/platforms/cell/spufs/fault.c
@@ -44,7 +44,7 @@ static void spufs_handle_event(struct spu_context *ctx,
 		return;
 	}
 
-	memset(&info, 0, sizeof(info));
+	clear_siginfo(&info);
 
 	switch (type) {
 	case SPE_EVENT_INVALID_DMA:
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 93132cb59184..48aa6471cede 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -68,6 +68,7 @@ static inline void do_trap_siginfo(int signo, int code,
 {
 	siginfo_t info;
 
+	clear_siginfo(&info);
 	info.si_signo = signo;
 	info.si_errno = 0;
 	info.si_code = code;
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index a5297a22bc1e..3ba649d8aa5a 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -47,6 +47,7 @@ void do_report_trap(struct pt_regs *regs, int si_signo, int si_code, char *str)
 	siginfo_t info;
 
 	if (user_mode(regs)) {
+		clear_siginfo(&info);
 		info.si_signo = si_signo;
 		info.si_errno = 0;
 		info.si_code = si_code;
@@ -86,6 +87,7 @@ void do_per_trap(struct pt_regs *regs)
 		return;
 	if (!current->ptrace)
 		return;
+	clear_siginfo(&info);
 	info.si_signo = SIGTRAP;
 	info.si_errno = 0;
 	info.si_code = TRAP_HWBKPT;
@@ -165,7 +167,6 @@ void translation_exception(struct pt_regs *regs)
 
 void illegal_op(struct pt_regs *regs)
 {
-	siginfo_t info;
         __u8 opcode[6];
 	__u16 __user *location;
 	int is_uprobe_insn = 0;
@@ -178,6 +179,8 @@ void illegal_op(struct pt_regs *regs)
 			return;
 		if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) {
 			if (current->ptrace) {
+				siginfo_t info;
+				clear_siginfo(&info);
 				info.si_signo = SIGTRAP;
 				info.si_errno = 0;
 				info.si_code = TRAP_BRKPT;
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 93faeca52284..b3ff0e8e5860 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -268,6 +268,7 @@ static noinline void do_sigsegv(struct pt_regs *regs, int si_code)
 	struct siginfo si;
 
 	report_user_fault(regs, SIGSEGV, 1);
+	clear_siginfo(&si);
 	si.si_signo = SIGSEGV;
 	si.si_errno = 0;
 	si.si_code = si_code;
@@ -323,6 +324,7 @@ static noinline void do_sigbus(struct pt_regs *regs)
 	 * Send a sigbus, regardless of whether we were in kernel
 	 * or user mode.
 	 */
+	clear_siginfo(&si);
 	si.si_signo = SIGBUS;
 	si.si_errno = 0;
 	si.si_code = BUS_ADRERR;
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index b3770bb26211..e85e59c3d6df 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -537,6 +537,7 @@ asmlinkage void do_address_error(struct pt_regs *regs,
 		       "access (PC %lx PR %lx)\n", current->comm, regs->pc,
 		       regs->pr);
 
+		clear_siginfo(&info);
 		info.si_signo = SIGBUS;
 		info.si_errno = 0;
 		info.si_code = si_code;
@@ -600,6 +601,7 @@ asmlinkage void do_divide_error(unsigned long r4)
 {
 	siginfo_t info;
 
+	clear_siginfo(&info);
 	switch (r4) {
 	case TRAP_DIVZERO_ERROR:
 		info.si_code = FPE_INTDIV;
diff --git a/arch/sh/math-emu/math.c b/arch/sh/math-emu/math.c
index c86f4360c6ce..d6d2213df078 100644
--- a/arch/sh/math-emu/math.c
+++ b/arch/sh/math-emu/math.c
@@ -560,6 +560,7 @@ static int ieee_fpe_handler(struct pt_regs *regs)
 				~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK);
 			task_thread_info(tsk)->status |= TS_USEDFPU;
 		} else {
+			clear_siginfo(&info);
 			info.si_signo = SIGFPE;
 			info.si_errno = 0;
 			info.si_code = FPE_FLTINV;
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index 6fd1bf7481c7..4c98b6f20e02 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -44,6 +44,7 @@ force_sig_info_fault(int si_signo, int si_code, unsigned long address,
 {
 	siginfo_t info;
 
+	clear_siginfo(&info);
 	info.si_signo	= si_signo;
 	info.si_errno	= 0;
 	info.si_code	= si_code;
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
index 454a8af28f13..2219e55206b4 100644
--- a/arch/sparc/kernel/process_64.c
+++ b/arch/sparc/kernel/process_64.c
@@ -520,6 +520,7 @@ static void stack_unaligned(unsigned long sp)
 {
 	siginfo_t info;
 
+	clear_siginfo(&info);
 	info.si_signo = SIGBUS;
 	info.si_errno = 0;
 	info.si_code = BUS_ADRALN;
diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c
index e8c3cb6b6d08..00f6353fe435 100644
--- a/arch/sparc/kernel/sys_sparc_32.c
+++ b/arch/sparc/kernel/sys_sparc_32.c
@@ -152,6 +152,7 @@ sparc_breakpoint (struct pt_regs *regs)
 #ifdef DEBUG_SPARC_BREAKPOINT
         printk ("TRAP: Entering kernel PC=%x, nPC=%x\n", regs->pc, regs->npc);
 #endif
+	clear_siginfo(&info);
 	info.si_signo = SIGTRAP;
 	info.si_errno = 0;
 	info.si_code = TRAP_BRKPT;
diff --git a/arch/sparc/kernel/traps_32.c b/arch/sparc/kernel/traps_32.c
index 33cd35bf3dc8..03e522274b8b 100644
--- a/arch/sparc/kernel/traps_32.c
+++ b/arch/sparc/kernel/traps_32.c
@@ -104,6 +104,7 @@ void do_hw_interrupt(struct pt_regs *regs, unsigned long type)
 	if(regs->psr & PSR_PS)
 		die_if_kernel("Kernel bad trap", regs);
 
+	clear_siginfo(&info);
 	info.si_signo = SIGILL;
 	info.si_errno = 0;
 	info.si_code = ILL_ILLTRP;
@@ -124,6 +125,7 @@ void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned lon
 	       regs->pc, *(unsigned long *)regs->pc);
 #endif
 
+	clear_siginfo(&info);
 	info.si_signo = SIGILL;
 	info.si_errno = 0;
 	info.si_code = ILL_ILLOPC;
@@ -139,6 +141,7 @@ void do_priv_instruction(struct pt_regs *regs, unsigned long pc, unsigned long n
 
 	if(psr & PSR_PS)
 		die_if_kernel("Penguin instruction from Penguin mode??!?!", regs);
+	clear_siginfo(&info);
 	info.si_signo = SIGILL;
 	info.si_errno = 0;
 	info.si_code = ILL_PRVOPC;
@@ -165,6 +168,7 @@ void do_memaccess_unaligned(struct pt_regs *regs, unsigned long pc, unsigned lon
 	instruction_dump ((unsigned long *) regs->pc);
 	printk ("do_MNA!\n");
 #endif
+	clear_siginfo(&info);
 	info.si_signo = SIGBUS;
 	info.si_errno = 0;
 	info.si_code = BUS_ADRALN;
@@ -303,6 +307,7 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc,
 	}
 
 	fsr = fpt->thread.fsr;
+	clear_siginfo(&info);
 	info.si_signo = SIGFPE;
 	info.si_errno = 0;
 	info.si_addr = (void __user *)pc;
@@ -336,6 +341,7 @@ void handle_tag_overflow(struct pt_regs *regs, unsigned long pc, unsigned long n
 
 	if(psr & PSR_PS)
 		die_if_kernel("Penguin overflow trap from kernel mode", regs);
+	clear_siginfo(&info);
 	info.si_signo = SIGEMT;
 	info.si_errno = 0;
 	info.si_code = EMT_TAGOVF;
@@ -365,6 +371,7 @@ void handle_reg_access(struct pt_regs *regs, unsigned long pc, unsigned long npc
 	printk("Register Access Exception at PC %08lx NPC %08lx PSR %08lx\n",
 	       pc, npc, psr);
 #endif
+	clear_siginfo(&info);
 	info.si_signo = SIGBUS;
 	info.si_errno = 0;
 	info.si_code = BUS_OBJERR;
@@ -378,6 +385,7 @@ void handle_cp_disabled(struct pt_regs *regs, unsigned long pc, unsigned long np
 {
 	siginfo_t info;
 
+	clear_siginfo(&info);
 	info.si_signo = SIGILL;
 	info.si_errno = 0;
 	info.si_code = ILL_COPROC;
@@ -395,6 +403,7 @@ void handle_cp_exception(struct pt_regs *regs, unsigned long pc, unsigned long n
 	printk("Co-Processor Exception at PC %08lx NPC %08lx PSR %08lx\n",
 	       pc, npc, psr);
 #endif
+	clear_siginfo(&info);
 	info.si_signo = SIGILL;
 	info.si_errno = 0;
 	info.si_code = ILL_COPROC;
@@ -408,6 +417,7 @@ void handle_hw_divzero(struct pt_regs *regs, unsigned long pc, unsigned long npc
 {
 	siginfo_t info;
 
+	clear_siginfo(&info);
 	info.si_signo = SIGFPE;
 	info.si_errno = 0;
 	info.si_code = FPE_INTDIV;
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index e81072ac52c3..b485b49b87a8 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -107,6 +107,7 @@ void bad_trap(struct pt_regs *regs, long lvl)
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
+	clear_siginfo(&info);
 	info.si_signo = SIGILL;
 	info.si_errno = 0;
 	info.si_code = ILL_ILLTRP;
@@ -206,6 +207,7 @@ void spitfire_insn_access_exception(struct pt_regs *regs, unsigned long sfsr, un
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
+	clear_siginfo(&info);
 	info.si_signo = SIGSEGV;
 	info.si_errno = 0;
 	info.si_code = SEGV_MAPERR;
@@ -247,6 +249,7 @@ void sun4v_insn_access_exception(struct pt_regs *regs, unsigned long addr, unsig
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
+	clear_siginfo(&info);
 	info.si_signo = SIGSEGV;
 	info.si_errno = 0;
 	info.si_code = SEGV_MAPERR;
@@ -338,6 +341,7 @@ void spitfire_data_access_exception(struct pt_regs *regs, unsigned long sfsr, un
 	if (is_no_fault_exception(regs))
 		return;
 
+	clear_siginfo(&info);
 	info.si_signo = SIGSEGV;
 	info.si_errno = 0;
 	info.si_code = SEGV_MAPERR;
@@ -595,6 +599,7 @@ static void spitfire_ue_log(unsigned long afsr, unsigned long afar, unsigned lon
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
+	clear_siginfo(&info);
 	info.si_signo = SIGBUS;
 	info.si_errno = 0;
 	info.si_code = BUS_OBJERR;
@@ -2211,6 +2216,7 @@ bool sun4v_nonresum_error_user_handled(struct pt_regs *regs,
 				addr += PAGE_SIZE;
 			}
 		}
+		clear_siginfo(&info);
 		info.si_signo = SIGKILL;
 		info.si_errno = 0;
 		info.si_trapno = 0;
@@ -2221,6 +2227,7 @@ bool sun4v_nonresum_error_user_handled(struct pt_regs *regs,
 	if (attrs & SUN4V_ERR_ATTRS_PIO) {
 		siginfo_t info;
 
+		clear_siginfo(&info);
 		info.si_signo = SIGBUS;
 		info.si_code = BUS_ADRERR;
 		info.si_addr = (void __user *)sun4v_get_vaddr(regs);
@@ -2368,6 +2375,7 @@ static void do_fpe_common(struct pt_regs *regs)
 			regs->tpc &= 0xffffffff;
 			regs->tnpc &= 0xffffffff;
 		}
+		clear_siginfo(&info);
 		info.si_signo = SIGFPE;
 		info.si_errno = 0;
 		info.si_addr = (void __user *)regs->tpc;
@@ -2440,6 +2448,7 @@ void do_tof(struct pt_regs *regs)
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
+	clear_siginfo(&info);
 	info.si_signo = SIGEMT;
 	info.si_errno = 0;
 	info.si_code = EMT_TAGOVF;
@@ -2465,6 +2474,7 @@ void do_div0(struct pt_regs *regs)
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
+	clear_siginfo(&info);
 	info.si_signo = SIGFPE;
 	info.si_errno = 0;
 	info.si_code = FPE_INTDIV;
@@ -2666,6 +2676,7 @@ void do_illegal_instruction(struct pt_regs *regs)
 			}
 		}
 	}
+	clear_siginfo(&info);
 	info.si_signo = SIGILL;
 	info.si_errno = 0;
 	info.si_code = ILL_ILLOPC;
@@ -2692,6 +2703,7 @@ void mem_address_unaligned(struct pt_regs *regs, unsigned long sfar, unsigned lo
 	if (is_no_fault_exception(regs))
 		return;
 
+	clear_siginfo(&info);
 	info.si_signo = SIGBUS;
 	info.si_errno = 0;
 	info.si_code = BUS_ADRALN;
@@ -2717,6 +2729,7 @@ void sun4v_do_mna(struct pt_regs *regs, unsigned long addr, unsigned long type_c
 	if (is_no_fault_exception(regs))
 		return;
 
+	clear_siginfo(&info);
 	info.si_signo = SIGBUS;
 	info.si_errno = 0;
 	info.si_code = BUS_ADRALN;
@@ -2785,6 +2798,7 @@ void do_privop(struct pt_regs *regs)
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
+	clear_siginfo(&info);
 	info.si_signo = SIGILL;
 	info.si_errno = 0;
 	info.si_code = ILL_PRVOPC;
diff --git a/arch/sparc/kernel/unaligned_32.c b/arch/sparc/kernel/unaligned_32.c
index 7642d7e4f0d9..0e4cf7217413 100644
--- a/arch/sparc/kernel/unaligned_32.c
+++ b/arch/sparc/kernel/unaligned_32.c
@@ -313,6 +313,7 @@ static void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
 {
 	siginfo_t info;
 
+	clear_siginfo(&info);
 	info.si_signo = SIGBUS;
 	info.si_errno = 0;
 	info.si_code = BUS_ADRALN;
diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c
index a8103a84b4ac..2deb586665b9 100644
--- a/arch/sparc/mm/fault_32.c
+++ b/arch/sparc/mm/fault_32.c
@@ -129,6 +129,7 @@ static void __do_fault_siginfo(int code, int sig, struct pt_regs *regs,
 {
 	siginfo_t info;
 
+	clear_siginfo(&info);
 	info.si_signo = sig;
 	info.si_code = code;
 	info.si_errno = 0;
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c
index 41363f46797b..46ccff95d10e 100644
--- a/arch/sparc/mm/fault_64.c
+++ b/arch/sparc/mm/fault_64.c
@@ -172,6 +172,7 @@ static void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
 	unsigned long addr;
 	siginfo_t info;
 
+	clear_siginfo(&info);
 	info.si_code = code;
 	info.si_signo = sig;
 	info.si_errno = 0;
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index b2b02df9896e..d4d38520c4c6 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -164,6 +164,7 @@ static void bad_segv(struct faultinfo fi, unsigned long ip)
 {
 	struct siginfo si;
 
+	clear_siginfo(&si);
 	si.si_signo = SIGSEGV;
 	si.si_code = SEGV_ACCERR;
 	si.si_addr = (void __user *) FAULT_ADDRESS(fi);
@@ -220,6 +221,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
 	int is_write = FAULT_WRITE(fi);
 	unsigned long address = FAULT_ADDRESS(fi);
 
+	clear_siginfo(&si);
 	if (!is_user && regs)
 		current->thread.segv_regs = container_of(regs, struct pt_regs, regs);
 
diff --git a/arch/unicore32/kernel/fpu-ucf64.c b/arch/unicore32/kernel/fpu-ucf64.c
index 12c8c9527b8e..d785955e1c29 100644
--- a/arch/unicore32/kernel/fpu-ucf64.c
+++ b/arch/unicore32/kernel/fpu-ucf64.c
@@ -56,7 +56,7 @@ void ucf64_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;
diff --git a/arch/unicore32/mm/fault.c b/arch/unicore32/mm/fault.c
index bbefcc46a45e..381473412937 100644
--- a/arch/unicore32/mm/fault.c
+++ b/arch/unicore32/mm/fault.c
@@ -125,6 +125,7 @@ static void __do_user_fault(struct task_struct *tsk, unsigned long addr,
 	tsk->thread.address = addr;
 	tsk->thread.error_code = fsr;
 	tsk->thread.trap_no = 14;
+	clear_siginfo(&si);
 	si.si_signo = sig;
 	si.si_errno = 0;
 	si.si_code = code;
@@ -472,6 +473,7 @@ asmlinkage void do_DataAbort(unsigned long addr, unsigned int fsr,
 	printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n",
 	       inf->name, fsr, addr);
 
+	clear_siginfo(&info);
 	info.si_signo = inf->sig;
 	info.si_errno = 0;
 	info.si_code = inf->code;
@@ -491,6 +493,7 @@ asmlinkage void do_PrefetchAbort(unsigned long addr,
 	printk(KERN_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;
diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c
index 70b7845434cb..7782cdbcd67d 100644
--- a/arch/x86/entry/vsyscall/vsyscall_64.c
+++ b/arch/x86/entry/vsyscall/vsyscall_64.c
@@ -107,7 +107,7 @@ static bool write_ok_or_segv(unsigned long ptr, size_t size)
 		thread->cr2		= ptr;
 		thread->trap_nr		= X86_TRAP_PF;
 
-		memset(&info, 0, sizeof(info));
+		clear_siginfo(&info);
 		info.si_signo		= SIGSEGV;
 		info.si_errno		= 0;
 		info.si_code		= SEGV_MAPERR;
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index ed5c4cdf0a34..e2ee403865eb 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -1377,7 +1377,6 @@ static void fill_sigtrap_info(struct task_struct *tsk,
 	tsk->thread.trap_nr = X86_TRAP_DB;
 	tsk->thread.error_code = error_code;
 
-	memset(info, 0, sizeof(*info));
 	info->si_signo = SIGTRAP;
 	info->si_code = si_code;
 	info->si_addr = user_mode(regs) ? (void __user *)regs->ip : NULL;
@@ -1395,6 +1394,7 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
 {
 	struct siginfo info;
 
+	clear_siginfo(&info);
 	fill_sigtrap_info(tsk, regs, error_code, si_code, &info);
 	/* Send us the fake SIGTRAP */
 	force_sig_info(SIGTRAP, &info, tsk);
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 03f3d7695dac..a535dd64de63 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -299,6 +299,7 @@ static void do_error_trap(struct pt_regs *regs, long error_code, char *str,
 	if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) !=
 			NOTIFY_STOP) {
 		cond_local_irq_enable(regs);
+		clear_siginfo(&info);
 		do_trap(trapnr, signr, str, regs, error_code,
 			fill_trap_info(regs, signr, trapnr, &info));
 	}
@@ -854,6 +855,7 @@ static void math_error(struct pt_regs *regs, int error_code, int trapnr)
 
 	task->thread.trap_nr	= trapnr;
 	task->thread.error_code = error_code;
+	clear_siginfo(&info);
 	info.si_signo		= SIGFPE;
 	info.si_errno		= 0;
 	info.si_addr		= (void __user *)uprobe_get_trap_addr(regs);
@@ -929,6 +931,7 @@ dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code)
 	RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
 	local_irq_enable();
 
+	clear_siginfo(&info);
 	info.si_signo = SIGILL;
 	info.si_errno = 0;
 	info.si_code = ILL_BADSTK;
diff --git a/arch/x86/kernel/umip.c b/arch/x86/kernel/umip.c
index f44ce0fb3583..ff20b35e98dd 100644
--- a/arch/x86/kernel/umip.c
+++ b/arch/x86/kernel/umip.c
@@ -278,6 +278,7 @@ static void force_sig_info_umip_fault(void __user *addr, struct pt_regs *regs)
 	tsk->thread.error_code	= X86_PF_USER | X86_PF_WRITE;
 	tsk->thread.trap_nr	= X86_TRAP_PF;
 
+	clear_siginfo(&info);
 	info.si_signo	= SIGSEGV;
 	info.si_errno	= 0;
 	info.si_code	= SEGV_MAPERR;
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 8494dbae41b9..d634f0332c0f 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -3007,6 +3007,7 @@ static void kvm_send_hwpoison_signal(unsigned long address, struct task_struct *
 {
 	siginfo_t info;
 
+	clear_siginfo(&info);
 	info.si_signo	= SIGBUS;
 	info.si_errno	= 0;
 	info.si_code	= BUS_MCEERR_AR;
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 73bd8c95ac71..2a5a2920203d 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -209,6 +209,7 @@ force_sig_info_fault(int si_signo, int si_code, unsigned long address,
 	unsigned lsb = 0;
 	siginfo_t info;
 
+	clear_siginfo(&info);
 	info.si_signo	= si_signo;
 	info.si_errno	= 0;
 	info.si_code	= si_code;
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index 32c5207f1226..51771929f341 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -334,6 +334,7 @@ do_unaligned_user (struct pt_regs *regs)
 			    "(pid = %d, pc = %#010lx)\n",
 			    regs->excvaddr, current->comm,
 			    task_pid_nr(current), regs->pc);
+	clear_siginfo(&info);
 	info.si_signo = SIGBUS;
 	info.si_errno = 0;
 	info.si_code = BUS_ADRALN;
diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c
index 8b9b6f44bb06..f9323a3e61ce 100644
--- a/arch/xtensa/mm/fault.c
+++ b/arch/xtensa/mm/fault.c
@@ -45,6 +45,7 @@ void do_page_fault(struct pt_regs *regs)
 	int fault;
 	unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
 
+	clear_siginfo(&info);
 	info.si_code = SEGV_MAPERR;
 
 	/* We fault-in kernel-space virtual memory on-demand. The
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index 919b2a0b0307..037bf0ef1ae9 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -345,7 +345,6 @@ extern void user_single_step_siginfo(struct task_struct *tsk,
 static inline void user_single_step_siginfo(struct task_struct *tsk,
 				struct pt_regs *regs, siginfo_t *info)
 {
-	memset(info, 0, sizeof(*info));
 	info->si_signo = SIGTRAP;
 }
 #endif
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
index 26c152122a42..4a8841963c2e 100644
--- a/include/linux/tracehook.h
+++ b/include/linux/tracehook.h
@@ -124,6 +124,7 @@ static inline void tracehook_report_syscall_exit(struct pt_regs *regs, int step)
 {
 	if (step) {
 		siginfo_t info;
+		clear_siginfo(&info);
 		user_single_step_siginfo(current, regs, &info);
 		force_sig_info(SIGTRAP, &info, current);
 		return;
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index 7f6a944db23d..8d90de213ce9 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -1401,6 +1401,7 @@ static void kvm_send_hwpoison_signal(unsigned long address,
 {
 	siginfo_t info;
 
+	clear_siginfo(&info);
 	info.si_signo   = SIGBUS;
 	info.si_errno   = 0;
 	info.si_code    = BUS_MCEERR_AR;
-- 
2.14.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 07/17] signal: Reduce copy_siginfo_to_user to just copy_to_user
  2018-04-20  1:01 [REVIEW][PATCH 00/17] siginfo bugfixes and cleanups Eric W. Biederman
                   ` (5 preceding siblings ...)
  2018-04-20  1:03 ` [REVIEW][PATCH 06/17] signal: Ensure every siginfo we send has all bits initialized Eric W. Biederman
@ 2018-04-20  1:03 ` Eric W. Biederman
  2018-04-20  1:03 ` [REVIEW][PATCH 08/17] signal: Stop special casing TRAP_FIXME and FPE_FIXME in siginfo_layout Eric W. Biederman
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20  1:03 UTC (permalink / raw)
  To: linux-arch; +Cc: linux-kernel, linux-api, Eric W. Biederman

Now that every instance of struct siginfo is now initialized it is no
longer necessary to copy struct siginfo piece by piece to userspace
but instead the entire structure can be copied.

As well as making the code simpler and more efficient this means that
copy_sinfo_to_user no longer cares which union member of struct
siginfo is in use.

In practice this means that all 32bit architectures that define
FPE_FIXME will handle properly send SI_USER when kill(SIGFPE) is sent.
While still performing their historic architectural brokenness when 0
is used a floating pointer signal.  This matches the current behavior
of 64bit architectures that define FPE_FIXME who get lucky and an
overloaded SI_USER has continuted to work through copy_siginfo_to_user
because the 8 byte si_addr occupies the same bytes in struct siginfo
as the 4 byte si_pid and the 4 byte si_uid.

Problematic architectures still need to fix their ABI so that signalfd
and 32bit compat code will work properly.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 kernel/signal.c | 84 ++-------------------------------------------------------
 1 file changed, 2 insertions(+), 82 deletions(-)

diff --git a/kernel/signal.c b/kernel/signal.c
index d4ccea599692..d56f4d496c89 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2850,89 +2850,9 @@ enum siginfo_layout siginfo_layout(int sig, int si_code)
 
 int copy_siginfo_to_user(siginfo_t __user *to, const siginfo_t *from)
 {
-	int err;
-
-	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
+	if (copy_to_user(to, from , sizeof(struct siginfo)))
 		return -EFAULT;
-	if (from->si_code < 0)
-		return __copy_to_user(to, from, sizeof(siginfo_t))
-			? -EFAULT : 0;
-	/*
-	 * If you change siginfo_t structure, please be sure
-	 * this code is fixed accordingly.
-	 * Please remember to update the signalfd_copyinfo() function
-	 * inside fs/signalfd.c too, in case siginfo_t changes.
-	 * It should never copy any pad contained in the structure
-	 * to avoid security leaks, but must copy the generic
-	 * 3 ints plus the relevant union member.
-	 */
-	err = __put_user(from->si_signo, &to->si_signo);
-	err |= __put_user(from->si_errno, &to->si_errno);
-	err |= __put_user(from->si_code, &to->si_code);
-	switch (siginfo_layout(from->si_signo, from->si_code)) {
-	case SIL_KILL:
-		err |= __put_user(from->si_pid, &to->si_pid);
-		err |= __put_user(from->si_uid, &to->si_uid);
-		break;
-	case SIL_TIMER:
-		/* Unreached SI_TIMER is negative */
-		break;
-	case SIL_POLL:
-		err |= __put_user(from->si_band, &to->si_band);
-		err |= __put_user(from->si_fd, &to->si_fd);
-		break;
-	case SIL_FAULT:
-		err |= __put_user(from->si_addr, &to->si_addr);
-#ifdef __ARCH_SI_TRAPNO
-		err |= __put_user(from->si_trapno, &to->si_trapno);
-#endif
-#ifdef __ia64__
-		err |= __put_user(from->si_imm, &to->si_imm);
-		err |= __put_user(from->si_flags, &to->si_flags);
-		err |= __put_user(from->si_isr, &to->si_isr);
-#endif
-		/*
-		 * Other callers might not initialize the si_lsb field,
-		 * so check explicitly for the right codes here.
-		 */
-#ifdef BUS_MCEERR_AR
-		if (from->si_signo == SIGBUS && from->si_code == BUS_MCEERR_AR)
-			err |= __put_user(from->si_addr_lsb, &to->si_addr_lsb);
-#endif
-#ifdef BUS_MCEERR_AO
-		if (from->si_signo == SIGBUS && from->si_code == BUS_MCEERR_AO)
-			err |= __put_user(from->si_addr_lsb, &to->si_addr_lsb);
-#endif
-#ifdef SEGV_BNDERR
-		if (from->si_signo == SIGSEGV && from->si_code == SEGV_BNDERR) {
-			err |= __put_user(from->si_lower, &to->si_lower);
-			err |= __put_user(from->si_upper, &to->si_upper);
-		}
-#endif
-#ifdef SEGV_PKUERR
-		if (from->si_signo == SIGSEGV && from->si_code == SEGV_PKUERR)
-			err |= __put_user(from->si_pkey, &to->si_pkey);
-#endif
-		break;
-	case SIL_CHLD:
-		err |= __put_user(from->si_pid, &to->si_pid);
-		err |= __put_user(from->si_uid, &to->si_uid);
-		err |= __put_user(from->si_status, &to->si_status);
-		err |= __put_user(from->si_utime, &to->si_utime);
-		err |= __put_user(from->si_stime, &to->si_stime);
-		break;
-	case SIL_RT:
-		err |= __put_user(from->si_pid, &to->si_pid);
-		err |= __put_user(from->si_uid, &to->si_uid);
-		err |= __put_user(from->si_ptr, &to->si_ptr);
-		break;
-	case SIL_SYS:
-		err |= __put_user(from->si_call_addr, &to->si_call_addr);
-		err |= __put_user(from->si_syscall, &to->si_syscall);
-		err |= __put_user(from->si_arch, &to->si_arch);
-		break;
-	}
-	return err;
+	return 0;
 }
 
 #ifdef CONFIG_COMPAT
-- 
2.14.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 08/17] signal: Stop special casing TRAP_FIXME and FPE_FIXME in siginfo_layout
  2018-04-20  1:01 [REVIEW][PATCH 00/17] siginfo bugfixes and cleanups Eric W. Biederman
                   ` (6 preceding siblings ...)
  2018-04-20  1:03 ` [REVIEW][PATCH 07/17] signal: Reduce copy_siginfo_to_user to just copy_to_user Eric W. Biederman
@ 2018-04-20  1:03 ` Eric W. Biederman
  2018-04-20  1:04 ` [REVIEW][PATCH 09/17] signal: Remove SEGV_BNDERR ifdefs Eric W. Biederman
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20  1:03 UTC (permalink / raw)
  To: linux-arch; +Cc: linux-kernel, linux-api, Eric W. Biederman

After more experience with the cases where no one the si_code of 0
is used both as a signal specific si_code, and as SI_USER it appears
that no one cares about the signal specific si_code case and the
good solution is to just fix the architectures by using
a different si_code.

In none of the conversations has anyone even suggested that
anything depends on the signal specific redefinition of SI_USER.

There are at least test cases that care when si_code as 0 does
not work as si_user.

So make things simple and keep the generic code from introducing
problems by removing the special casing of TRAP_FIXME and FPE_FIXME.
This will ensure the generic case of sending a signal with
kill will always set SI_USER and work.

The architecture specific, and signal specific overloads that
set si_code to 0 will now have problems with signalfd and
the 32bit compat versions of siginfo copying.   At least
until they are fixed.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 kernel/signal.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/kernel/signal.c b/kernel/signal.c
index d56f4d496c89..fc82d2c0918f 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2835,15 +2835,6 @@ enum siginfo_layout siginfo_layout(int sig, int si_code)
 			layout = SIL_POLL;
 		else if (si_code < 0)
 			layout = SIL_RT;
-		/* Tests to support buggy kernel ABIs */
-#ifdef TRAP_FIXME
-		if ((sig == SIGTRAP) && (si_code == TRAP_FIXME))
-			layout = SIL_FAULT;
-#endif
-#ifdef FPE_FIXME
-		if ((sig == SIGFPE) && (si_code == FPE_FIXME))
-			layout = SIL_FAULT;
-#endif
 	}
 	return layout;
 }
-- 
2.14.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 09/17] signal: Remove SEGV_BNDERR ifdefs
  2018-04-20  1:01 [REVIEW][PATCH 00/17] siginfo bugfixes and cleanups Eric W. Biederman
                   ` (7 preceding siblings ...)
  2018-04-20  1:03 ` [REVIEW][PATCH 08/17] signal: Stop special casing TRAP_FIXME and FPE_FIXME in siginfo_layout Eric W. Biederman
@ 2018-04-20  1:04 ` Eric W. Biederman
  2018-04-20  1:04 ` [REVIEW][PATCH 10/17] signal: Remove ifdefs for BUS_MCEERR_AR and BUS_MCEERR_AO Eric W. Biederman
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20  1:04 UTC (permalink / raw)
  To: linux-arch; +Cc: linux-kernel, linux-api, Eric W. Biederman

After the last round of cleanups to siginfo.h SEGV_BNDERR is defined
on all architectures so testing to see if it is defined is unnecessary.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 kernel/signal.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/kernel/signal.c b/kernel/signal.c
index fc82d2c0918f..a6d55a6e9915 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1570,7 +1570,6 @@ int send_sig_mceerr(int code, void __user *addr, short lsb, struct task_struct *
 EXPORT_SYMBOL(send_sig_mceerr);
 #endif
 
-#ifdef SEGV_BNDERR
 int force_sig_bnderr(void __user *addr, void __user *lower, void __user *upper)
 {
 	struct siginfo info;
@@ -1584,7 +1583,6 @@ int force_sig_bnderr(void __user *addr, void __user *lower, void __user *upper)
 	info.si_upper = upper;
 	return force_sig_info(info.si_signo, &info, current);
 }
-#endif
 
 #ifdef SEGV_PKUERR
 int force_sig_pkuerr(void __user *addr, u32 pkey)
@@ -2890,13 +2888,11 @@ int __copy_siginfo_to_user32(struct compat_siginfo __user *to,
 		if ((from->si_signo == SIGBUS) && (from->si_code == BUS_MCEERR_AO))
 			new.si_addr_lsb = from->si_addr_lsb;
 #endif
-#ifdef SEGV_BNDERR
 		if ((from->si_signo == SIGSEGV) &&
 		    (from->si_code == SEGV_BNDERR)) {
 			new.si_lower = ptr_to_compat(from->si_lower);
 			new.si_upper = ptr_to_compat(from->si_upper);
 		}
-#endif
 #ifdef SEGV_PKUERR
 		if ((from->si_signo == SIGSEGV) &&
 		    (from->si_code == SEGV_PKUERR))
@@ -2976,12 +2972,10 @@ int copy_siginfo_from_user32(struct siginfo *to,
 		if ((from.si_signo == SIGBUS) && (from.si_code == BUS_MCEERR_AO))
 			to->si_addr_lsb = from.si_addr_lsb;
 #endif
-#ifdef SEGV_BNDERR
 		if ((from.si_signo == SIGSEGV) && (from.si_code == SEGV_BNDERR)) {
 			to->si_lower = compat_ptr(from.si_lower);
 			to->si_upper = compat_ptr(from.si_upper);
 		}
-#endif
 #ifdef SEGV_PKUERR
 		if ((from.si_signo == SIGSEGV) && (from.si_code == SEGV_PKUERR))
 			to->si_pkey = from.si_pkey;
-- 
2.14.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 10/17] signal: Remove ifdefs for BUS_MCEERR_AR and BUS_MCEERR_AO
  2018-04-20  1:01 [REVIEW][PATCH 00/17] siginfo bugfixes and cleanups Eric W. Biederman
                   ` (8 preceding siblings ...)
  2018-04-20  1:04 ` [REVIEW][PATCH 09/17] signal: Remove SEGV_BNDERR ifdefs Eric W. Biederman
@ 2018-04-20  1:04 ` Eric W. Biederman
  2018-04-20  1:04 ` [REVIEW][PATCH 11/17] signal/alpha: Replace FPE_FIXME with FPE_FLTUNK Eric W. Biederman
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20  1:04 UTC (permalink / raw)
  To: linux-arch; +Cc: linux-kernel, linux-api, Eric W. Biederman

With the recent architecture cleanups these si_codes are always
defined so there is no need to test for them.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/signalfd.c   | 15 ++-------------
 kernel/signal.c | 24 ++++++++----------------
 2 files changed, 10 insertions(+), 29 deletions(-)

diff --git a/fs/signalfd.c b/fs/signalfd.c
index d2187a813376..ff302bf50be4 100644
--- a/fs/signalfd.c
+++ b/fs/signalfd.c
@@ -117,26 +117,15 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
 #ifdef __ARCH_SI_TRAPNO
 		err |= __put_user(kinfo->si_trapno, &uinfo->ssi_trapno);
 #endif
-#ifdef BUS_MCEERR_AO
 		/*
 		 * Other callers might not initialize the si_lsb field,
 		 * so check explicitly for the right codes here.
 		 */
 		if (kinfo->si_signo == SIGBUS &&
-		     kinfo->si_code == BUS_MCEERR_AO)
+		    ((kinfo->si_code == BUS_MCEERR_AR) ||
+		     (kinfo->si_code == BUS_MCEERR_AO)))
 			err |= __put_user((short) kinfo->si_addr_lsb,
 					  &uinfo->ssi_addr_lsb);
-#endif
-#ifdef BUS_MCEERR_AR
-		/*
-		 * Other callers might not initialize the si_lsb field,
-		 * so check explicitly for the right codes here.
-		 */
-		if (kinfo->si_signo == SIGBUS &&
-		    kinfo->si_code == BUS_MCEERR_AR)
-			err |= __put_user((short) kinfo->si_addr_lsb,
-					  &uinfo->ssi_addr_lsb);
-#endif
 		break;
 	case SIL_CHLD:
 		err |= __put_user(kinfo->si_pid, &uinfo->ssi_pid);
diff --git a/kernel/signal.c b/kernel/signal.c
index a6d55a6e9915..b87a9c21f698 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1539,7 +1539,6 @@ int send_sig_fault(int sig, int code, void __user *addr
 	return send_sig_info(info.si_signo, &info, t);
 }
 
-#if defined(BUS_MCEERR_AO) && defined(BUS_MCEERR_AR)
 int force_sig_mceerr(int code, void __user *addr, short lsb, struct task_struct *t)
 {
 	struct siginfo info;
@@ -1568,7 +1567,6 @@ int send_sig_mceerr(int code, void __user *addr, short lsb, struct task_struct *
 	return send_sig_info(info.si_signo, &info, t);
 }
 EXPORT_SYMBOL(send_sig_mceerr);
-#endif
 
 int force_sig_bnderr(void __user *addr, void __user *lower, void __user *upper)
 {
@@ -2880,14 +2878,11 @@ int __copy_siginfo_to_user32(struct compat_siginfo __user *to,
 #ifdef __ARCH_SI_TRAPNO
 		new.si_trapno = from->si_trapno;
 #endif
-#ifdef BUS_MCEERR_AR
-		if ((from->si_signo == SIGBUS) && (from->si_code == BUS_MCEERR_AR))
-			new.si_addr_lsb = from->si_addr_lsb;
-#endif
-#ifdef BUS_MCEERR_AO
-		if ((from->si_signo == SIGBUS) && (from->si_code == BUS_MCEERR_AO))
+		if ((from->si_signo == SIGBUS) &&
+		    ((from->si_code == BUS_MCEERR_AR) ||
+		     (from->si_code == BUS_MCEERR_AO)))
 			new.si_addr_lsb = from->si_addr_lsb;
-#endif
+
 		if ((from->si_signo == SIGSEGV) &&
 		    (from->si_code == SEGV_BNDERR)) {
 			new.si_lower = ptr_to_compat(from->si_lower);
@@ -2964,14 +2959,11 @@ int copy_siginfo_from_user32(struct siginfo *to,
 #ifdef __ARCH_SI_TRAPNO
 		to->si_trapno = from.si_trapno;
 #endif
-#ifdef BUS_MCEERR_AR
-		if ((from.si_signo == SIGBUS) && (from.si_code == BUS_MCEERR_AR))
+		if ((from.si_signo == SIGBUS) &&
+		    ((from.si_code == BUS_MCEERR_AR) ||
+		     (from.si_code == BUS_MCEERR_AO)))
 			to->si_addr_lsb = from.si_addr_lsb;
-#endif
-#ifdef BUS_MCEER_AO
-		if ((from.si_signo == SIGBUS) && (from.si_code == BUS_MCEERR_AO))
-			to->si_addr_lsb = from.si_addr_lsb;
-#endif
+
 		if ((from.si_signo == SIGSEGV) && (from.si_code == SEGV_BNDERR)) {
 			to->si_lower = compat_ptr(from.si_lower);
 			to->si_upper = compat_ptr(from.si_upper);
-- 
2.14.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 11/17] signal/alpha: Replace FPE_FIXME with FPE_FLTUNK
  2018-04-20  1:01 [REVIEW][PATCH 00/17] siginfo bugfixes and cleanups Eric W. Biederman
                   ` (9 preceding siblings ...)
  2018-04-20  1:04 ` [REVIEW][PATCH 10/17] signal: Remove ifdefs for BUS_MCEERR_AR and BUS_MCEERR_AO Eric W. Biederman
@ 2018-04-20  1:04 ` Eric W. Biederman
  2018-04-20  1:04 ` [REVIEW][PATCH 12/17] signal/ia64: " Eric W. Biederman
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20  1:04 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, linux-api, Eric W. Biederman, Helge Deller,
	Richard Henderson, Ivan Kokshaysky, Matt Turner, linux-alpha

Using an si_code of 0 that aliases with SI_USER is clearly the wrong
thing todo, and causes problems in interesting ways.

The newly defined FPE_FLTUNK semantically appears to fit the bill so
use it instead.

Given recent experience in this area odds are it will not break
anything.  Fixing it removes a hazard to kernel maintenance.

Cc: Helge Deller <deller@gmx.de>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Matt Turner <mattst88@gmail.com>
Cc: linux-alpha@vger.kernel.org
History Tree: https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git
Fixes: 0a635c7a84cf ("Fill in siginfo_t.")
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/alpha/include/uapi/asm/siginfo.h | 7 -------
 arch/alpha/kernel/osf_sys.c           | 2 +-
 arch/alpha/kernel/traps.c             | 2 +-
 3 files changed, 2 insertions(+), 9 deletions(-)

diff --git a/arch/alpha/include/uapi/asm/siginfo.h b/arch/alpha/include/uapi/asm/siginfo.h
index 0cf3b527b274..3ebbb1e17902 100644
--- a/arch/alpha/include/uapi/asm/siginfo.h
+++ b/arch/alpha/include/uapi/asm/siginfo.h
@@ -7,13 +7,6 @@
 
 #include <asm-generic/siginfo.h>
 
-/*
- * SIGFPE si_codes
- */
-#ifdef __KERNEL__
-#define FPE_FIXME	0	/* Broken dup of SI_USER */
-#endif /* __KERNEL__ */
-
 /*
  * SIGTRAP si_codes
  */
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index f5f154942aab..bb3619118926 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -872,7 +872,7 @@ SYSCALL_DEFINE5(osf_setsysinfo, unsigned long, op, void __user *, buffer,
 		fex = (exc >> IEEE_STATUS_TO_EXCSUM_SHIFT) & swcr;
  		if (fex) {
 			siginfo_t info;
-			int si_code = FPE_FIXME;
+			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;
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index 91636765dd6d..422b676b28f2 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -328,7 +328,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:
-- 
2.14.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 12/17] signal/ia64: Replace FPE_FIXME with FPE_FLTUNK
  2018-04-20  1:01 [REVIEW][PATCH 00/17] siginfo bugfixes and cleanups Eric W. Biederman
                   ` (10 preceding siblings ...)
  2018-04-20  1:04 ` [REVIEW][PATCH 11/17] signal/alpha: Replace FPE_FIXME with FPE_FLTUNK Eric W. Biederman
@ 2018-04-20  1:04 ` Eric W. Biederman
  2018-04-20  1:04 ` [REVIEW][PATCH 13/17] signal/powerpc: " Eric W. Biederman
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20  1:04 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, linux-api, Eric W. Biederman, Tony Luck,
	Fenghua Yu, linux-ia64

Using an si_code of 0 that aliases with SI_USER is clearly the wrong
thing todo, and causes problems in interesting ways.

The newly defined FPE_FLTUNK semantically appears to fit the bill so
use it instead.

Given recent experience in this area odds are it will not
break anything.  Fixing it removes a hazard to kernel maintenance.

Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: linux-ia64@vger.kernel.org
Fixes: 987159266c45 ("Linux version 2.3.48")
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/ia64/include/uapi/asm/siginfo.h | 7 -------
 arch/ia64/kernel/traps.c             | 4 ++--
 2 files changed, 2 insertions(+), 9 deletions(-)

diff --git a/arch/ia64/include/uapi/asm/siginfo.h b/arch/ia64/include/uapi/asm/siginfo.h
index 5aa454ed89db..52b5af424511 100644
--- a/arch/ia64/include/uapi/asm/siginfo.h
+++ b/arch/ia64/include/uapi/asm/siginfo.h
@@ -27,11 +27,4 @@
 #define __ISR_VALID_BIT	0
 #define __ISR_VALID	(1 << __ISR_VALID_BIT)
 
-/*
- * SIGFPE si_codes
- */
-#ifdef __KERNEL__
-#define FPE_FIXME	0	/* Broken dup of SI_USER */
-#endif /* __KERNEL__ */
-
 #endif /* _UAPI_ASM_IA64_SIGINFO_H */
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index 972873ed1ae5..c6f4932073a1 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -353,7 +353,7 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr)
 			clear_siginfo(&siginfo);
 			siginfo.si_signo = SIGFPE;
 			siginfo.si_errno = 0;
-			siginfo.si_code = FPE_FIXME;	/* default code */
+			siginfo.si_code = FPE_FLTUNK;	/* default code */
 			siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
 			if (isr & 0x11) {
 				siginfo.si_code = FPE_FLTINV;
@@ -380,7 +380,7 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr)
 			clear_siginfo(&siginfo);
 			siginfo.si_signo = SIGFPE;
 			siginfo.si_errno = 0;
-			siginfo.si_code = FPE_FIXME;	/* default code */
+			siginfo.si_code = FPE_FLTUNK;	/* default code */
 			siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
 			if (isr & 0x880) {
 				siginfo.si_code = FPE_FLTOVF;
-- 
2.14.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 13/17] signal/powerpc: Replace FPE_FIXME with FPE_FLTUNK
  2018-04-20  1:01 [REVIEW][PATCH 00/17] siginfo bugfixes and cleanups Eric W. Biederman
                   ` (11 preceding siblings ...)
  2018-04-20  1:04 ` [REVIEW][PATCH 12/17] signal/ia64: " Eric W. Biederman
@ 2018-04-20  1:04 ` Eric W. Biederman
  2018-04-20  1:04 ` [REVIEW][PATCH 14/17] signal/unicore32: Use FPE_FLTUNK instead of 0 in ucf64_raise_sigfpe Eric W. Biederman
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20  1:04 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, linux-api, Eric W. Biederman, Paul Mackerras,
	Kumar Gala, Michael Ellerman, Benjamin Herrenschmidt,
	linuxppc-dev

Using an si_code of 0 that aliases with SI_USER is clearly the
wrong thing todo, and causes problems in interesting ways.

The newly defined FPE_FLTUNK semantically appears to fit the
bill so use it instead.

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
Fixes: 9bad068c24d7 ("[PATCH] ppc32: support for e500 and 85xx")
Fixes: 0ed70f6105ef ("PPC32: Provide proper siginfo information on various exceptions.")
History Tree: https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/powerpc/include/uapi/asm/siginfo.h | 7 -------
 arch/powerpc/kernel/traps.c             | 6 +++---
 2 files changed, 3 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/include/uapi/asm/siginfo.h b/arch/powerpc/include/uapi/asm/siginfo.h
index 9f142451a01f..0437afc9ef3c 100644
--- a/arch/powerpc/include/uapi/asm/siginfo.h
+++ b/arch/powerpc/include/uapi/asm/siginfo.h
@@ -15,13 +15,6 @@
 
 #include <asm-generic/siginfo.h>
 
-/*
- * SIGFPE si_codes
- */
-#ifdef __KERNEL__
-#define FPE_FIXME	0	/* Broken dup of SI_USER */
-#endif /* __KERNEL__ */
-
 /*
  * SIGTRAP si_codes
  */
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 087855caf6a9..fdf9400beec8 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -1031,7 +1031,7 @@ static void emulate_single_step(struct pt_regs *regs)
 
 static inline int __parse_fpscr(unsigned long fpscr)
 {
-	int ret = FPE_FIXME;
+	int ret = FPE_FLTUNK;
 
 	/* Invalid operation */
 	if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX))
@@ -1972,7 +1972,7 @@ void SPEFloatingPointException(struct pt_regs *regs)
 	extern int do_spe_mathemu(struct pt_regs *regs);
 	unsigned long spefscr;
 	int fpexc_mode;
-	int code = FPE_FIXME;
+	int code = FPE_FLTUNK;
 	int err;
 
 	flush_spe_to_thread(current);
@@ -2041,7 +2041,7 @@ void SPEFloatingPointRoundException(struct pt_regs *regs)
 		printk(KERN_ERR "unrecognized spe instruction "
 		       "in %s at %lx\n", current->comm, regs->nip);
 	} else {
-		_exception(SIGFPE, regs, FPE_FIXME, regs->nip);
+		_exception(SIGFPE, regs, FPE_FLTUNK, regs->nip);
 		return;
 	}
 }
-- 
2.14.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 14/17] signal/unicore32: Use FPE_FLTUNK instead of 0 in ucf64_raise_sigfpe
  2018-04-20  1:01 [REVIEW][PATCH 00/17] siginfo bugfixes and cleanups Eric W. Biederman
                   ` (12 preceding siblings ...)
  2018-04-20  1:04 ` [REVIEW][PATCH 13/17] signal/powerpc: " Eric W. Biederman
@ 2018-04-20  1:04 ` Eric W. Biederman
  2018-04-20  1:04 ` [REVIEW][PATCH 15/17] signal: Add TRAP_UNK si_code for undiagnosted trap exceptions Eric W. Biederman
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20  1:04 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, linux-api, Eric W. Biederman, Guan Xuetao, Arnd Bergmann

The si_code of 0 (aka SI_USER) has fields si_pid and si_uid not
si_addr so it so only by luck would the appropriate fields by copied
to userspace by copy_siginfo_to_user.

This is just broken and wrong.

Make it obvious what is happening by moving the si_code from a
parameter of the one call to ucf64_raise_sigfpe to a constant value
that info.si_code gets set to.

Explicitly set the si_code to FPE_FLTUNK the newly reserved floating
point si_code for an unknown floating point exception.

It looks like there is a fair chance that this is a code path that has
never been used in real life on unicore32.  The bad si_code and the
print statement that calls it an unhandled exception.  So I really
don't expect anyone will mind if this just gets fixed.

In similar situations on more popular architectures the conclusion was
just fix it.

Cc: Guan Xuetao <gxt@mprc.pku.edu.cn>
Cc: Arnd Bergmann <arnd@arndb.de>
Fixes: d9bc15794d12 ("unicore32 additional architecture files: float point handling")
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/unicore32/kernel/fpu-ucf64.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/unicore32/kernel/fpu-ucf64.c b/arch/unicore32/kernel/fpu-ucf64.c
index d785955e1c29..8594b168f25e 100644
--- a/arch/unicore32/kernel/fpu-ucf64.c
+++ b/arch/unicore32/kernel/fpu-ucf64.c
@@ -52,14 +52,14 @@
  * Raise a SIGFPE for the current process.
  * sicode describes the signal being raised.
  */
-void ucf64_raise_sigfpe(unsigned int sicode, struct pt_regs *regs)
+void ucf64_raise_sigfpe(struct pt_regs *regs)
 {
 	siginfo_t info;
 
 	clear_siginfo(&info);
 
 	info.si_signo = SIGFPE;
-	info.si_code = sicode;
+	info.si_code = FPE_FLTUNK;
 	info.si_addr = (void __user *)(instruction_pointer(regs) - 4);
 
 	/*
@@ -94,7 +94,7 @@ void ucf64_exchandler(u32 inst, u32 fpexc, struct pt_regs *regs)
 		pr_debug("UniCore-F64 FPSCR 0x%08x INST 0x%08x\n",
 				cff(FPSCR), inst);
 
-		ucf64_raise_sigfpe(0, regs);
+		ucf64_raise_sigfpe(regs);
 		return;
 	}
 
-- 
2.14.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 15/17] signal: Add TRAP_UNK si_code for undiagnosted trap exceptions
  2018-04-20  1:01 [REVIEW][PATCH 00/17] siginfo bugfixes and cleanups Eric W. Biederman
                   ` (13 preceding siblings ...)
  2018-04-20  1:04 ` [REVIEW][PATCH 14/17] signal/unicore32: Use FPE_FLTUNK instead of 0 in ucf64_raise_sigfpe Eric W. Biederman
@ 2018-04-20  1:04 ` Eric W. Biederman
  2018-04-20  1:04 ` [REVIEW][PATCH 16/17] signal/alpha: Replace TRAP_FIXME with TRAP_UNK Eric W. Biederman
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20  1:04 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, linux-api, Eric W. Biederman, linux-alpha, linuxppc-dev

Both powerpc and alpha have cases where they wronly set si_code to 0
in combination with SIGTRAP and don't mean SI_USER.

About half the time this is because the architecture can not report
accurately what kind of trap exception triggered the trap exception.
The other half the time it looks like no one has bothered to
figure out an appropriate si_code.

For the cases where the architecture does not have enough information
or is too lazy to figure out exactly what kind of trap exception
it is define TRAP_UNK.

Cc: linux-api@vger.kernel.org
Cc: linux-arch@vger.kernel.org
Cc: linux-alpha@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/x86/kernel/signal_compat.c    | 2 +-
 include/uapi/asm-generic/siginfo.h | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/signal_compat.c b/arch/x86/kernel/signal_compat.c
index 14c057f29979..9ccbf0576cd0 100644
--- a/arch/x86/kernel/signal_compat.c
+++ b/arch/x86/kernel/signal_compat.c
@@ -29,7 +29,7 @@ static inline void signal_compat_build_tests(void)
 	BUILD_BUG_ON(NSIGFPE  != 15);
 	BUILD_BUG_ON(NSIGSEGV != 7);
 	BUILD_BUG_ON(NSIGBUS  != 5);
-	BUILD_BUG_ON(NSIGTRAP != 4);
+	BUILD_BUG_ON(NSIGTRAP != 5);
 	BUILD_BUG_ON(NSIGCHLD != 6);
 	BUILD_BUG_ON(NSIGSYS  != 1);
 
diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h
index 558b902f18d4..80e2a7227205 100644
--- a/include/uapi/asm-generic/siginfo.h
+++ b/include/uapi/asm-generic/siginfo.h
@@ -249,7 +249,8 @@ typedef struct siginfo {
 #define TRAP_TRACE	2	/* process trace trap */
 #define TRAP_BRANCH     3	/* process taken branch trap */
 #define TRAP_HWBKPT     4	/* hardware breakpoint/watchpoint */
-#define NSIGTRAP	4
+#define TRAP_UNK	5	/* undiagnosed trap */
+#define NSIGTRAP	5
 
 /*
  * There is an additional set of SIGTRAP si_codes used by ptrace
-- 
2.14.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 16/17] signal/alpha:  Replace TRAP_FIXME with TRAP_UNK
  2018-04-20  1:01 [REVIEW][PATCH 00/17] siginfo bugfixes and cleanups Eric W. Biederman
                   ` (14 preceding siblings ...)
  2018-04-20  1:04 ` [REVIEW][PATCH 15/17] signal: Add TRAP_UNK si_code for undiagnosted trap exceptions Eric W. Biederman
@ 2018-04-20  1:04 ` Eric W. Biederman
  2018-04-20  1:04 ` [REVIEW][PATCH 17/17] signal/powerpc: " Eric W. Biederman
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
  17 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20  1:04 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, linux-api, Eric W. Biederman, Helge Deller,
	Richard Henderson, Ivan Kokshaysky, Matt Turner, linux-alpha

Using an si_code of 0 that aliases with SI_USER is clearly the wrong
thing to do, and causes problems in interesting ways.

For it really is not clear to me if using TRAP_UNK bugcheck or
the default case of gentrap is really the best way to handle
things.  There is certainly enough information that that a more
specific si_code could potentially be used.  That said TRAP_UNK
is definitely an improvement over 0 as it removes the ambiguiuty
of what si_code of 0 with SIGTRAP means on alpha.

Recent history suggests no actually cares about crazy corner cases of
the kernel behavior like this so I don't expect any regressions from
changing this.  However if something does happen this change is easy
to revert.

Cc: Helge Deller <deller@gmx.de>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Matt Turner <mattst88@gmail.com>
Cc: linux-alpha@vger.kernel.org
Fixes: 0a635c7a84cf ("Fill in siginfo_t.")
History Tree: https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/alpha/include/uapi/asm/siginfo.h | 7 -------
 arch/alpha/kernel/traps.c             | 4 ++--
 2 files changed, 2 insertions(+), 9 deletions(-)

diff --git a/arch/alpha/include/uapi/asm/siginfo.h b/arch/alpha/include/uapi/asm/siginfo.h
index 3ebbb1e17902..db3f0138536f 100644
--- a/arch/alpha/include/uapi/asm/siginfo.h
+++ b/arch/alpha/include/uapi/asm/siginfo.h
@@ -7,11 +7,4 @@
 
 #include <asm-generic/siginfo.h>
 
-/*
- * SIGTRAP si_codes
- */
-#ifdef __KERNEL__
-#define TRAP_FIXME	0	/* Broken dup of SI_USER */
-#endif /* __KERNEL__ */
-
 #endif
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index 422b676b28f2..242c83d86ace 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -288,7 +288,7 @@ do_entIF(unsigned long type, struct pt_regs *regs)
 	      case 1: /* bugcheck */
 		info.si_signo = SIGTRAP;
 		info.si_errno = 0;
-		info.si_code = TRAP_FIXME;
+		info.si_code = TRAP_UNK;
 		info.si_addr = (void __user *) regs->pc;
 		info.si_trapno = 0;
 		send_sig_info(SIGTRAP, &info, current);
@@ -350,7 +350,7 @@ do_entIF(unsigned long type, struct pt_regs *regs)
 		case GEN_SUBRNG7:
 		default:
 			signo = SIGTRAP;
-			code = TRAP_FIXME;
+			code = TRAP_UNK;
 			break;
 		}
 
-- 
2.14.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 17/17] signal/powerpc: Replace TRAP_FIXME with TRAP_UNK
  2018-04-20  1:01 [REVIEW][PATCH 00/17] siginfo bugfixes and cleanups Eric W. Biederman
                   ` (15 preceding siblings ...)
  2018-04-20  1:04 ` [REVIEW][PATCH 16/17] signal/alpha: Replace TRAP_FIXME with TRAP_UNK Eric W. Biederman
@ 2018-04-20  1:04 ` Eric W. Biederman
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
  17 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20  1:04 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, linux-api, Eric W. Biederman, Paul Mackerras,
	Kumar Gala, Michael Ellerman, Benjamin Herrenschmidt,
	linuxppc-dev

Using an si_code of 0 that aliases with SI_USER is clearly the wrong
thing todo, and causes problems in interesting ways.

For use in unknown_exception the recently defined TRAP_UNK
semantically is a perfect fit.  For use in RunModeException it looks
like something more specific than TRAP_UNK could be used.  No one has
bothered to find a better fit than the broken si_code of 0 in all of
these years and I don't see an obvious better fit so TRAP_UNK is
switching RunModeException to return TRAP_UNK is clearly an
improvement.

Recent history suggests no actually cares about crazy corner
cases of the kernel behavior like this so I don't expect any
regressions from changing this.  However if something does
happen this change is easy to revert.

Though I wonder if SIGKILL might not be a better fit.

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
Fixes: 9bad068c24d7 ("[PATCH] ppc32: support for e500 and 85xx")
Fixes: 0ed70f6105ef ("PPC32: Provide proper siginfo information on various exceptions.")
History Tree: https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/powerpc/include/uapi/asm/siginfo.h | 8 --------
 arch/powerpc/kernel/traps.c             | 4 ++--
 2 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/include/uapi/asm/siginfo.h b/arch/powerpc/include/uapi/asm/siginfo.h
index 0437afc9ef3c..1d51d9b88221 100644
--- a/arch/powerpc/include/uapi/asm/siginfo.h
+++ b/arch/powerpc/include/uapi/asm/siginfo.h
@@ -15,12 +15,4 @@
 
 #include <asm-generic/siginfo.h>
 
-/*
- * SIGTRAP si_codes
- */
-#ifdef __KERNEL__
-#define TRAP_FIXME	0	/* Broken dup of SI_USER */
-#endif /* __KERNEL__ */
-
-
 #endif	/* _ASM_POWERPC_SIGINFO_H */
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index fdf9400beec8..0e17dcb48720 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -969,7 +969,7 @@ void unknown_exception(struct pt_regs *regs)
 	printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
 	       regs->nip, regs->msr, regs->trap);
 
-	_exception(SIGTRAP, regs, TRAP_FIXME, 0);
+	_exception(SIGTRAP, regs, TRAP_UNK, 0);
 
 	exception_exit(prev_state);
 }
@@ -991,7 +991,7 @@ void instruction_breakpoint_exception(struct pt_regs *regs)
 
 void RunModeException(struct pt_regs *regs)
 {
-	_exception(SIGTRAP, regs, TRAP_FIXME, 0);
+	_exception(SIGTRAP, regs, TRAP_UNK, 0);
 }
 
 void single_step_exception(struct pt_regs *regs)
-- 
2.14.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 00/22] Simplifying siginfo users
  2018-04-20  1:01 [REVIEW][PATCH 00/17] siginfo bugfixes and cleanups Eric W. Biederman
                   ` (16 preceding siblings ...)
  2018-04-20  1:04 ` [REVIEW][PATCH 17/17] signal/powerpc: " Eric W. Biederman
@ 2018-04-20 14:35 ` Eric W. Biederman
  2018-04-20 14:37   ` [REVIEW][PATCH 01/22] signal/alpha: Use send_sig_fault where appropriate Eric W. Biederman
                     ` (21 more replies)
  17 siblings, 22 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20 14:35 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, Albert Ou, Aurelien Jacquiot, Chris Zankel,
	David Miller, Geert Uytterhoeven, Greentime Hu, Heiko Carstens,
	Helge Deller, Ivan Kokshaysky, James Bottomley, James Hogan,
	Jeff Dike, Jonas Bonn, Ley Foon Tan, Mark Salter,
	Martin Schwidefsky, Max Filippov, Michal Simek, nios2-dev,
	openrisc, Palmer Dabbelt, Ralf Baechle, Richard Henderson,
	Richard Kuo, Richard Weinberger, Rich Felker, sparclinux, stable,
	Stafford Horne, Stefan Kristiansson, user-mode-linux-devel,
	Vincent Chen, Yoshinori Sato


This patchset is almost completely updating the various pieces of
architecture code from filling out a struct siginfo and then calling
force_sig_info.  To using the helper force_sig_fault instead.  Which
takes the values that would have gone in siginfo as arguments.

As the diffstat below shows this noticeable reduces the amount of code.

There are a couple of minor and straight forward bug fixes as well
that I came across while working on the aforementioned changes.

This applies on my last round of siginfo changes simply to remove the
possibility of conflicts.  The changes should be semantically separate.

I intend to merge these changes through my siginfo tree.  If you have
any objections or would prefer to carry these changes in your
architecture trees please let me know.

The changes are also available at:
  git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace.git siginfo-review2

Eric W. Biederman (22):
      signal/alpha: Use send_sig_fault where appropriate
      signal/alpha: Use force_sig_fault where appropriate
      signal/c6x: Use force_sig_fault where appropriate
      signal/hexagon: Use force_sig_fault as appropriate
      signal/m68k: Use force_sig_fault where appropriate
      signal/microblaze: Remove the commented out force_sig_info in do_page_fault
      signal/microblaze: Use force_sig_fault where appropriate
      signal/mips: Use force_sig_fault where appropriate
      signal/nds32: Use force_sig_fault where appropriate
      signal/nios2: Use force_sig_fault where appropriate
      signal/openrisc: Use force_sig_fault where appropriate
      signal/parisc: Use force_sig_mceerr where appropriate
      signal/parisc: Use force_sig_fault where appropriate
      signal/riscv: Use force_sig_fault where appropriate
      signal/s390: Use force_sig_fault where appropriate
      signal/sh: Use force_sig_fault where appropriate
      signal/sparc: Use send_sig_fault where appropriate
      signal/sparc: Use force_sig_fault where appropriate
      signal/um: Use force_sig_fault in relay_signal.
      signal/um: Use force_sig_fault where appropriate
      signal/xtensa: Consistenly use SIGBUS in do_unaligned_user
      signal/xtensa: Use force_sig_fault where appropriate

 arch/alpha/kernel/osf_sys.c         |  10 +--
 arch/alpha/kernel/signal.c          |  22 +-----
 arch/alpha/kernel/traps.c           |  80 +++++---------------
 arch/alpha/mm/fault.c               |  15 +---
 arch/c6x/kernel/traps.c             |  10 +--
 arch/hexagon/kernel/traps.c         |  10 +--
 arch/hexagon/mm/vm_fault.c          |  21 ++----
 arch/m68k/kernel/traps.c            |  60 +++++++--------
 arch/m68k/mm/fault.c                |  25 +++----
 arch/microblaze/kernel/exceptions.c |   9 +--
 arch/microblaze/mm/fault.c          |  14 +---
 arch/mips/kernel/traps.c            |  65 +++++-----------
 arch/mips/mm/fault.c                |  19 ++---
 arch/nds32/kernel/traps.c           |  20 +----
 arch/nds32/mm/fault.c               |  19 ++---
 arch/nios2/kernel/traps.c           |   9 +--
 arch/openrisc/kernel/traps.c        |  33 +-------
 arch/openrisc/mm/fault.c            |  19 ++---
 arch/parisc/kernel/ptrace.c         |  11 +--
 arch/parisc/kernel/traps.c          |  63 +++++-----------
 arch/parisc/kernel/unaligned.c      |  16 +---
 arch/parisc/math-emu/driver.c       |   9 +--
 arch/parisc/mm/fault.c              |  55 +++++++-------
 arch/riscv/kernel/traps.c           |   9 +--
 arch/s390/kernel/traps.c            |  32 ++------
 arch/s390/mm/fault.c                |  23 ++----
 arch/sh/kernel/traps_32.c           |  19 ++---
 arch/sh/math-emu/math.c             |   9 +--
 arch/sh/mm/fault.c                  |  10 +--
 arch/sparc/kernel/process_64.c      |  10 +--
 arch/sparc/kernel/sys_sparc_32.c    |   9 +--
 arch/sparc/kernel/sys_sparc_64.c    |   8 +-
 arch/sparc/kernel/traps_32.c        | 114 +++++-----------------------
 arch/sparc/kernel/traps_64.c        | 145 +++++++-----------------------------
 arch/sparc/kernel/unaligned_32.c    |  12 +--
 arch/sparc/mm/fault_32.c            |  13 +---
 arch/sparc/mm/fault_64.c            |   9 +--
 arch/um/kernel/ptrace.c             |  13 +---
 arch/um/kernel/trap.c               |  54 ++++++--------
 arch/xtensa/kernel/traps.c          |  10 +--
 arch/xtensa/mm/fault.c              |  19 ++---
 41 files changed, 280 insertions(+), 852 deletions(-)

Eric

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 01/22] signal/alpha: Use send_sig_fault where appropriate
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
@ 2018-04-20 14:37   ` Eric W. Biederman
  2018-04-20 14:37   ` [REVIEW][PATCH 02/22] signal/alpha: Use force_sig_fault " Eric W. Biederman
                     ` (20 subsequent siblings)
  21 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20 14:37 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, Eric W. Biederman, Richard Henderson,
	Ivan Kokshaysky, linux-alpha

Filling in struct siginfo before calling send_sig_info a tedious and
error prone process, where once in a great while the wrong fields
are filled out, and siginfo has been inconsistently cleared.

Simplify this process by using the helper send_sig_fault.  Which
takes as a parameters all of the information it needs, ensures
all of the fiddly bits of filling in struct siginfo are done properly
and then calls send_sig_info.

In short about a 5 line reduction in code for every time send_sig_info
is called, which makes the calling function clearer.

Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: linux-alpha@vger.kernel.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/alpha/kernel/osf_sys.c | 10 ++-----
 arch/alpha/kernel/signal.c  | 22 +++-----------
 arch/alpha/kernel/traps.c   | 71 +++++++++++----------------------------------
 3 files changed, 24 insertions(+), 79 deletions(-)

diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index bb3619118926..6e921754c8fc 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -871,7 +871,6 @@ 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 = FPE_FLTUNK;
 
 			if (fex & IEEE_TRAP_ENABLE_DNO) si_code = FPE_FLTUND;
@@ -881,12 +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;
 
-			clear_siginfo(&info);
-			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;
 	}
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
index cd306e602313..8c0c4ee0be6e 100644
--- a/arch/alpha/kernel/signal.c
+++ b/arch/alpha/kernel/signal.c
@@ -219,15 +219,8 @@ do_sigreturn(struct sigcontext __user *sc)
 
 	/* Send SIGTRAP if we're single-stepping: */
 	if (ptrace_cancel_bpt (current)) {
-		siginfo_t info;
-
-		clear_siginfo(&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;
 
@@ -254,15 +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;
-
-		clear_siginfo(&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;
 
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index 242c83d86ace..106a1692fca0 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -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
@@ -228,21 +227,14 @@ do_entArith(unsigned long summary, unsigned long write_mask,
 	}
 	die_if_kernel("Arithmetic fault", regs, 0, NULL);
 
-	clear_siginfo(&info);
-	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;
 
-	clear_siginfo(&info);
 	if ((regs->ps & ~IPL_MAX) == 0) {
 		if (type == 1) {
 			const unsigned int *data
@@ -272,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_UNK;
-		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;
@@ -354,11 +335,8 @@ do_entIF(unsigned long type, struct pt_regs *regs)
 			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 */
@@ -382,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;
 			}
 		}
@@ -411,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 
@@ -761,11 +733,9 @@ 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;
 
-	clear_siginfo(&info);
-
 	/* Check the UAC bits to decide what the user wants us to do
 	   with the unaliged access.  */
 
@@ -986,34 +956,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;
 }
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 02/22] signal/alpha: Use force_sig_fault where appropriate
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
  2018-04-20 14:37   ` [REVIEW][PATCH 01/22] signal/alpha: Use send_sig_fault where appropriate Eric W. Biederman
@ 2018-04-20 14:37   ` Eric W. Biederman
  2018-04-20 14:37   ` [REVIEW][PATCH 03/22] signal/c6x: " Eric W. Biederman
                     ` (19 subsequent siblings)
  21 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20 14:37 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, Eric W. Biederman, Richard Henderson,
	Ivan Kokshaysky, linux-alpha

Filling in struct siginfo before calling force_sig_info a tedious and
error prone process, where once in a great while the wrong fields
are filled out, and siginfo has been inconsistently cleared.

Simplify this process by using the helper force_sig_fault.  Which
takes as a parameters all of the information it needs, ensures
all of the fiddly bits of filling in struct siginfo are done properly
and then calls force_sig_info.

In short about a 5 line reduction in code for every time force_sig_info
is called, which makes the calling function clearer.

Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: linux-alpha@vger.kernel.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/alpha/kernel/traps.c |  9 +--------
 arch/alpha/mm/fault.c     | 15 ++-------------
 2 files changed, 3 insertions(+), 21 deletions(-)

diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index 106a1692fca0..bc9627698796 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -400,16 +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);
 
-	clear_siginfo(&info);
-	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);
 }
 
 
diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
index 7f2202a9f50a..de2bd217adad 100644
--- a/arch/alpha/mm/fault.c
+++ b/arch/alpha/mm/fault.c
@@ -88,11 +88,8 @@ 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;
 
-	clear_siginfo(&info);
-
 	/* As of EV6, a load into $31/$f31 is a prefetch, and never faults
 	   (or is suppressed by the PALcode).  Support that for older CPUs
 	   by ignoring such an instruction.  */
@@ -223,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
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 03/22] signal/c6x: Use force_sig_fault where appropriate
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
  2018-04-20 14:37   ` [REVIEW][PATCH 01/22] signal/alpha: Use send_sig_fault where appropriate Eric W. Biederman
  2018-04-20 14:37   ` [REVIEW][PATCH 02/22] signal/alpha: Use force_sig_fault " Eric W. Biederman
@ 2018-04-20 14:37   ` Eric W. Biederman
  2018-04-20 14:37   ` [REVIEW][PATCH 04/22] signal/hexagon: Use force_sig_fault as appropriate Eric W. Biederman
                     ` (18 subsequent siblings)
  21 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20 14:37 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, Eric W. Biederman, Mark Salter, Aurelien Jacquiot,
	linux-c6x-dev

Filling in struct siginfo before calling force_sig_info a tedious and
error prone process, where once in a great while the wrong fields
are filled out, and siginfo has been inconsistently cleared.

Simplify this process by using the helper force_sig_fault.  Which
takes as a parameters all of the information it needs, ensures
all of the fiddly bits of filling in struct siginfo are done properly
and then calls force_sig_info.

In short about a 5 line reduction in code for every time force_sig_info
is called, which makes the calling function clearer.

Cc: Mark Salter <msalter@redhat.com>
Cc: Aurelien Jacquiot <jacquiot.aurelien@gmail.com>
Cc: linux-c6x-dev@linux-c6x.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/c6x/kernel/traps.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/arch/c6x/kernel/traps.c b/arch/c6x/kernel/traps.c
index c5feee4542b0..5c60aea3b75a 100644
--- a/arch/c6x/kernel/traps.c
+++ b/arch/c6x/kernel/traps.c
@@ -244,9 +244,7 @@ static struct exception_info eexcept_table[128] = {
 static void do_trap(struct exception_info *except_info, struct pt_regs *regs)
 {
 	unsigned long addr = instruction_pointer(regs);
-	siginfo_t info;
 
-	clear_siginfo(&info);
 	if (except_info->code != TRAP_BRKPT)
 		pr_err("TRAP: %s PC[0x%lx] signo[%d] code[%d]\n",
 		       except_info->kernel_str, regs->pc,
@@ -254,12 +252,8 @@ static void do_trap(struct exception_info *except_info, struct pt_regs *regs)
 
 	die_if_kernel(except_info->kernel_str, regs, addr);
 
-	info.si_signo = except_info->signo;
-	info.si_errno = 0;
-	info.si_code  = except_info->code;
-	info.si_addr  = (void __user *)addr;
-
-	force_sig_info(except_info->signo, &info, current);
+	force_sig_fault(except_info->signo, except_info->code,
+			(void __user *)addr, current);
 }
 
 /*
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 04/22] signal/hexagon: Use force_sig_fault as appropriate
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
                     ` (2 preceding siblings ...)
  2018-04-20 14:37   ` [REVIEW][PATCH 03/22] signal/c6x: " Eric W. Biederman
@ 2018-04-20 14:37   ` Eric W. Biederman
  2018-04-20 14:37   ` [REVIEW][PATCH 05/22] signal/m68k: Use force_sig_fault where appropriate Eric W. Biederman
                     ` (17 subsequent siblings)
  21 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20 14:37 UTC (permalink / raw)
  To: linux-arch; +Cc: linux-kernel, Eric W. Biederman, Richard Kuo, linux-hexagon

Filling in struct siginfo before calling force_sig_info a tedious and
error prone process, where once in a great while the wrong fields
are filled out, and siginfo has been inconsistently cleared.

Simplify this process by using the helper force_sig_fault.  Which
takes as a parameters all of the information it needs, ensures
all of the fiddly bits of filling in struct siginfo are done properly
and then calls force_sig_info.

In short about a 5 line reduction in code for every time force_sig_info
is called, which makes the calling function clearer.

Cc: Richard Kuo <rkuo@codeaurora.org>
Cc: linux-hexagon@vger.kernel.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/hexagon/kernel/traps.c | 10 ++--------
 arch/hexagon/mm/vm_fault.c  | 21 +++++++--------------
 2 files changed, 9 insertions(+), 22 deletions(-)

diff --git a/arch/hexagon/kernel/traps.c b/arch/hexagon/kernel/traps.c
index 1ff6a6a7b97c..91ee04842c22 100644
--- a/arch/hexagon/kernel/traps.c
+++ b/arch/hexagon/kernel/traps.c
@@ -412,11 +412,6 @@ void do_trap0(struct pt_regs *regs)
 	case TRAP_DEBUG:
 		/* Trap0 0xdb is debug breakpoint */
 		if (user_mode(regs)) {
-			struct siginfo info;
-
-			clear_siginfo(&info);
-			info.si_signo = SIGTRAP;
-			info.si_errno = 0;
 			/*
 			 * Some architecures add some per-thread state
 			 * to distinguish between breakpoint traps and
@@ -424,9 +419,8 @@ void do_trap0(struct pt_regs *regs)
 			 * set the si_code value appropriately, or we
 			 * may want to use a different trap0 flavor.
 			 */
-			info.si_code = TRAP_BRKPT;
-			info.si_addr = (void __user *) pt_elr(regs);
-			force_sig_info(SIGTRAP, &info, current);
+			force_sig_fault(SIGTRAP, TRAP_BRKPT,
+					(void __user *) pt_elr(regs), current);
 		} else {
 #ifdef CONFIG_KGDB
 			kgdb_handle_exception(pt_cause(regs), SIGTRAP,
diff --git a/arch/hexagon/mm/vm_fault.c b/arch/hexagon/mm/vm_fault.c
index 2ad92edc877c..933bbcef5363 100644
--- a/arch/hexagon/mm/vm_fault.c
+++ b/arch/hexagon/mm/vm_fault.c
@@ -50,13 +50,12 @@ void do_page_fault(unsigned long address, long cause, struct pt_regs *regs)
 {
 	struct vm_area_struct *vma;
 	struct mm_struct *mm = current->mm;
-	siginfo_t info;
+	int si_signo;
 	int si_code = SEGV_MAPERR;
 	int fault;
 	const struct exception_table_entry *fixup;
 	unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
 
-	clear_siginfo(&info);
 	/*
 	 * If we're in an interrupt or have no user context,
 	 * then must not take the fault.
@@ -141,28 +140,22 @@ void do_page_fault(unsigned long address, long cause, struct pt_regs *regs)
 	 * unable to fix up the page fault.
 	 */
 	if (fault & VM_FAULT_SIGBUS) {
-		info.si_signo = SIGBUS;
-		info.si_code = BUS_ADRERR;
+		si_signo = SIGBUS;
+		si_code = BUS_ADRERR;
 	}
 	/* Address is not in the memory map */
 	else {
-		info.si_signo = SIGSEGV;
-		info.si_code = SEGV_ACCERR;
+		si_signo = SIGSEGV;
+		si_code  = SEGV_ACCERR;
 	}
-	info.si_errno = 0;
-	info.si_addr = (void __user *)address;
-	force_sig_info(info.si_signo, &info, current);
+	force_sig_fault(si_signo, si_code, (void __user *)address, current);
 	return;
 
 bad_area:
 	up_read(&mm->mmap_sem);
 
 	if (user_mode(regs)) {
-		info.si_signo = SIGSEGV;
-		info.si_errno = 0;
-		info.si_code = si_code;
-		info.si_addr = (void *)address;
-		force_sig_info(info.si_signo, &info, current);
+		force_sig_fault(SIGSEGV, si_code, (void __user *)address, current);
 		return;
 	}
 	/* Kernel-mode fault falls through */
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 05/22] signal/m68k: Use force_sig_fault where appropriate
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
                     ` (3 preceding siblings ...)
  2018-04-20 14:37   ` [REVIEW][PATCH 04/22] signal/hexagon: Use force_sig_fault as appropriate Eric W. Biederman
@ 2018-04-20 14:37   ` Eric W. Biederman
  2018-04-20 14:37   ` [REVIEW][PATCH 06/22] signal/microblaze: Remove the commented out force_sig_info in do_page_fault Eric W. Biederman
                     ` (16 subsequent siblings)
  21 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20 14:37 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, Eric W. Biederman, Geert Uytterhoeven, linux-m68k

Filling in struct siginfo before calling force_sig_info a tedious and
error prone process, where once in a great while the wrong fields
are filled out, and siginfo has been inconsistently cleared.

Simplify this process by using the helper force_sig_fault.  Which
takes as a parameters all of the information it needs, ensures
all of the fiddly bits of filling in struct siginfo are done properly
and then calls force_sig_info.

In short about a 5 line reduction in code for every time force_sig_info
is called, which makes the calling function clearer.

Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: linux-m68k@lists.linux-m68k.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/m68k/kernel/traps.c | 60 ++++++++++++++++++++----------------------------
 arch/m68k/mm/fault.c     | 25 +++++++++-----------
 2 files changed, 36 insertions(+), 49 deletions(-)

diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c
index 0a00b476236d..b2fd000b9285 100644
--- a/arch/m68k/kernel/traps.c
+++ b/arch/m68k/kernel/traps.c
@@ -1007,11 +1007,10 @@ void bad_super_trap (struct frame *fp)
 
 asmlinkage void trap_c(struct frame *fp)
 {
-	int sig;
+	int sig, si_code;
+	void __user *addr;
 	int vector = (fp->ptregs.vector >> 2) & 0xff;
-	siginfo_t info;
 
-	clear_siginfo(&info);
 	if (fp->ptregs.sr & PS_S) {
 		if (vector == VEC_TRACE) {
 			/* traced a trapping instruction on a 68020/30,
@@ -1030,21 +1029,21 @@ asmlinkage void trap_c(struct frame *fp)
 	/* send the appropriate signal to the user program */
 	switch (vector) {
 	    case VEC_ADDRERR:
-		info.si_code = BUS_ADRALN;
+		si_code = BUS_ADRALN;
 		sig = SIGBUS;
 		break;
 	    case VEC_ILLEGAL:
 	    case VEC_LINE10:
 	    case VEC_LINE11:
-		info.si_code = ILL_ILLOPC;
+		si_code = ILL_ILLOPC;
 		sig = SIGILL;
 		break;
 	    case VEC_PRIV:
-		info.si_code = ILL_PRVOPC;
+		si_code = ILL_PRVOPC;
 		sig = SIGILL;
 		break;
 	    case VEC_COPROC:
-		info.si_code = ILL_COPROC;
+		si_code = ILL_COPROC;
 		sig = SIGILL;
 		break;
 	    case VEC_TRAP1:
@@ -1061,76 +1060,74 @@ asmlinkage void trap_c(struct frame *fp)
 	    case VEC_TRAP12:
 	    case VEC_TRAP13:
 	    case VEC_TRAP14:
-		info.si_code = ILL_ILLTRP;
+		si_code = ILL_ILLTRP;
 		sig = SIGILL;
 		break;
 	    case VEC_FPBRUC:
 	    case VEC_FPOE:
 	    case VEC_FPNAN:
-		info.si_code = FPE_FLTINV;
+		si_code = FPE_FLTINV;
 		sig = SIGFPE;
 		break;
 	    case VEC_FPIR:
-		info.si_code = FPE_FLTRES;
+		si_code = FPE_FLTRES;
 		sig = SIGFPE;
 		break;
 	    case VEC_FPDIVZ:
-		info.si_code = FPE_FLTDIV;
+		si_code = FPE_FLTDIV;
 		sig = SIGFPE;
 		break;
 	    case VEC_FPUNDER:
-		info.si_code = FPE_FLTUND;
+		si_code = FPE_FLTUND;
 		sig = SIGFPE;
 		break;
 	    case VEC_FPOVER:
-		info.si_code = FPE_FLTOVF;
+		si_code = FPE_FLTOVF;
 		sig = SIGFPE;
 		break;
 	    case VEC_ZERODIV:
-		info.si_code = FPE_INTDIV;
+		si_code = FPE_INTDIV;
 		sig = SIGFPE;
 		break;
 	    case VEC_CHK:
 	    case VEC_TRAP:
-		info.si_code = FPE_INTOVF;
+		si_code = FPE_INTOVF;
 		sig = SIGFPE;
 		break;
 	    case VEC_TRACE:		/* ptrace single step */
-		info.si_code = TRAP_TRACE;
+		si_code = TRAP_TRACE;
 		sig = SIGTRAP;
 		break;
 	    case VEC_TRAP15:		/* breakpoint */
-		info.si_code = TRAP_BRKPT;
+		si_code = TRAP_BRKPT;
 		sig = SIGTRAP;
 		break;
 	    default:
-		info.si_code = ILL_ILLOPC;
+		si_code = ILL_ILLOPC;
 		sig = SIGILL;
 		break;
 	}
-	info.si_signo = sig;
-	info.si_errno = 0;
 	switch (fp->ptregs.format) {
 	    default:
-		info.si_addr = (void *) fp->ptregs.pc;
+		addr = (void __user *) fp->ptregs.pc;
 		break;
 	    case 2:
-		info.si_addr = (void *) fp->un.fmt2.iaddr;
+		addr = (void __user *) fp->un.fmt2.iaddr;
 		break;
 	    case 7:
-		info.si_addr = (void *) fp->un.fmt7.effaddr;
+		addr = (void __user *) fp->un.fmt7.effaddr;
 		break;
 	    case 9:
-		info.si_addr = (void *) fp->un.fmt9.iaddr;
+		addr = (void __user *) fp->un.fmt9.iaddr;
 		break;
 	    case 10:
-		info.si_addr = (void *) fp->un.fmta.daddr;
+		addr = (void __user *) fp->un.fmta.daddr;
 		break;
 	    case 11:
-		info.si_addr = (void *) fp->un.fmtb.daddr;
+		addr = (void __user*) fp->un.fmtb.daddr;
 		break;
 	}
-	force_sig_info (sig, &info, current);
+	force_sig_fault(sig, si_code, addr, current);
 }
 
 void die_if_kernel (char *str, struct pt_regs *fp, int nr)
@@ -1162,13 +1159,6 @@ asmlinkage void fpsp040_die(void)
 #ifdef CONFIG_M68KFPU_EMU
 asmlinkage void fpemu_signal(int signal, int code, void *addr)
 {
-	siginfo_t info;
-
-	clear_siginfo(&info);
-	info.si_signo = signal;
-	info.si_errno = 0;
-	info.si_code = code;
-	info.si_addr = addr;
-	force_sig_info(signal, &info, current);
+	force_sig_fault(signal, code, addr, current);
 }
 #endif
diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c
index 03253c4f8e6a..f2ff3779875a 100644
--- a/arch/m68k/mm/fault.c
+++ b/arch/m68k/mm/fault.c
@@ -21,35 +21,32 @@ extern void die_if_kernel(char *, struct pt_regs *, long);
 
 int send_fault_sig(struct pt_regs *regs)
 {
-	siginfo_t siginfo;
+	int signo, si_code;
+	void __user *addr;
 
-	clear_siginfo(&siginfo);
-	siginfo.si_signo = current->thread.signo;
-	siginfo.si_code = current->thread.code;
-	siginfo.si_addr = (void *)current->thread.faddr;
-	pr_debug("send_fault_sig: %p,%d,%d\n", siginfo.si_addr,
-		 siginfo.si_signo, siginfo.si_code);
+	signo = current->thread.signo;
+	si_code = current->thread.code;
+	addr = (void __user *)current->thread.faddr;
+	pr_debug("send_fault_sig: %p,%d,%d\n", addr, signo, si_code);
 
 	if (user_mode(regs)) {
-		force_sig_info(siginfo.si_signo,
-			       &siginfo, current);
+		force_sig_fault(signo, si_code, addr, current);
 	} else {
 		if (fixup_exception(regs))
 			return -1;
 
-		//if (siginfo.si_signo == SIGBUS)
-		//	force_sig_info(siginfo.si_signo,
-		//		       &siginfo, current);
+		//if (signo == SIGBUS)
+		//	force_sig_fault(si_signo, si_code, addr, current);
 
 		/*
 		 * Oops. The kernel tried to access some bad page. We'll have to
 		 * terminate things with extreme prejudice.
 		 */
-		if ((unsigned long)siginfo.si_addr < PAGE_SIZE)
+		if ((unsigned long)addr < PAGE_SIZE)
 			pr_alert("Unable to handle kernel NULL pointer dereference");
 		else
 			pr_alert("Unable to handle kernel access");
-		pr_cont(" at virtual address %p\n", siginfo.si_addr);
+		pr_cont(" at virtual address %p\n", addr);
 		die_if_kernel("Oops", regs, 0 /*error_code*/);
 		do_exit(SIGKILL);
 	}
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 06/22] signal/microblaze: Remove the commented out force_sig_info in do_page_fault
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
                     ` (4 preceding siblings ...)
  2018-04-20 14:37   ` [REVIEW][PATCH 05/22] signal/m68k: Use force_sig_fault where appropriate Eric W. Biederman
@ 2018-04-20 14:37   ` Eric W. Biederman
  2018-04-20 14:37   ` [REVIEW][PATCH 07/22] signal/microblaze: Use force_sig_fault where appropriate Eric W. Biederman
                     ` (15 subsequent siblings)
  21 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20 14:37 UTC (permalink / raw)
  To: linux-arch; +Cc: linux-kernel, Eric W. Biederman, Michal Simek

Remove the commented out call to force_sig_info right after a call to
_exception in do_page_fault.  The function _exception does exactly the
work the commented out code does so there is no reason for the
commented out code.

Cc: Michal Simek <monstr@monstr.eu>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/microblaze/mm/fault.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/arch/microblaze/mm/fault.c b/arch/microblaze/mm/fault.c
index 43d92167012a..1251d380df47 100644
--- a/arch/microblaze/mm/fault.c
+++ b/arch/microblaze/mm/fault.c
@@ -268,11 +268,6 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
 	/* User mode accesses cause a SIGSEGV */
 	if (user_mode(regs)) {
 		_exception(SIGSEGV, regs, code, address);
-/*		info.si_signo = SIGSEGV;
-		info.si_errno = 0;
-		info.si_code = code;
-		info.si_addr = (void *) address;
-		force_sig_info(SIGSEGV, &info, current);*/
 		return;
 	}
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 07/22] signal/microblaze: Use force_sig_fault where appropriate
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
                     ` (5 preceding siblings ...)
  2018-04-20 14:37   ` [REVIEW][PATCH 06/22] signal/microblaze: Remove the commented out force_sig_info in do_page_fault Eric W. Biederman
@ 2018-04-20 14:37   ` Eric W. Biederman
  2018-04-20 14:37   ` [REVIEW][PATCH 08/22] signal/mips: " Eric W. Biederman
                     ` (14 subsequent siblings)
  21 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20 14:37 UTC (permalink / raw)
  To: linux-arch; +Cc: linux-kernel, Eric W. Biederman, Michal Simek

Filling in struct siginfo before calling force_sig_info a tedious and
error prone process, where once in a great while the wrong fields
are filled out, and siginfo has been inconsistently cleared.

Simplify this process by using the helper force_sig_fault.  Which
takes as a parameters all of the information it needs, ensures
all of the fiddly bits of filling in struct siginfo are done properly
and then calls force_sig_info.

In short about a 5 line reduction in code for every time force_sig_info
is called, which makes the calling function clearer.

Cc: Michal Simek <monstr@monstr.eu>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/microblaze/kernel/exceptions.c | 9 +--------
 arch/microblaze/mm/fault.c          | 9 +--------
 2 files changed, 2 insertions(+), 16 deletions(-)

diff --git a/arch/microblaze/kernel/exceptions.c b/arch/microblaze/kernel/exceptions.c
index 443ec1feacb4..eafff21fcb0e 100644
--- a/arch/microblaze/kernel/exceptions.c
+++ b/arch/microblaze/kernel/exceptions.c
@@ -60,17 +60,10 @@ asmlinkage void sw_exception(struct pt_regs *regs)
 
 void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
 {
-	siginfo_t info;
-
 	if (kernel_mode(regs))
 		die("Exception in kernel mode", regs, signr);
 
-	clear_siginfo(&info);
-	info.si_signo = signr;
-	info.si_errno = 0;
-	info.si_code = code;
-	info.si_addr = (void __user *) addr;
-	force_sig_info(signr, &info, current);
+	force_sig_fault(signr, code, (void __user *)addr, current);
 }
 
 asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
diff --git a/arch/microblaze/mm/fault.c b/arch/microblaze/mm/fault.c
index 1251d380df47..af607447c683 100644
--- a/arch/microblaze/mm/fault.c
+++ b/arch/microblaze/mm/fault.c
@@ -289,14 +289,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
 do_sigbus:
 	up_read(&mm->mmap_sem);
 	if (user_mode(regs)) {
-		siginfo_t info;
-
-		clear_siginfo(&info);
-		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, current);
 		return;
 	}
 	bad_page_fault(regs, address, SIGBUS);
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 08/22] signal/mips: Use force_sig_fault where appropriate
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
                     ` (6 preceding siblings ...)
  2018-04-20 14:37   ` [REVIEW][PATCH 07/22] signal/microblaze: Use force_sig_fault where appropriate Eric W. Biederman
@ 2018-04-20 14:37   ` Eric W. Biederman
  2018-05-09 15:14     ` Matt Redfearn
  2018-04-20 14:37   ` [REVIEW][PATCH 09/22] signal/nds32: " Eric W. Biederman
                     ` (13 subsequent siblings)
  21 siblings, 1 reply; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20 14:37 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, Eric W. Biederman, Ralf Baechle, James Hogan, linux-mips

Filling in struct siginfo before calling force_sig_info a tedious and
error prone process, where once in a great while the wrong fields
are filled out, and siginfo has been inconsistently cleared.

Simplify this process by using the helper force_sig_fault.  Which
takes as a parameters all of the information it needs, ensures
all of the fiddly bits of filling in struct siginfo are done properly
and then calls force_sig_info.

In short about a 5 line reduction in code for every time force_sig_info
is called, which makes the calling function clearer.

Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: James Hogan <jhogan@kernel.org>
Cc: linux-mips@linux-mips.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/mips/kernel/traps.c | 65 ++++++++++++++----------------------------------
 arch/mips/mm/fault.c     | 19 ++++----------
 2 files changed, 23 insertions(+), 61 deletions(-)

diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 967e9e4e795e..66ec4b0b484d 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -699,17 +699,11 @@ 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;
-
-	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);
 
-	force_sig_info(SIGFPE, &info, current);
+	force_sig_fault(SIGFPE, FPE_INTOVF, (void __user *)regs->cp0_epc, current);
 	exception_exit(prev_state);
 }
 
@@ -722,32 +716,27 @@ 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;
-
-	clear_siginfo(&si);
-	si.si_addr = fault_addr;
-	si.si_signo = SIGFPE;
+	int si_code;
 
 	if (fcr31 & FPU_CSR_INV_X)
-		si.si_code = FPE_FLTINV;
+		si_code = FPE_FLTINV;
 	else if (fcr31 & FPU_CSR_DIV_X)
-		si.si_code = FPE_FLTDIV;
+		si_code = FPE_FLTDIV;
 	else if (fcr31 & FPU_CSR_OVF_X)
-		si.si_code = FPE_FLTOVF;
+		si_code = FPE_FLTOVF;
 	else if (fcr31 & FPU_CSR_UDF_X)
-		si.si_code = FPE_FLTUND;
+		si_code = FPE_FLTUND;
 	else if (fcr31 & FPU_CSR_INE_X)
-		si.si_code = FPE_FLTRES;
+		si_code = FPE_FLTRES;
 
-	force_sig_info(SIGFPE, &si, tsk);
+	force_sig_fault(SIGFPE, si_code, fault_addr, tsk);
 }
 
 int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcr31)
 {
-	struct siginfo si;
+	int si_code;
 	struct vm_area_struct *vma;
 
-	clear_siginfo(&si);
 	switch (sig) {
 	case 0:
 		return 0;
@@ -757,23 +746,18 @@ int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcr31)
 		return 1;
 
 	case SIGBUS:
-		si.si_addr = fault_addr;
-		si.si_signo = sig;
-		si.si_code = BUS_ADRERR;
-		force_sig_info(sig, &si, current);
+		force_sig_fault(SIGBUS, BUS_ADRERR, fault_addr, current);
 		return 1;
 
 	case SIGSEGV:
-		si.si_addr = fault_addr;
-		si.si_signo = sig;
 		down_read(&current->mm->mmap_sem);
 		vma = find_vma(current->mm, (unsigned long)fault_addr);
 		if (vma && (vma->vm_start <= (unsigned long)fault_addr))
-			si.si_code = SEGV_ACCERR;
+			si_code = SEGV_ACCERR;
 		else
-			si.si_code = SEGV_MAPERR;
+			si_code = SEGV_MAPERR;
 		up_read(&current->mm->mmap_sem);
-		force_sig_info(sig, &si, current);
+		force_sig_fault(SIGSEGV, si_code, fault_addr, current);
 		return 1;
 
 	default:
@@ -896,10 +880,8 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
 void do_trap_or_bp(struct pt_regs *regs, unsigned int code, int si_code,
 	const char *str)
 {
-	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)
@@ -921,13 +903,9 @@ void do_trap_or_bp(struct pt_regs *regs, unsigned int code, int si_code,
 	case BRK_DIVZERO:
 		scnprintf(b, sizeof(b), "%s instruction in kernel code", str);
 		die_if_kernel(b, regs);
-		if (code == BRK_DIVZERO)
-			info.si_code = FPE_INTDIV;
-		else
-			info.si_code = FPE_INTOVF;
-		info.si_signo = SIGFPE;
-		info.si_addr = (void __user *) regs->cp0_epc;
-		force_sig_info(SIGFPE, &info, current);
+		force_sig_fault(SIGFPE,
+				code == BRK_DIVZERO ? FPE_INTDIV : FPE_INTOVF,
+				(void __user *) regs->cp0_epc, current);
 		break;
 	case BRK_BUG:
 		die_if_kernel("Kernel bug detected", regs);
@@ -952,9 +930,7 @@ void do_trap_or_bp(struct pt_regs *regs, unsigned int code, int si_code,
 		scnprintf(b, sizeof(b), "%s instruction in kernel code", str);
 		die_if_kernel(b, regs);
 		if (si_code) {
-			info.si_signo = SIGTRAP;
-			info.si_code = si_code;
-			force_sig_info(SIGTRAP, &info, current);
+			force_sig_fault(SIGTRAP, si_code, NULL,	current);
 		} else {
 			force_sig(SIGTRAP, current);
 		}
@@ -1506,13 +1482,8 @@ asmlinkage void do_mdmx(struct pt_regs *regs)
  */
 asmlinkage void do_watch(struct pt_regs *regs)
 {
-	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
@@ -1528,7 +1499,7 @@ asmlinkage void do_watch(struct pt_regs *regs)
 	if (test_tsk_thread_flag(current, TIF_LOAD_WATCH)) {
 		mips_read_watch_registers();
 		local_irq_enable();
-		force_sig_info(SIGTRAP, &info, current);
+		force_sig_fault(SIGTRAP, TRAP_HWBKPT, NULL, current);
 	} else {
 		mips_clear_watch_registers();
 		local_irq_enable();
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index 75392becd933..5f71f2b903b7 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -42,7 +42,7 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
 	struct task_struct *tsk = current;
 	struct mm_struct *mm = tsk->mm;
 	const int field = sizeof(unsigned long) * 2;
-	siginfo_t info;
+	int si_code;
 	int fault;
 	unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
 
@@ -63,8 +63,7 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
 		return;
 #endif
 
-	clear_siginfo(&info);
-	info.si_code = SEGV_MAPERR;
+	si_code = SEGV_MAPERR;
 
 	/*
 	 * We fault-in kernel-space virtual memory on-demand. The
@@ -113,7 +112,7 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
  * we can handle it..
  */
 good_area:
-	info.si_code = SEGV_ACCERR;
+	si_code = SEGV_ACCERR;
 
 	if (write) {
 		if (!(vma->vm_flags & VM_WRITE))
@@ -224,11 +223,7 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
 			pr_cont("\n");
 		}
 		current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
-		info.si_signo = SIGSEGV;
-		info.si_errno = 0;
-		/* info.si_code has been set above */
-		info.si_addr = (void __user *) address;
-		force_sig_info(SIGSEGV, &info, tsk);
+		force_sig_fault(SIGSEGV, si_code, (void __user *)address, tsk);
 		return;
 	}
 
@@ -284,11 +279,7 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
 #endif
 	current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
 	tsk->thread.cp0_badvaddr = address;
-	info.si_signo = SIGBUS;
-	info.si_errno = 0;
-	info.si_code = BUS_ADRERR;
-	info.si_addr = (void __user *) address;
-	force_sig_info(SIGBUS, &info, tsk);
+	force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)address, tsk);
 
 	return;
 #ifndef CONFIG_64BIT
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 09/22] signal/nds32: Use force_sig_fault where appropriate
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
                     ` (7 preceding siblings ...)
  2018-04-20 14:37   ` [REVIEW][PATCH 08/22] signal/mips: " Eric W. Biederman
@ 2018-04-20 14:37   ` Eric W. Biederman
  2018-04-25 11:29     ` Vincent Chen
  2018-04-20 14:37   ` [REVIEW][PATCH 10/22] signal/nios2: " Eric W. Biederman
                     ` (12 subsequent siblings)
  21 siblings, 1 reply; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20 14:37 UTC (permalink / raw)
  To: linux-arch; +Cc: linux-kernel, Eric W. Biederman, Greentime Hu, Vincent Chen

Filling in struct siginfo before calling force_sig_info a tedious and
error prone process, where once in a great while the wrong fields
are filled out, and siginfo has been inconsistently cleared.

Simplify this process by using the helper force_sig_fault.  Which
takes as a parameters all of the information it needs, ensures
all of the fiddly bits of filling in struct siginfo are done properly
and then calls force_sig_info.

In short about a 5 line reduction in code for every time force_sig_info
is called, which makes the calling function clearer.

Cc: Greentime Hu <green.hu@gmail.com>
Cc: Vincent Chen <deanbo422@gmail.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/nds32/kernel/traps.c | 20 ++++----------------
 arch/nds32/mm/fault.c     | 19 +++++--------------
 2 files changed, 9 insertions(+), 30 deletions(-)

diff --git a/arch/nds32/kernel/traps.c b/arch/nds32/kernel/traps.c
index 46911768f4b5..636d1c7aa895 100644
--- a/arch/nds32/kernel/traps.c
+++ b/arch/nds32/kernel/traps.c
@@ -222,20 +222,13 @@ void die_if_kernel(const char *str, struct pt_regs *regs, int err)
 
 int bad_syscall(int n, struct pt_regs *regs)
 {
-	siginfo_t info;
-
 	if (current->personality != PER_LINUX) {
 		send_sig(SIGSEGV, current, 1);
 		return regs->uregs[0];
 	}
 
-	clear_siginfo(&info);
-	info.si_signo = SIGILL;
-	info.si_errno = 0;
-	info.si_code = ILL_ILLTRP;
-	info.si_addr = (void __user *)instruction_pointer(regs) - 4;
-
-	force_sig_info(SIGILL, &info, current);
+	force_sig_fault(SIGILL, ILL_ILLTRP,
+			(void __user *)instruction_pointer(regs) - 4, current);
 	die_if_kernel("Oops - bad syscall", regs, n);
 	return regs->uregs[0];
 }
@@ -288,16 +281,11 @@ void __init early_trap_init(void)
 void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
 		  int error_code, int si_code)
 {
-	struct siginfo info;
-
 	tsk->thread.trap_no = ENTRY_DEBUG_RELATED;
 	tsk->thread.error_code = error_code;
 
-	clear_siginfo(&info);
-	info.si_signo = SIGTRAP;
-	info.si_code = si_code;
-	info.si_addr = (void __user *)instruction_pointer(regs);
-	force_sig_info(SIGTRAP, &info, tsk);
+	force_sig_fault(SIGTRAP, si_code
+			(void __user *)instruction_pointer(regs), tsk);
 }
 
 void do_debug_trap(unsigned long entry, unsigned long addr,
diff --git a/arch/nds32/mm/fault.c b/arch/nds32/mm/fault.c
index 876ee01ff80a..9bdb7c3ecbb6 100644
--- a/arch/nds32/mm/fault.c
+++ b/arch/nds32/mm/fault.c
@@ -72,16 +72,15 @@ void do_page_fault(unsigned long entry, unsigned long addr,
 	struct task_struct *tsk;
 	struct mm_struct *mm;
 	struct vm_area_struct *vma;
-	siginfo_t info;
+	int si_code;
 	int fault;
 	unsigned int mask = VM_READ | VM_WRITE | VM_EXEC;
 	unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
 
-	clear_siginfo(&info);
 	error_code = error_code & (ITYPE_mskINST | ITYPE_mskETYPE);
 	tsk = current;
 	mm = tsk->mm;
-	info.si_code = SEGV_MAPERR;
+	si_code = SEGV_MAPERR;
 	/*
 	 * We fault-in kernel-space virtual memory on-demand. The
 	 * 'reference' page table is init_mm.pgd.
@@ -162,7 +161,7 @@ void do_page_fault(unsigned long entry, unsigned long addr,
 	 */
 
 good_area:
-	info.si_code = SEGV_ACCERR;
+	si_code = SEGV_ACCERR;
 
 	/* first do some preliminary protection checks */
 	if (entry == ENTRY_PTE_NOT_PRESENT) {
@@ -267,11 +266,7 @@ void do_page_fault(unsigned long entry, unsigned long addr,
 		tsk->thread.address = addr;
 		tsk->thread.error_code = error_code;
 		tsk->thread.trap_no = entry;
-		info.si_signo = SIGSEGV;
-		info.si_errno = 0;
-		/* info.si_code has been set above */
-		info.si_addr = (void *)addr;
-		force_sig_info(SIGSEGV, &info, tsk);
+		force_sig_fault(SIGSEGV, si_code, (void __user *)addr, tsk);
 		return;
 	}
 
@@ -340,11 +335,7 @@ void do_page_fault(unsigned long entry, unsigned long addr,
 	tsk->thread.address = addr;
 	tsk->thread.error_code = error_code;
 	tsk->thread.trap_no = entry;
-	info.si_signo = SIGBUS;
-	info.si_errno = 0;
-	info.si_code = BUS_ADRERR;
-	info.si_addr = (void *)addr;
-	force_sig_info(SIGBUS, &info, tsk);
+	force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)addr, tsk);
 
 	return;
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 10/22] signal/nios2: Use force_sig_fault where appropriate
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
                     ` (8 preceding siblings ...)
  2018-04-20 14:37   ` [REVIEW][PATCH 09/22] signal/nds32: " Eric W. Biederman
@ 2018-04-20 14:37   ` Eric W. Biederman
  2018-04-20 14:38   ` [REVIEW][PATCH 11/22] signal/openrisc: " Eric W. Biederman
                     ` (11 subsequent siblings)
  21 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20 14:37 UTC (permalink / raw)
  To: linux-arch; +Cc: linux-kernel, Eric W. Biederman, Ley Foon Tan, nios2-dev

Filling in struct siginfo before calling force_sig_info a tedious and
error prone process, where once in a great while the wrong fields
are filled out, and siginfo has been inconsistently cleared.

Simplify this process by using the helper force_sig_fault.  Which
takes as a parameters all of the information it needs, ensures
all of the fiddly bits of filling in struct siginfo are done properly
and then calls force_sig_info.

In short about a 5 line reduction in code for every time force_sig_info
is called, which makes the calling function clearer.

Cc: Ley Foon Tan <lftan@altera.com>
Cc: nios2-dev@lists.rocketboards.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/nios2/kernel/traps.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/arch/nios2/kernel/traps.c b/arch/nios2/kernel/traps.c
index a69861d3e1a3..3bc3cd22b750 100644
--- a/arch/nios2/kernel/traps.c
+++ b/arch/nios2/kernel/traps.c
@@ -26,14 +26,7 @@ static DEFINE_SPINLOCK(die_lock);
 
 static void _send_sig(int signo, int code, unsigned long addr)
 {
-	siginfo_t info;
-
-	clear_siginfo(&info);
-	info.si_signo = signo;
-	info.si_errno = 0;
-	info.si_code = code;
-	info.si_addr = (void __user *) addr;
-	force_sig_info(signo, &info, current);
+	force_sig_fault(signo, code, (void __user *) addr, current);
 }
 
 void die(const char *str, struct pt_regs *regs, long err)
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 11/22] signal/openrisc: Use force_sig_fault where appropriate
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
                     ` (9 preceding siblings ...)
  2018-04-20 14:37   ` [REVIEW][PATCH 10/22] signal/nios2: " Eric W. Biederman
@ 2018-04-20 14:38   ` Eric W. Biederman
  2018-04-20 14:38   ` [REVIEW][PATCH 12/22] signal/parisc: Use force_sig_mceerr " Eric W. Biederman
                     ` (10 subsequent siblings)
  21 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20 14:38 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, Eric W. Biederman, Jonas Bonn, Stefan Kristiansson,
	Stafford Horne, openrisc

Filling in struct siginfo before calling force_sig_info a tedious and
error prone process, where once in a great while the wrong fields
are filled out, and siginfo has been inconsistently cleared.

Simplify this process by using the helper force_sig_fault.  Which
takes as a parameters all of the information it needs, ensures
all of the fiddly bits of filling in struct siginfo are done properly
and then calls force_sig_info.

In short about a 5 line reduction in code for every time force_sig_info
is called, which makes the calling function clearer.

Cc: Jonas Bonn <jonas@southpole.se>
Cc: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
Cc: Stafford Horne <shorne@gmail.com>
Cc: openrisc@lists.librecores.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/openrisc/kernel/traps.c | 33 ++++-----------------------------
 arch/openrisc/mm/fault.c     | 19 +++++--------------
 2 files changed, 9 insertions(+), 43 deletions(-)

diff --git a/arch/openrisc/kernel/traps.c b/arch/openrisc/kernel/traps.c
index 1610b1d65a11..fac246e6f37a 100644
--- a/arch/openrisc/kernel/traps.c
+++ b/arch/openrisc/kernel/traps.c
@@ -250,28 +250,16 @@ void __init trap_init(void)
 
 asmlinkage void do_trap(struct pt_regs *regs, unsigned long address)
 {
-	siginfo_t info;
-	clear_siginfo(&info);
-	info.si_signo = SIGTRAP;
-	info.si_code = TRAP_TRACE;
-	info.si_addr = (void *)address;
-	force_sig_info(SIGTRAP, &info, current);
+	force_sig_fault(SIGTRAP, TRAP_TRACE, (void __user *)address, current);
 
 	regs->pc += 4;
 }
 
 asmlinkage void do_unaligned_access(struct pt_regs *regs, unsigned long address)
 {
-	siginfo_t info;
-
 	if (user_mode(regs)) {
 		/* Send a SIGBUS */
-		clear_siginfo(&info);
-		info.si_signo = SIGBUS;
-		info.si_errno = 0;
-		info.si_code = BUS_ADRALN;
-		info.si_addr = (void __user *)address;
-		force_sig_info(SIGBUS, &info, current);
+		force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)address, current);
 	} else {
 		printk("KERNEL: Unaligned Access 0x%.8lx\n", address);
 		show_registers(regs);
@@ -282,16 +270,9 @@ asmlinkage void do_unaligned_access(struct pt_regs *regs, unsigned long address)
 
 asmlinkage void do_bus_fault(struct pt_regs *regs, unsigned long address)
 {
-	siginfo_t info;
-
 	if (user_mode(regs)) {
 		/* Send a SIGBUS */
-		clear_siginfo(&info);
-		info.si_signo = SIGBUS;
-		info.si_errno = 0;
-		info.si_code = BUS_ADRERR;
-		info.si_addr = (void *)address;
-		force_sig_info(SIGBUS, &info, current);
+		force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)address, current);
 	} else {		/* Kernel mode */
 		printk("KERNEL: Bus error (SIGBUS) 0x%.8lx\n", address);
 		show_registers(regs);
@@ -466,7 +447,6 @@ static inline void simulate_swa(struct pt_regs *regs, unsigned long address,
 asmlinkage void do_illegal_instruction(struct pt_regs *regs,
 				       unsigned long address)
 {
-	siginfo_t info;
 	unsigned int op;
 	unsigned int insn = *((unsigned int *)address);
 
@@ -487,12 +467,7 @@ asmlinkage void do_illegal_instruction(struct pt_regs *regs,
 
 	if (user_mode(regs)) {
 		/* Send a SIGILL */
-		clear_siginfo(&info);
-		info.si_signo = SIGILL;
-		info.si_errno = 0;
-		info.si_code = ILL_ILLOPC;
-		info.si_addr = (void *)address;
-		force_sig_info(SIGBUS, &info, current);
+		force_sig_fault(SIGILL, ILL_ILLOPC, (void __user *)address, current);
 	} else {		/* Kernel mode */
 		printk("KERNEL: Illegal instruction (SIGILL) 0x%.8lx\n",
 		       address);
diff --git a/arch/openrisc/mm/fault.c b/arch/openrisc/mm/fault.c
index 68be33e4ae17..9f011d16cc46 100644
--- a/arch/openrisc/mm/fault.c
+++ b/arch/openrisc/mm/fault.c
@@ -52,11 +52,10 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long address,
 	struct task_struct *tsk;
 	struct mm_struct *mm;
 	struct vm_area_struct *vma;
-	siginfo_t info;
+	int si_code;
 	int fault;
 	unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
 
-	clear_siginfo(&info);
 	tsk = current;
 
 	/*
@@ -98,7 +97,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long address,
 	}
 
 	mm = tsk->mm;
-	info.si_code = SEGV_MAPERR;
+	si_code = SEGV_MAPERR;
 
 	/*
 	 * If we're in an interrupt or have no user
@@ -140,7 +139,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long address,
 	 */
 
 good_area:
-	info.si_code = SEGV_ACCERR;
+	si_code = SEGV_ACCERR;
 
 	/* first do some preliminary protection checks */
 
@@ -214,11 +213,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long address,
 	/* User mode accesses just cause a SIGSEGV */
 
 	if (user_mode(regs)) {
-		info.si_signo = SIGSEGV;
-		info.si_errno = 0;
-		/* info.si_code has been set above */
-		info.si_addr = (void *)address;
-		force_sig_info(SIGSEGV, &info, tsk);
+		force_sig_fault(SIGSEGV, si_code, (void __user *)address, tsk);
 		return;
 	}
 
@@ -283,11 +278,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long address,
 	 * 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 *)address;
-	force_sig_info(SIGBUS, &info, tsk);
+	force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)address, tsk);
 
 	/* Kernel mode? Handle exceptions or die */
 	if (!user_mode(regs))
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 12/22] signal/parisc: Use force_sig_mceerr where appropriate
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
                     ` (10 preceding siblings ...)
  2018-04-20 14:38   ` [REVIEW][PATCH 11/22] signal/openrisc: " Eric W. Biederman
@ 2018-04-20 14:38   ` Eric W. Biederman
  2018-04-20 14:38   ` [REVIEW][PATCH 13/22] signal/parisc: Use force_sig_fault " Eric W. Biederman
                     ` (9 subsequent siblings)
  21 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20 14:38 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, Eric W. Biederman, James Bottomley, Helge Deller,
	linux-parisc

In do_page_fault where an mceerr is generated stop and call force_sig_mceerr.
Keeping the mcerr handling logic out of the force_sig_info call below.

This ensures that only and always in the mcerr case is lsb interesting.

This ensures setting set si_lsb in the future won't accidentally
stomp another siginfo field in the non mcerr case.

Cc: James Bottomley <jejb@parisc-linux.org>
Cc: Helge Deller <deller@gmx.de>
Cc: linux-parisc@vger.kernel.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/parisc/mm/fault.c | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
index 657b35096bd8..51215b0048ef 100644
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c
@@ -354,7 +354,6 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
 
 	if (user_mode(regs)) {
 		struct siginfo si;
-		unsigned int lsb = 0;
 
 		clear_siginfo(&si);
 		switch (code) {
@@ -391,26 +390,27 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
 
 #ifdef CONFIG_MEMORY_FAILURE
 		if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) {
+			unsigned int lsb = 0;
 			printk(KERN_ERR
 	"MCE: Killing %s:%d due to hardware memory corruption fault at %08lx\n",
 			tsk->comm, tsk->pid, address);
-			si.si_signo = SIGBUS;
-			si.si_code = BUS_MCEERR_AR;
+			/*
+			 * Either small page or large page may be poisoned.
+			 * In other words, VM_FAULT_HWPOISON_LARGE and
+			 * VM_FAULT_HWPOISON are mutually exclusive.
+			 */
+			if (fault & VM_FAULT_HWPOISON_LARGE)
+				lsb = hstate_index_to_shift(VM_FAULT_GET_HINDEX(fault));
+			else if (fault & VM_FAULT_HWPOISON)
+				lsb = PAGE_SHIFT;
+
+			force_sig_mceerr(BUS_MCEERR_AR, (void __user *) address,
+					 lsb, current);
+			return;
 		}
 #endif
 
-		/*
-		 * Either small page or large page may be poisoned.
-		 * In other words, VM_FAULT_HWPOISON_LARGE and
-		 * VM_FAULT_HWPOISON are mutually exclusive.
-		 */
-		if (fault & VM_FAULT_HWPOISON_LARGE)
-			lsb = hstate_index_to_shift(VM_FAULT_GET_HINDEX(fault));
-		else if (fault & VM_FAULT_HWPOISON)
-			lsb = PAGE_SHIFT;
-		else
-			show_signal_msg(regs, code, address, tsk, vma);
-		si.si_addr_lsb = lsb;
+		show_signal_msg(regs, code, address, tsk, vma);
 
 		si.si_errno = 0;
 		si.si_addr = (void __user *) address;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 13/22] signal/parisc: Use force_sig_fault where appropriate
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
                     ` (11 preceding siblings ...)
  2018-04-20 14:38   ` [REVIEW][PATCH 12/22] signal/parisc: Use force_sig_mceerr " Eric W. Biederman
@ 2018-04-20 14:38   ` Eric W. Biederman
  2018-04-21 17:24     ` Helge Deller
  2018-04-20 14:38   ` [REVIEW][PATCH 14/22] signal/riscv: " Eric W. Biederman
                     ` (8 subsequent siblings)
  21 siblings, 1 reply; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20 14:38 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, Eric W. Biederman, James Bottomley, Helge Deller,
	linux-parisc

Filling in struct siginfo before calling force_sig_info a tedious and
error prone process, where once in a great while the wrong fields
are filled out, and siginfo has been inconsistently cleared.

Simplify this process by using the helper force_sig_fault.  Which
takes as a parameters all of the information it needs, ensures
all of the fiddly bits of filling in struct siginfo are done properly
and then calls force_sig_info.

In short about a 5 line reduction in code for every time force_sig_info
is called, which makes the calling function clearer.

Cc: James Bottomley <jejb@parisc-linux.org>
Cc: Helge Deller <deller@gmx.de>
Cc: linux-parisc@vger.kernel.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/parisc/kernel/ptrace.c    | 11 ++------
 arch/parisc/kernel/traps.c     | 63 ++++++++++++++----------------------------
 arch/parisc/kernel/unaligned.c | 16 +++--------
 arch/parisc/math-emu/driver.c  |  9 ++----
 arch/parisc/mm/fault.c         | 25 +++++++----------
 5 files changed, 39 insertions(+), 85 deletions(-)

diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index b1c12ceb1c88..7aa1d4d0d444 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -76,8 +76,6 @@ void user_enable_single_step(struct task_struct *task)
 	set_tsk_thread_flag(task, TIF_SINGLESTEP);
 
 	if (pa_psw(task)->n) {
-		struct siginfo si;
-
 		/* Nullified, just crank over the queue. */
 		task_regs(task)->iaoq[0] = task_regs(task)->iaoq[1];
 		task_regs(task)->iasq[0] = task_regs(task)->iasq[1];
@@ -90,12 +88,9 @@ void user_enable_single_step(struct task_struct *task)
 		ptrace_disable(task);
 		/* Don't wake up the task, but let the
 		   parent know something happened. */
-		clear_siginfo(&si);
-		si.si_code = TRAP_TRACE;
-		si.si_addr = (void __user *) (task_regs(task)->iaoq[0] & ~3);
-		si.si_signo = SIGTRAP;
-		si.si_errno = 0;
-		force_sig_info(SIGTRAP, &si, task);
+		force_sig_fault(SIGTRAP, TRAP_TRACE,
+				(void __user *) (task_regs(task)->iaoq[0] & ~3),
+				task);
 		/* notify_parent(task, SIGCHLD); */
 		return;
 	}
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index 98f9f2f85940..132b09c657ff 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -297,14 +297,8 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err)
 #define GDB_BREAK_INSN 0x10004
 static void handle_gdb_break(struct pt_regs *regs, int wot)
 {
-	struct siginfo si;
-
-	clear_siginfo(&si);
-	si.si_signo = SIGTRAP;
-	si.si_errno = 0;
-	si.si_code = wot;
-	si.si_addr = (void __user *) (regs->iaoq[0] & ~3);
-	force_sig_info(SIGTRAP, &si, current);
+	force_sig_fault(SIGTRAP, wot,
+			(void __user *) (regs->iaoq[0] & ~3), current);
 }
 
 static void handle_break(struct pt_regs *regs)
@@ -488,9 +482,8 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
 {
 	unsigned long fault_address = 0;
 	unsigned long fault_space = 0;
-	struct siginfo si;
+	int si_code;
 
-	clear_siginfo(&si);
 	if (code == 1)
 	    pdc_console_restart();  /* switch back to pdc if HPMC */
 	else
@@ -573,7 +566,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
 	case  8:
 		/* Illegal instruction trap */
 		die_if_kernel("Illegal instruction", regs, code);
-		si.si_code = ILL_ILLOPC;
+		si_code = ILL_ILLOPC;
 		goto give_sigill;
 
 	case  9:
@@ -584,7 +577,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
 	case 10:
 		/* Privileged operation trap */
 		die_if_kernel("Privileged operation", regs, code);
-		si.si_code = ILL_PRVOPC;
+		si_code = ILL_PRVOPC;
 		goto give_sigill;
 
 	case 11:
@@ -607,20 +600,16 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
 		}
 
 		die_if_kernel("Privileged register usage", regs, code);
-		si.si_code = ILL_PRVREG;
+		si_code = ILL_PRVREG;
 	give_sigill:
-		si.si_signo = SIGILL;
-		si.si_errno = 0;
-		si.si_addr = (void __user *) regs->iaoq[0];
-		force_sig_info(SIGILL, &si, current);
+		force_sig_fault(SIGILL, si_code,
+				(void __user *) regs->iaoq[0], current);
 		return;
 
 	case 12:
 		/* Overflow Trap, let the userland signal handler do the cleanup */
-		si.si_signo = SIGFPE;
-		si.si_code = FPE_INTOVF;
-		si.si_addr = (void __user *) regs->iaoq[0];
-		force_sig_info(SIGFPE, &si, current);
+		force_sig_fault(SIGFPE, FPE_INTOVF,
+				(void __user *) regs->iaoq[0], current);
 		return;
 		
 	case 13:
@@ -628,13 +617,11 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
 		   The condition succeeds in an instruction which traps
 		   on condition  */
 		if(user_mode(regs)){
-			si.si_signo = SIGFPE;
 			/* Let userspace app figure it out from the insn pointed
 			 * to by si_addr.
 			 */
-			si.si_code = FPE_CONDTRAP;
-			si.si_addr = (void __user *) regs->iaoq[0];
-			force_sig_info(SIGFPE, &si, current);
+			force_sig_fault(SIGFPE, FPE_CONDTRAP,
+					(void __user *) regs->iaoq[0], current);
 			return;
 		} 
 		/* The kernel doesn't want to handle condition codes */
@@ -743,14 +730,10 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
 			return;
 
 		die_if_kernel("Protection id trap", regs, code);
-		si.si_code = SEGV_MAPERR;
-		si.si_signo = SIGSEGV;
-		si.si_errno = 0;
-		if (code == 7)
-		    si.si_addr = (void __user *) regs->iaoq[0];
-		else
-		    si.si_addr = (void __user *) regs->ior;
-		force_sig_info(SIGSEGV, &si, current);
+		force_sig_fault(SIGSEGV, SEGV_MAPERR,
+				(code == 7)?
+				((void __user *) regs->iaoq[0]) :
+				((void __user *) regs->ior), current);
 		return;
 
 	case 28: 
@@ -764,11 +747,8 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
 				"handle_interruption() pid=%d command='%s'\n",
 				task_pid_nr(current), current->comm);
 			/* SIGBUS, for lack of a better one. */
-			si.si_signo = SIGBUS;
-			si.si_code = BUS_OBJERR;
-			si.si_errno = 0;
-			si.si_addr = (void __user *) regs->ior;
-			force_sig_info(SIGBUS, &si, current);
+			force_sig_fault(SIGBUS, BUS_OBJERR,
+					(void __user *)regs->ior, current);
 			return;
 		}
 		pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
@@ -783,11 +763,8 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
 				"User fault %d on space 0x%08lx, pid=%d command='%s'\n",
 				code, fault_space,
 				task_pid_nr(current), current->comm);
-		si.si_signo = SIGSEGV;
-		si.si_errno = 0;
-		si.si_code = SEGV_MAPERR;
-		si.si_addr = (void __user *) regs->ior;
-		force_sig_info(SIGSEGV, &si, current);
+		force_sig_fault(SIGSEGV, SEGV_MAPERR,
+				(void __user *)regs->ior, current);
 		return;
 	    }
 	}
diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c
index 30b7c7f6c471..932bfc0b7cd8 100644
--- a/arch/parisc/kernel/unaligned.c
+++ b/arch/parisc/kernel/unaligned.c
@@ -452,10 +452,8 @@ void handle_unaligned(struct pt_regs *regs)
 	unsigned long newbase = R1(regs->iir)?regs->gr[R1(regs->iir)]:0;
 	int modify = 0;
 	int ret = ERR_NOTHANDLED;
-	struct siginfo si;
 	register int flop=0;	/* true if this is a flop */
 
-	clear_siginfo(&si);
 	__inc_irq_stat(irq_unaligned_count);
 
 	/* log a message with pacing */
@@ -691,21 +689,15 @@ void handle_unaligned(struct pt_regs *regs)
 
 		if (ret == ERR_PAGEFAULT)
 		{
-			si.si_signo = SIGSEGV;
-			si.si_errno = 0;
-			si.si_code = SEGV_MAPERR;
-			si.si_addr = (void __user *)regs->ior;
-			force_sig_info(SIGSEGV, &si, current);
+			force_sig_fault(SIGSEGV, SEGV_MAPERR,
+					(void __user *)regs->ior, current);
 		}
 		else
 		{
 force_sigbus:
 			/* couldn't handle it ... */
-			si.si_signo = SIGBUS;
-			si.si_errno = 0;
-			si.si_code = BUS_ADRALN;
-			si.si_addr = (void __user *)regs->ior;
-			force_sig_info(SIGBUS, &si, current);
+			force_sig_fault(SIGBUS, BUS_ADRALN,
+					(void __user *)regs->ior, current);
 		}
 		
 		return;
diff --git a/arch/parisc/math-emu/driver.c b/arch/parisc/math-emu/driver.c
index 0d10efb53361..0590e05571d1 100644
--- a/arch/parisc/math-emu/driver.c
+++ b/arch/parisc/math-emu/driver.c
@@ -81,7 +81,6 @@ int
 handle_fpe(struct pt_regs *regs)
 {
 	extern void printbinary(unsigned long x, int nbits);
-	struct siginfo si;
 	unsigned int orig_sw, sw;
 	int signalcode;
 	/* need an intermediate copy of float regs because FPU emulation
@@ -93,7 +92,6 @@ handle_fpe(struct pt_regs *regs)
 	 */
 	__u64 frcopy[36];
 
-	clear_siginfo(&si);
 	memcpy(frcopy, regs->fr, sizeof regs->fr);
 	frcopy[32] = 0;
 
@@ -118,11 +116,8 @@ handle_fpe(struct pt_regs *regs)
 
 	memcpy(regs->fr, frcopy, sizeof regs->fr);
 	if (signalcode != 0) {
-	    si.si_signo = signalcode >> 24;
-	    si.si_errno = 0;
-	    si.si_code = signalcode & 0xffffff;
-	    si.si_addr = (void __user *) regs->iaoq[0];
-	    force_sig_info(si.si_signo, &si, current);
+	    force_sig_fault(signalcode >> 24, signalcode & 0xffffff,
+			    (void __user *) regs->iaoq[0], current);
 	    return -1;
 	}
 
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
index 51215b0048ef..a80117980fc2 100644
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c
@@ -353,23 +353,22 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
 	up_read(&mm->mmap_sem);
 
 	if (user_mode(regs)) {
-		struct siginfo si;
+		int signo, si_code;
 
-		clear_siginfo(&si);
 		switch (code) {
 		case 15:	/* Data TLB miss fault/Data page fault */
 			/* send SIGSEGV when outside of vma */
 			if (!vma ||
 			    address < vma->vm_start || address >= vma->vm_end) {
-				si.si_signo = SIGSEGV;
-				si.si_code = SEGV_MAPERR;
+				signo = SIGSEGV;
+				si_code = SEGV_MAPERR;
 				break;
 			}
 
 			/* send SIGSEGV for wrong permissions */
 			if ((vma->vm_flags & acc_type) != acc_type) {
-				si.si_signo = SIGSEGV;
-				si.si_code = SEGV_ACCERR;
+				signo = SIGSEGV;
+				si_code = SEGV_ACCERR;
 				break;
 			}
 
@@ -377,17 +376,16 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
 			/* fall through */
 		case 17:	/* NA data TLB miss / page fault */
 		case 18:	/* Unaligned access - PCXS only */
-			si.si_signo = SIGBUS;
-			si.si_code = (code == 18) ? BUS_ADRALN : BUS_ADRERR;
+			signo = SIGBUS;
+			si_code = (code == 18) ? BUS_ADRALN : BUS_ADRERR;
 			break;
 		case 16:	/* Non-access instruction TLB miss fault */
 		case 26:	/* PCXL: Data memory access rights trap */
 		default:
-			si.si_signo = SIGSEGV;
-			si.si_code = (code == 26) ? SEGV_ACCERR : SEGV_MAPERR;
+			signo = SIGSEGV;
+			si_code = (code == 26) ? SEGV_ACCERR : SEGV_MAPERR;
 			break;
 		}
-
 #ifdef CONFIG_MEMORY_FAILURE
 		if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) {
 			unsigned int lsb = 0;
@@ -409,12 +407,9 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
 			return;
 		}
 #endif
-
 		show_signal_msg(regs, code, address, tsk, vma);
 
-		si.si_errno = 0;
-		si.si_addr = (void __user *) address;
-		force_sig_info(si.si_signo, &si, current);
+		force_sig_fault(signo, si_code, (void __user *) address, current);
 		return;
 	}
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 14/22] signal/riscv: Use force_sig_fault where appropriate
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
                     ` (12 preceding siblings ...)
  2018-04-20 14:38   ` [REVIEW][PATCH 13/22] signal/parisc: Use force_sig_fault " Eric W. Biederman
@ 2018-04-20 14:38   ` Eric W. Biederman
  2018-04-21  7:25     ` Christoph Hellwig
  2018-04-23 19:11     ` [REVIEW][PATCH 14/22] signal/riscv: Use force_sig_fault where appropriate Palmer Dabbelt
  2018-04-20 14:38   ` [REVIEW][PATCH 15/22] signal/s390: " Eric W. Biederman
                     ` (7 subsequent siblings)
  21 siblings, 2 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20 14:38 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, Eric W. Biederman, Palmer Dabbelt, Albert Ou, linux-riscv

Filling in struct siginfo before calling force_sig_info a tedious and
error prone process, where once in a great while the wrong fields
are filled out, and siginfo has been inconsistently cleared.

Simplify this process by using the helper force_sig_fault.  Which
takes as a parameters all of the information it needs, ensures
all of the fiddly bits of filling in struct siginfo are done properly
and then calls force_sig_info.

In short about a 5 line reduction in code for every time force_sig_info
is called, which makes the calling function clearer.

Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Albert Ou <albert@sifive.com>
Cc: linux-riscv@lists.infradead.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/riscv/kernel/traps.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 48aa6471cede..3087940008f4 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -66,14 +66,7 @@ void die(struct pt_regs *regs, const char *str)
 static inline void do_trap_siginfo(int signo, int code,
 	unsigned long addr, struct task_struct *tsk)
 {
-	siginfo_t info;
-
-	clear_siginfo(&info);
-	info.si_signo = signo;
-	info.si_errno = 0;
-	info.si_code = code;
-	info.si_addr = (void __user *)addr;
-	force_sig_info(signo, &info, tsk);
+	force_sig_fault(signo, code, (void __user *)addr, tsk);
 }
 
 void do_trap(struct pt_regs *regs, int signo, int code,
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 15/22] signal/s390: Use force_sig_fault where appropriate
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
                     ` (13 preceding siblings ...)
  2018-04-20 14:38   ` [REVIEW][PATCH 14/22] signal/riscv: " Eric W. Biederman
@ 2018-04-20 14:38   ` Eric W. Biederman
  2018-04-23  5:44     ` Martin Schwidefsky
  2018-04-20 14:38   ` [REVIEW][PATCH 16/22] signal/sh: " Eric W. Biederman
                     ` (6 subsequent siblings)
  21 siblings, 1 reply; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20 14:38 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, Eric W. Biederman, Martin Schwidefsky,
	Heiko Carstens, linux-s390

Filling in struct siginfo before calling force_sig_info a tedious and
error prone process, where once in a great while the wrong fields
are filled out, and siginfo has been inconsistently cleared.

Simplify this process by using the helper force_sig_fault.  Which
takes as a parameters all of the information it needs, ensures
all of the fiddly bits of filling in struct siginfo are done properly
and then calls force_sig_info.

In short about a 5 line reduction in code for every time force_sig_info
is called, which makes the calling function clearer.

Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: linux-s390@vger.kernel.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/s390/kernel/traps.c | 32 ++++++--------------------------
 arch/s390/mm/fault.c     | 23 ++++++-----------------
 2 files changed, 12 insertions(+), 43 deletions(-)

diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 3ba649d8aa5a..8003b38c1688 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -44,15 +44,8 @@ int is_valid_bugaddr(unsigned long addr)
 
 void do_report_trap(struct pt_regs *regs, int si_signo, int si_code, char *str)
 {
-	siginfo_t info;
-
 	if (user_mode(regs)) {
-		clear_siginfo(&info);
-		info.si_signo = si_signo;
-		info.si_errno = 0;
-		info.si_code = si_code;
-		info.si_addr = get_trap_ip(regs);
-		force_sig_info(si_signo, &info, current);
+		force_sig_fault(si_signo, si_code, get_trap_ip(regs), current);
 		report_user_fault(regs, si_signo, 0);
         } else {
                 const struct exception_table_entry *fixup;
@@ -81,19 +74,12 @@ NOKPROBE_SYMBOL(do_trap);
 
 void do_per_trap(struct pt_regs *regs)
 {
-	siginfo_t info;
-
 	if (notify_die(DIE_SSTEP, "sstep", regs, 0, 0, SIGTRAP) == NOTIFY_STOP)
 		return;
 	if (!current->ptrace)
 		return;
-	clear_siginfo(&info);
-	info.si_signo = SIGTRAP;
-	info.si_errno = 0;
-	info.si_code = TRAP_HWBKPT;
-	info.si_addr =
-		(void __force __user *) current->thread.per_event.address;
-	force_sig_info(SIGTRAP, &info, current);
+	force_sig_fault(SIGTRAP, TRAP_HWBKPT,
+		(void __force __user *) current->thread.per_event.address, current);
 }
 NOKPROBE_SYMBOL(do_per_trap);
 
@@ -178,15 +164,9 @@ void illegal_op(struct pt_regs *regs)
 		if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
 			return;
 		if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) {
-			if (current->ptrace) {
-				siginfo_t info;
-				clear_siginfo(&info);
-				info.si_signo = SIGTRAP;
-				info.si_errno = 0;
-				info.si_code = TRAP_BRKPT;
-				info.si_addr = location;
-				force_sig_info(SIGTRAP, &info, current);
-			} else
+			if (current->ptrace)
+				force_sig_fault(SIGTRAP, TRAP_BRKPT, location, current);
+			else
 				signal = SIGILL;
 #ifdef CONFIG_UPROBES
 		} else if (*((__u16 *) opcode) == UPROBE_SWBP_INSN) {
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index b3ff0e8e5860..e074480d3598 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -265,15 +265,10 @@ void report_user_fault(struct pt_regs *regs, long signr, int is_mm_fault)
  */
 static noinline void do_sigsegv(struct pt_regs *regs, int si_code)
 {
-	struct siginfo si;
-
 	report_user_fault(regs, SIGSEGV, 1);
-	clear_siginfo(&si);
-	si.si_signo = SIGSEGV;
-	si.si_errno = 0;
-	si.si_code = si_code;
-	si.si_addr = (void __user *)(regs->int_parm_long & __FAIL_ADDR_MASK);
-	force_sig_info(SIGSEGV, &si, current);
+	force_sig_fault(SIGSEGV, si_code,
+			(void __user *)(regs->int_parm_long & __FAIL_ADDR_MASK),
+			current);
 }
 
 static noinline void do_no_context(struct pt_regs *regs)
@@ -317,19 +312,13 @@ static noinline void do_low_address(struct pt_regs *regs)
 
 static noinline void do_sigbus(struct pt_regs *regs)
 {
-	struct task_struct *tsk = current;
-	struct siginfo si;
-
 	/*
 	 * Send a sigbus, regardless of whether we were in kernel
 	 * or user mode.
 	 */
-	clear_siginfo(&si);
-	si.si_signo = SIGBUS;
-	si.si_errno = 0;
-	si.si_code = BUS_ADRERR;
-	si.si_addr = (void __user *)(regs->int_parm_long & __FAIL_ADDR_MASK);
-	force_sig_info(SIGBUS, &si, tsk);
+	force_sig_fault(SIGBUS, BUS_ADRERR,
+			(void __user *)(regs->int_parm_long & __FAIL_ADDR_MASK),
+			current);
 }
 
 static noinline int signal_return(struct pt_regs *regs)
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 16/22] signal/sh: Use force_sig_fault where appropriate
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
                     ` (14 preceding siblings ...)
  2018-04-20 14:38   ` [REVIEW][PATCH 15/22] signal/s390: " Eric W. Biederman
@ 2018-04-20 14:38   ` Eric W. Biederman
  2018-04-20 14:55     ` Rich Felker
  2018-04-20 14:38   ` [REVIEW][PATCH 17/22] signal/sparc: Use send_sig_fault where appropriate Eric W. Biederman
                     ` (5 subsequent siblings)
  21 siblings, 1 reply; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20 14:38 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, Eric W. Biederman, Yoshinori Sato, Rich Felker, linux-sh

Filling in struct siginfo before calling force_sig_info a tedious and
error prone process, where once in a great while the wrong fields
are filled out, and siginfo has been inconsistently cleared.

Simplify this process by using the helper force_sig_fault.  Which
takes as a parameters all of the information it needs, ensures
all of the fiddly bits of filling in struct siginfo are done properly
and then calls force_sig_info.

In short about a 5 line reduction in code for every time force_sig_info
is called, which makes the calling function clearer.

Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: Rich Felker <dalias@libc.org>
Cc: linux-sh@vger.kernel.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/sh/kernel/traps_32.c | 19 +++++--------------
 arch/sh/math-emu/math.c   |  9 ++-------
 arch/sh/mm/fault.c        | 10 +---------
 3 files changed, 8 insertions(+), 30 deletions(-)

diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index e85e59c3d6df..660a4bc17698 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -477,7 +477,6 @@ asmlinkage void do_address_error(struct pt_regs *regs,
 {
 	unsigned long error_code = 0;
 	mm_segment_t oldfs;
-	siginfo_t info;
 	insn_size_t instruction;
 	int tmp;
 
@@ -537,12 +536,7 @@ asmlinkage void do_address_error(struct pt_regs *regs,
 		       "access (PC %lx PR %lx)\n", current->comm, regs->pc,
 		       regs->pr);
 
-		clear_siginfo(&info);
-		info.si_signo = SIGBUS;
-		info.si_errno = 0;
-		info.si_code = si_code;
-		info.si_addr = (void __user *)address;
-		force_sig_info(SIGBUS, &info, current);
+		force_sig_fault(SIGBUS, si_code, (void __user *)address, current);
 	} else {
 		inc_unaligned_kernel_access();
 
@@ -599,20 +593,17 @@ int is_dsp_inst(struct pt_regs *regs)
 #ifdef CONFIG_CPU_SH2A
 asmlinkage void do_divide_error(unsigned long r4)
 {
-	siginfo_t info;
+	int code;
 
-	clear_siginfo(&info);
 	switch (r4) {
 	case TRAP_DIVZERO_ERROR:
-		info.si_code = FPE_INTDIV;
+		code = FPE_INTDIV;
 		break;
 	case TRAP_DIVOVF_ERROR:
-		info.si_code = FPE_INTOVF;
+		code = FPE_INTOVF;
 		break;
 	}
-
-	info.si_signo = SIGFPE;
-	force_sig_info(info.si_signo, &info, current);
+	force_sig_fault(SIGFPE, code, NULL, current);
 }
 #endif
 
diff --git a/arch/sh/math-emu/math.c b/arch/sh/math-emu/math.c
index d6d2213df078..a0fa8fc88739 100644
--- a/arch/sh/math-emu/math.c
+++ b/arch/sh/math-emu/math.c
@@ -507,7 +507,6 @@ static int ieee_fpe_handler(struct pt_regs *regs)
 	unsigned short insn = *(unsigned short *)regs->pc;
 	unsigned short finsn;
 	unsigned long nextpc;
-	siginfo_t info;
 	int nib[4] = {
 		(insn >> 12) & 0xf,
 		(insn >> 8) & 0xf,
@@ -560,12 +559,8 @@ static int ieee_fpe_handler(struct pt_regs *regs)
 				~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK);
 			task_thread_info(tsk)->status |= TS_USEDFPU;
 		} else {
-			clear_siginfo(&info);
-			info.si_signo = SIGFPE;
-			info.si_errno = 0;
-			info.si_code = FPE_FLTINV;
-			info.si_addr = (void __user *)regs->pc;
-			force_sig_info(SIGFPE, &info, tsk);
+			force_sig_fault(SIGFPE, FPE_FLTINV,
+					(void __user *)regs->pc, tsk);
 		}
 
 		regs->pc = nextpc;
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index 4c98b6f20e02..b8e7bb84b6b1 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -42,15 +42,7 @@ static void
 force_sig_info_fault(int si_signo, int si_code, unsigned long address,
 		     struct task_struct *tsk)
 {
-	siginfo_t info;
-
-	clear_siginfo(&info);
-	info.si_signo	= si_signo;
-	info.si_errno	= 0;
-	info.si_code	= si_code;
-	info.si_addr	= (void __user *)address;
-
-	force_sig_info(si_signo, &info, tsk);
+	force_sig_fault(si_signo, si_code, (void __user *)address, tsk);
 }
 
 /*
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 17/22] signal/sparc: Use send_sig_fault where appropriate
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
                     ` (15 preceding siblings ...)
  2018-04-20 14:38   ` [REVIEW][PATCH 16/22] signal/sh: " Eric W. Biederman
@ 2018-04-20 14:38   ` Eric W. Biederman
  2018-04-20 14:38   ` [REVIEW][PATCH 18/22] signal/sparc: Use force_sig_fault " Eric W. Biederman
                     ` (4 subsequent siblings)
  21 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20 14:38 UTC (permalink / raw)
  To: linux-arch; +Cc: linux-kernel, Eric W. Biederman, David Miller, sparclinux

Filling in struct siginfo before calling send_sig_info a tedious and
error prone process, where once in a great while the wrong fields
are filled out, and siginfo has been inconsistently cleared.

Simplify this process by using the helper send_sig_fault.  Which
takes as a parameters all of the information it needs, ensures
all of the fiddly bits of filling in struct siginfo are done properly
and then calls send_sig_info.

In short about a 5 line reduction in code for every time send_sig_info
is called, which makes the calling function clearer.

Cc: David Miller <davem@davemloft.net>
Cc: sparclinux@vger.kernel.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/sparc/kernel/traps_32.c     | 93 ++++++++--------------------------------
 arch/sparc/kernel/unaligned_32.c | 12 ++----
 2 files changed, 20 insertions(+), 85 deletions(-)

diff --git a/arch/sparc/kernel/traps_32.c b/arch/sparc/kernel/traps_32.c
index 03e522274b8b..06f43cf9695f 100644
--- a/arch/sparc/kernel/traps_32.c
+++ b/arch/sparc/kernel/traps_32.c
@@ -116,8 +116,6 @@ void do_hw_interrupt(struct pt_regs *regs, unsigned long type)
 void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned long npc,
 			    unsigned long psr)
 {
-	siginfo_t info;
-
 	if(psr & PSR_PS)
 		die_if_kernel("Kernel illegal instruction", regs);
 #ifdef TRAP_DEBUG
@@ -125,29 +123,15 @@ void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned lon
 	       regs->pc, *(unsigned long *)regs->pc);
 #endif
 
-	clear_siginfo(&info);
-	info.si_signo = SIGILL;
-	info.si_errno = 0;
-	info.si_code = ILL_ILLOPC;
-	info.si_addr = (void __user *)pc;
-	info.si_trapno = 0;
-	send_sig_info(SIGILL, &info, current);
+	send_sig_fault(SIGILL, ILL_ILLOPC, (void __user *)pc, 0, current);
 }
 
 void do_priv_instruction(struct pt_regs *regs, unsigned long pc, unsigned long npc,
 			 unsigned long psr)
 {
-	siginfo_t info;
-
 	if(psr & PSR_PS)
 		die_if_kernel("Penguin instruction from Penguin mode??!?!", regs);
-	clear_siginfo(&info);
-	info.si_signo = SIGILL;
-	info.si_errno = 0;
-	info.si_code = ILL_PRVOPC;
-	info.si_addr = (void __user *)pc;
-	info.si_trapno = 0;
-	send_sig_info(SIGILL, &info, current);
+	send_sig_fault(SIGILL, ILL_PRVOPC, (void __user *)pc, 0, current);
 }
 
 /* XXX User may want to be allowed to do this. XXX */
@@ -155,8 +139,6 @@ void do_priv_instruction(struct pt_regs *regs, unsigned long pc, unsigned long n
 void do_memaccess_unaligned(struct pt_regs *regs, unsigned long pc, unsigned long npc,
 			    unsigned long psr)
 {
-	siginfo_t info;
-
 	if(regs->psr & PSR_PS) {
 		printk("KERNEL MNA at pc %08lx npc %08lx called by %08lx\n", pc, npc,
 		       regs->u_regs[UREG_RETPC]);
@@ -168,13 +150,9 @@ void do_memaccess_unaligned(struct pt_regs *regs, unsigned long pc, unsigned lon
 	instruction_dump ((unsigned long *) regs->pc);
 	printk ("do_MNA!\n");
 #endif
-	clear_siginfo(&info);
-	info.si_signo = SIGBUS;
-	info.si_errno = 0;
-	info.si_code = BUS_ADRALN;
-	info.si_addr = /* FIXME: Should dig out mna address */ (void *)0;
-	info.si_trapno = 0;
-	send_sig_info(SIGBUS, &info, current);
+	send_sig_fault(SIGBUS, BUS_ADRALN,
+		       /* FIXME: Should dig out mna address */ (void *)0,
+		       0, current);
 }
 
 static unsigned long init_fsr = 0x0UL;
@@ -230,9 +208,9 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc,
 		 unsigned long psr)
 {
 	static int calls;
-	siginfo_t info;
 	unsigned long fsr;
 	int ret = 0;
+	int code;
 #ifndef CONFIG_SMP
 	struct task_struct *fpt = last_task_used_math;
 #else
@@ -307,25 +285,20 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc,
 	}
 
 	fsr = fpt->thread.fsr;
-	clear_siginfo(&info);
-	info.si_signo = SIGFPE;
-	info.si_errno = 0;
-	info.si_addr = (void __user *)pc;
-	info.si_trapno = 0;
-	info.si_code = FPE_FLTUNK;
+	code = FPE_FLTUNK;
 	if ((fsr & 0x1c000) == (1 << 14)) {
 		if (fsr & 0x10)
-			info.si_code = FPE_FLTINV;
+			code = FPE_FLTINV;
 		else if (fsr & 0x08)
-			info.si_code = FPE_FLTOVF;
+			code = FPE_FLTOVF;
 		else if (fsr & 0x04)
-			info.si_code = FPE_FLTUND;
+			code = FPE_FLTUND;
 		else if (fsr & 0x02)
-			info.si_code = FPE_FLTDIV;
+			code = FPE_FLTDIV;
 		else if (fsr & 0x01)
-			info.si_code = FPE_FLTRES;
+			code = FPE_FLTRES;
 	}
-	send_sig_info(SIGFPE, &info, fpt);
+	send_sig_fault(SIGFPE, code, (void __user *)pc, 0, fpt);
 #ifndef CONFIG_SMP
 	last_task_used_math = NULL;
 #endif
@@ -337,17 +310,9 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc,
 void handle_tag_overflow(struct pt_regs *regs, unsigned long pc, unsigned long npc,
 			 unsigned long psr)
 {
-	siginfo_t info;
-
 	if(psr & PSR_PS)
 		die_if_kernel("Penguin overflow trap from kernel mode", regs);
-	clear_siginfo(&info);
-	info.si_signo = SIGEMT;
-	info.si_errno = 0;
-	info.si_code = EMT_TAGOVF;
-	info.si_addr = (void __user *)pc;
-	info.si_trapno = 0;
-	send_sig_info(SIGEMT, &info, current);
+	send_sig_fault(SIGEMT, EMT_TAGOVF, (void __user *)pc, 0, current);
 }
 
 void handle_watchpoint(struct pt_regs *regs, unsigned long pc, unsigned long npc,
@@ -383,47 +348,23 @@ void handle_reg_access(struct pt_regs *regs, unsigned long pc, unsigned long npc
 void handle_cp_disabled(struct pt_regs *regs, unsigned long pc, unsigned long npc,
 			unsigned long psr)
 {
-	siginfo_t info;
-
-	clear_siginfo(&info);
-	info.si_signo = SIGILL;
-	info.si_errno = 0;
-	info.si_code = ILL_COPROC;
-	info.si_addr = (void __user *)pc;
-	info.si_trapno = 0;
-	send_sig_info(SIGILL, &info, current);
+	send_sig_fault(SIGILL, ILL_COPROC, (void __user *)pc, 0, current);
 }
 
 void handle_cp_exception(struct pt_regs *regs, unsigned long pc, unsigned long npc,
 			 unsigned long psr)
 {
-	siginfo_t info;
-
 #ifdef TRAP_DEBUG
 	printk("Co-Processor Exception at PC %08lx NPC %08lx PSR %08lx\n",
 	       pc, npc, psr);
 #endif
-	clear_siginfo(&info);
-	info.si_signo = SIGILL;
-	info.si_errno = 0;
-	info.si_code = ILL_COPROC;
-	info.si_addr = (void __user *)pc;
-	info.si_trapno = 0;
-	send_sig_info(SIGILL, &info, current);
+	send_sig_fault(SIGILL, ILL_COPROC, (void __user *)pc, 0, current);
 }
 
 void handle_hw_divzero(struct pt_regs *regs, unsigned long pc, unsigned long npc,
 		       unsigned long psr)
 {
-	siginfo_t info;
-
-	clear_siginfo(&info);
-	info.si_signo = SIGFPE;
-	info.si_errno = 0;
-	info.si_code = FPE_INTDIV;
-	info.si_addr = (void __user *)pc;
-	info.si_trapno = 0;
-	send_sig_info(SIGFPE, &info, current);
+	send_sig_fault(SIGFPE, FPE_INTDIV, (void __user *)pc, 0, current);
 }
 
 #ifdef CONFIG_DEBUG_BUGVERBOSE
diff --git a/arch/sparc/kernel/unaligned_32.c b/arch/sparc/kernel/unaligned_32.c
index 0e4cf7217413..64ac8c0c1429 100644
--- a/arch/sparc/kernel/unaligned_32.c
+++ b/arch/sparc/kernel/unaligned_32.c
@@ -311,15 +311,9 @@ static inline int ok_for_user(struct pt_regs *regs, unsigned int insn,
 
 static void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
 {
-	siginfo_t info;
-
-	clear_siginfo(&info);
-	info.si_signo = SIGBUS;
-	info.si_errno = 0;
-	info.si_code = BUS_ADRALN;
-	info.si_addr = (void __user *)safe_compute_effective_address(regs, insn);
-	info.si_trapno = 0;
-	send_sig_info(SIGBUS, &info, current);
+	send_sig_fault(SIGBUS, BUS_ADRALN,
+		       (void __user *)safe_compute_effective_address(regs, insn),
+		       0, current);
 }
 
 asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn)
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 18/22] signal/sparc: Use force_sig_fault where appropriate
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
                     ` (16 preceding siblings ...)
  2018-04-20 14:38   ` [REVIEW][PATCH 17/22] signal/sparc: Use send_sig_fault where appropriate Eric W. Biederman
@ 2018-04-20 14:38   ` Eric W. Biederman
  2018-04-20 14:38   ` [REVIEW][PATCH 19/22] signal/um: Use force_sig_fault in relay_signal Eric W. Biederman
                     ` (3 subsequent siblings)
  21 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20 14:38 UTC (permalink / raw)
  To: linux-arch; +Cc: linux-kernel, Eric W. Biederman, David Miller, sparclinux

Filling in struct siginfo before calling force_sig_info a tedious and
error prone process, where once in a great while the wrong fields
are filled out, and siginfo has been inconsistently cleared.

Simplify this process by using the helper force_sig_fault.  Which
takes as a parameters all of the information it needs, ensures
all of the fiddly bits of filling in struct siginfo are done properly
and then calls force_sig_info.

In short about a 5 line reduction in code for every time force_sig_info
is called, which makes the calling function clearer.

Cc: David Miller <davem@davemloft.net>
Cc: sparclinux@vger.kernel.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/sparc/kernel/process_64.c   |  10 +--
 arch/sparc/kernel/sys_sparc_32.c |   9 +--
 arch/sparc/kernel/sys_sparc_64.c |   8 +--
 arch/sparc/kernel/traps_32.c     |  21 +-----
 arch/sparc/kernel/traps_64.c     | 145 ++++++++-------------------------------
 arch/sparc/mm/fault_32.c         |  13 +---
 arch/sparc/mm/fault_64.c         |   9 +--
 7 files changed, 37 insertions(+), 178 deletions(-)

diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
index 2219e55206b4..6c086086ca8f 100644
--- a/arch/sparc/kernel/process_64.c
+++ b/arch/sparc/kernel/process_64.c
@@ -518,15 +518,7 @@ void synchronize_user_stack(void)
 
 static void stack_unaligned(unsigned long sp)
 {
-	siginfo_t info;
-
-	clear_siginfo(&info);
-	info.si_signo = SIGBUS;
-	info.si_errno = 0;
-	info.si_code = BUS_ADRALN;
-	info.si_addr = (void __user *) sp;
-	info.si_trapno = 0;
-	force_sig_info(SIGBUS, &info, current);
+	force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *) sp, 0, current);
 }
 
 void fault_in_user_windows(void)
diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c
index 00f6353fe435..7f3d9c59719a 100644
--- a/arch/sparc/kernel/sys_sparc_32.c
+++ b/arch/sparc/kernel/sys_sparc_32.c
@@ -147,18 +147,11 @@ SYSCALL_DEFINE0(nis_syscall)
 asmlinkage void
 sparc_breakpoint (struct pt_regs *regs)
 {
-	siginfo_t info;
 
 #ifdef DEBUG_SPARC_BREAKPOINT
         printk ("TRAP: Entering kernel PC=%x, nPC=%x\n", regs->pc, regs->npc);
 #endif
-	clear_siginfo(&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;
-	force_sig_info(SIGTRAP, &info, current);
+	force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->pc, 0, current);
 
 #ifdef DEBUG_SPARC_BREAKPOINT
 	printk ("TRAP: Returning to space: PC=%x nPC=%x\n", regs->pc, regs->npc);
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index 9ef8de63f28b..7e49bbc925a5 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -502,7 +502,6 @@ SYSCALL_DEFINE0(nis_syscall)
 asmlinkage void sparc_breakpoint(struct pt_regs *regs)
 {
 	enum ctx_state prev_state = exception_enter();
-	siginfo_t info;
 
 	if (test_thread_flag(TIF_32BIT)) {
 		regs->tpc &= 0xffffffff;
@@ -511,12 +510,7 @@ asmlinkage void sparc_breakpoint(struct pt_regs *regs)
 #ifdef DEBUG_SPARC_BREAKPOINT
         printk ("TRAP: Entering kernel PC=%lx, nPC=%lx\n", regs->tpc, regs->tnpc);
 #endif
-	info.si_signo = SIGTRAP;
-	info.si_errno = 0;
-	info.si_code = TRAP_BRKPT;
-	info.si_addr = (void __user *)regs->tpc;
-	info.si_trapno = 0;
-	force_sig_info(SIGTRAP, &info, current);
+	force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->tpc, 0, current);
 #ifdef DEBUG_SPARC_BREAKPOINT
 	printk ("TRAP: Returning to space: PC=%lx nPC=%lx\n", regs->tpc, regs->tnpc);
 #endif
diff --git a/arch/sparc/kernel/traps_32.c b/arch/sparc/kernel/traps_32.c
index 06f43cf9695f..bcdfc6168dd5 100644
--- a/arch/sparc/kernel/traps_32.c
+++ b/arch/sparc/kernel/traps_32.c
@@ -93,8 +93,6 @@ void __noreturn die_if_kernel(char *str, struct pt_regs *regs)
 
 void do_hw_interrupt(struct pt_regs *regs, unsigned long type)
 {
-	siginfo_t info;
-
 	if(type < 0x80) {
 		/* Sun OS's puke from bad traps, Linux survives! */
 		printk("Unimplemented Sparc TRAP, type = %02lx\n", type);
@@ -104,13 +102,8 @@ void do_hw_interrupt(struct pt_regs *regs, unsigned long type)
 	if(regs->psr & PSR_PS)
 		die_if_kernel("Kernel bad trap", regs);
 
-	clear_siginfo(&info);
-	info.si_signo = SIGILL;
-	info.si_errno = 0;
-	info.si_code = ILL_ILLTRP;
-	info.si_addr = (void __user *)regs->pc;
-	info.si_trapno = type - 0x80;
-	force_sig_info(SIGILL, &info, current);
+	force_sig_fault(SIGILL, ILL_ILLTRP,
+			(void __user *)regs->pc, type - 0x80, current);
 }
 
 void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned long npc,
@@ -330,19 +323,11 @@ void handle_watchpoint(struct pt_regs *regs, unsigned long pc, unsigned long npc
 void handle_reg_access(struct pt_regs *regs, unsigned long pc, unsigned long npc,
 		       unsigned long psr)
 {
-	siginfo_t info;
-
 #ifdef TRAP_DEBUG
 	printk("Register Access Exception at PC %08lx NPC %08lx PSR %08lx\n",
 	       pc, npc, psr);
 #endif
-	clear_siginfo(&info);
-	info.si_signo = SIGBUS;
-	info.si_errno = 0;
-	info.si_code = BUS_OBJERR;
-	info.si_addr = (void __user *)pc;
-	info.si_trapno = 0;
-	force_sig_info(SIGBUS, &info, current);
+	force_sig_fault(SIGBUS, BUS_OBJERR, (void __user *)pc, 0, current);
 }
 
 void handle_cp_disabled(struct pt_regs *regs, unsigned long pc, unsigned long npc,
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index b485b49b87a8..aa624ed79db1 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -87,7 +87,6 @@ static void dump_tl1_traplog(struct tl1_traplog *p)
 void bad_trap(struct pt_regs *regs, long lvl)
 {
 	char buffer[36];
-	siginfo_t info;
 
 	if (notify_die(DIE_TRAP, "bad trap", regs,
 		       0, lvl, SIGTRAP) == NOTIFY_STOP)
@@ -107,13 +106,8 @@ void bad_trap(struct pt_regs *regs, long lvl)
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
-	clear_siginfo(&info);
-	info.si_signo = SIGILL;
-	info.si_errno = 0;
-	info.si_code = ILL_ILLTRP;
-	info.si_addr = (void __user *)regs->tpc;
-	info.si_trapno = lvl;
-	force_sig_info(SIGILL, &info, current);
+	force_sig_fault(SIGILL, ILL_ILLTRP,
+			(void __user *)regs->tpc, lvl, current);
 }
 
 void bad_trap_tl1(struct pt_regs *regs, long lvl)
@@ -192,7 +186,6 @@ EXPORT_SYMBOL_GPL(unregister_dimm_printer);
 void spitfire_insn_access_exception(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar)
 {
 	enum ctx_state prev_state = exception_enter();
-	siginfo_t info;
 
 	if (notify_die(DIE_TRAP, "instruction access exception", regs,
 		       0, 0x8, SIGTRAP) == NOTIFY_STOP)
@@ -207,13 +200,8 @@ void spitfire_insn_access_exception(struct pt_regs *regs, unsigned long sfsr, un
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
-	clear_siginfo(&info);
-	info.si_signo = SIGSEGV;
-	info.si_errno = 0;
-	info.si_code = SEGV_MAPERR;
-	info.si_addr = (void __user *)regs->tpc;
-	info.si_trapno = 0;
-	force_sig_info(SIGSEGV, &info, current);
+	force_sig_fault(SIGSEGV, SEGV_MAPERR,
+			(void __user *)regs->tpc, 0, current);
 out:
 	exception_exit(prev_state);
 }
@@ -232,7 +220,6 @@ void sun4v_insn_access_exception(struct pt_regs *regs, unsigned long addr, unsig
 {
 	unsigned short type = (type_ctx >> 16);
 	unsigned short ctx  = (type_ctx & 0xffff);
-	siginfo_t info;
 
 	if (notify_die(DIE_TRAP, "instruction access exception", regs,
 		       0, 0x8, SIGTRAP) == NOTIFY_STOP)
@@ -249,13 +236,7 @@ void sun4v_insn_access_exception(struct pt_regs *regs, unsigned long addr, unsig
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
-	clear_siginfo(&info);
-	info.si_signo = SIGSEGV;
-	info.si_errno = 0;
-	info.si_code = SEGV_MAPERR;
-	info.si_addr = (void __user *) addr;
-	info.si_trapno = 0;
-	force_sig_info(SIGSEGV, &info, current);
+	force_sig_fault(SIGSEGV, SEGV_MAPERR, (void __user *) addr, 0, current);
 }
 
 void sun4v_insn_access_exception_tl1(struct pt_regs *regs, unsigned long addr, unsigned long type_ctx)
@@ -310,7 +291,6 @@ bool is_no_fault_exception(struct pt_regs *regs)
 void spitfire_data_access_exception(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar)
 {
 	enum ctx_state prev_state = exception_enter();
-	siginfo_t info;
 
 	if (notify_die(DIE_TRAP, "data access exception", regs,
 		       0, 0x30, SIGTRAP) == NOTIFY_STOP)
@@ -341,13 +321,7 @@ void spitfire_data_access_exception(struct pt_regs *regs, unsigned long sfsr, un
 	if (is_no_fault_exception(regs))
 		return;
 
-	clear_siginfo(&info);
-	info.si_signo = SIGSEGV;
-	info.si_errno = 0;
-	info.si_code = SEGV_MAPERR;
-	info.si_addr = (void __user *)sfar;
-	info.si_trapno = 0;
-	force_sig_info(SIGSEGV, &info, current);
+	force_sig_fault(SIGSEGV, SEGV_MAPERR, (void __user *)sfar, 0, current);
 out:
 	exception_exit(prev_state);
 }
@@ -563,8 +537,6 @@ static void spitfire_cee_log(unsigned long afsr, unsigned long afar, unsigned lo
 
 static void spitfire_ue_log(unsigned long afsr, unsigned long afar, unsigned long udbh, unsigned long udbl, unsigned long tt, int tl1, struct pt_regs *regs)
 {
-	siginfo_t info;
-
 	printk(KERN_WARNING "CPU[%d]: Uncorrectable Error AFSR[%lx] "
 	       "AFAR[%lx] UDBL[%lx] UDBH[%ld] TT[%lx] TL>1[%d]\n",
 	       smp_processor_id(), afsr, afar, udbl, udbh, tt, tl1);
@@ -599,13 +571,7 @@ static void spitfire_ue_log(unsigned long afsr, unsigned long afar, unsigned lon
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
-	clear_siginfo(&info);
-	info.si_signo = SIGBUS;
-	info.si_errno = 0;
-	info.si_code = BUS_OBJERR;
-	info.si_addr = (void *)0;
-	info.si_trapno = 0;
-	force_sig_info(SIGBUS, &info, current);
+	force_sig_fault(SIGBUS, BUS_OBJERR, (void *)0, 0, current);
 }
 
 void spitfire_access_error(struct pt_regs *regs, unsigned long status_encoded, unsigned long afar)
@@ -2195,7 +2161,6 @@ bool sun4v_nonresum_error_user_handled(struct pt_regs *regs,
 
 	if (attrs & SUN4V_ERR_ATTRS_MEMORY) {
 		unsigned long addr = ent->err_raddr;
-		siginfo_t info;
 
 		if (addr == ~(u64)0) {
 			/* This seems highly unlikely to ever occur */
@@ -2216,23 +2181,13 @@ bool sun4v_nonresum_error_user_handled(struct pt_regs *regs,
 				addr += PAGE_SIZE;
 			}
 		}
-		clear_siginfo(&info);
-		info.si_signo = SIGKILL;
-		info.si_errno = 0;
-		info.si_trapno = 0;
-		force_sig_info(info.si_signo, &info, current);
+		force_sig(SIGKILL, current);
 
 		return true;
 	}
 	if (attrs & SUN4V_ERR_ATTRS_PIO) {
-		siginfo_t info;
-
-		clear_siginfo(&info);
-		info.si_signo = SIGBUS;
-		info.si_code = BUS_ADRERR;
-		info.si_addr = (void __user *)sun4v_get_vaddr(regs);
-		force_sig_info(info.si_signo, &info, current);
-
+		force_sig_fault(SIGBUS, BUS_ADRERR,
+				(void __user *)sun4v_get_vaddr(regs), 0, current);
 		return true;
 	}
 
@@ -2369,31 +2324,27 @@ static void do_fpe_common(struct pt_regs *regs)
 		regs->tnpc += 4;
 	} else {
 		unsigned long fsr = current_thread_info()->xfsr[0];
-		siginfo_t info;
+		int code;
 
 		if (test_thread_flag(TIF_32BIT)) {
 			regs->tpc &= 0xffffffff;
 			regs->tnpc &= 0xffffffff;
 		}
-		clear_siginfo(&info);
-		info.si_signo = SIGFPE;
-		info.si_errno = 0;
-		info.si_addr = (void __user *)regs->tpc;
-		info.si_trapno = 0;
-		info.si_code = FPE_FLTUNK;
+		code = FPE_FLTUNK;
 		if ((fsr & 0x1c000) == (1 << 14)) {
 			if (fsr & 0x10)
-				info.si_code = FPE_FLTINV;
+				code = FPE_FLTINV;
 			else if (fsr & 0x08)
-				info.si_code = FPE_FLTOVF;
+				code = FPE_FLTOVF;
 			else if (fsr & 0x04)
-				info.si_code = FPE_FLTUND;
+				code = FPE_FLTUND;
 			else if (fsr & 0x02)
-				info.si_code = FPE_FLTDIV;
+				code = FPE_FLTDIV;
 			else if (fsr & 0x01)
-				info.si_code = FPE_FLTRES;
+				code = FPE_FLTRES;
 		}
-		force_sig_info(SIGFPE, &info, current);
+		force_sig_fault(SIGFPE, code,
+				(void __user *)regs->tpc, 0, current);
 	}
 }
 
@@ -2436,7 +2387,6 @@ void do_fpother(struct pt_regs *regs)
 void do_tof(struct pt_regs *regs)
 {
 	enum ctx_state prev_state = exception_enter();
-	siginfo_t info;
 
 	if (notify_die(DIE_TRAP, "tagged arithmetic overflow", regs,
 		       0, 0x26, SIGEMT) == NOTIFY_STOP)
@@ -2448,13 +2398,8 @@ void do_tof(struct pt_regs *regs)
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
-	clear_siginfo(&info);
-	info.si_signo = SIGEMT;
-	info.si_errno = 0;
-	info.si_code = EMT_TAGOVF;
-	info.si_addr = (void __user *)regs->tpc;
-	info.si_trapno = 0;
-	force_sig_info(SIGEMT, &info, current);
+	force_sig_fault(SIGEMT, EMT_TAGOVF,
+			(void __user *)regs->tpc, 0, current);
 out:
 	exception_exit(prev_state);
 }
@@ -2462,7 +2407,6 @@ void do_tof(struct pt_regs *regs)
 void do_div0(struct pt_regs *regs)
 {
 	enum ctx_state prev_state = exception_enter();
-	siginfo_t info;
 
 	if (notify_die(DIE_TRAP, "integer division by zero", regs,
 		       0, 0x28, SIGFPE) == NOTIFY_STOP)
@@ -2474,13 +2418,8 @@ void do_div0(struct pt_regs *regs)
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
-	clear_siginfo(&info);
-	info.si_signo = SIGFPE;
-	info.si_errno = 0;
-	info.si_code = FPE_INTDIV;
-	info.si_addr = (void __user *)regs->tpc;
-	info.si_trapno = 0;
-	force_sig_info(SIGFPE, &info, current);
+	force_sig_fault(SIGFPE, FPE_INTDIV,
+			(void __user *)regs->tpc, 0, current);
 out:
 	exception_exit(prev_state);
 }
@@ -2642,7 +2581,6 @@ void do_illegal_instruction(struct pt_regs *regs)
 	unsigned long pc = regs->tpc;
 	unsigned long tstate = regs->tstate;
 	u32 insn;
-	siginfo_t info;
 
 	if (notify_die(DIE_TRAP, "illegal instruction", regs,
 		       0, 0x10, SIGILL) == NOTIFY_STOP)
@@ -2676,13 +2614,7 @@ void do_illegal_instruction(struct pt_regs *regs)
 			}
 		}
 	}
-	clear_siginfo(&info);
-	info.si_signo = SIGILL;
-	info.si_errno = 0;
-	info.si_code = ILL_ILLOPC;
-	info.si_addr = (void __user *)pc;
-	info.si_trapno = 0;
-	force_sig_info(SIGILL, &info, current);
+	force_sig_fault(SIGILL, ILL_ILLOPC, (void __user *)pc, 0, current);
 out:
 	exception_exit(prev_state);
 }
@@ -2690,7 +2622,6 @@ void do_illegal_instruction(struct pt_regs *regs)
 void mem_address_unaligned(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr)
 {
 	enum ctx_state prev_state = exception_enter();
-	siginfo_t info;
 
 	if (notify_die(DIE_TRAP, "memory address unaligned", regs,
 		       0, 0x34, SIGSEGV) == NOTIFY_STOP)
@@ -2703,21 +2634,13 @@ void mem_address_unaligned(struct pt_regs *regs, unsigned long sfar, unsigned lo
 	if (is_no_fault_exception(regs))
 		return;
 
-	clear_siginfo(&info);
-	info.si_signo = SIGBUS;
-	info.si_errno = 0;
-	info.si_code = BUS_ADRALN;
-	info.si_addr = (void __user *)sfar;
-	info.si_trapno = 0;
-	force_sig_info(SIGBUS, &info, current);
+	force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)sfar, 0, current);
 out:
 	exception_exit(prev_state);
 }
 
 void sun4v_do_mna(struct pt_regs *regs, unsigned long addr, unsigned long type_ctx)
 {
-	siginfo_t info;
-
 	if (notify_die(DIE_TRAP, "memory address unaligned", regs,
 		       0, 0x34, SIGSEGV) == NOTIFY_STOP)
 		return;
@@ -2729,13 +2652,7 @@ void sun4v_do_mna(struct pt_regs *regs, unsigned long addr, unsigned long type_c
 	if (is_no_fault_exception(regs))
 		return;
 
-	clear_siginfo(&info);
-	info.si_signo = SIGBUS;
-	info.si_errno = 0;
-	info.si_code = BUS_ADRALN;
-	info.si_addr = (void __user *) addr;
-	info.si_trapno = 0;
-	force_sig_info(SIGBUS, &info, current);
+	force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *) addr, 0, current);
 }
 
 /* sun4v_mem_corrupt_detect_precise() - Handle precise exception on an ADI
@@ -2788,7 +2705,6 @@ void sun4v_mem_corrupt_detect_precise(struct pt_regs *regs, unsigned long addr,
 void do_privop(struct pt_regs *regs)
 {
 	enum ctx_state prev_state = exception_enter();
-	siginfo_t info;
 
 	if (notify_die(DIE_TRAP, "privileged operation", regs,
 		       0, 0x11, SIGILL) == NOTIFY_STOP)
@@ -2798,13 +2714,8 @@ void do_privop(struct pt_regs *regs)
 		regs->tpc &= 0xffffffff;
 		regs->tnpc &= 0xffffffff;
 	}
-	clear_siginfo(&info);
-	info.si_signo = SIGILL;
-	info.si_errno = 0;
-	info.si_code = ILL_PRVOPC;
-	info.si_addr = (void __user *)regs->tpc;
-	info.si_trapno = 0;
-	force_sig_info(SIGILL, &info, current);
+	force_sig_fault(SIGILL, ILL_PRVOPC,
+			(void __user *)regs->tpc, 0, current);
 out:
 	exception_exit(prev_state);
 }
diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c
index 2deb586665b9..9f75b6444bf1 100644
--- a/arch/sparc/mm/fault_32.c
+++ b/arch/sparc/mm/fault_32.c
@@ -127,20 +127,11 @@ show_signal_msg(struct pt_regs *regs, int sig, int code,
 static void __do_fault_siginfo(int code, int sig, struct pt_regs *regs,
 			       unsigned long addr)
 {
-	siginfo_t info;
-
-	clear_siginfo(&info);
-	info.si_signo = sig;
-	info.si_code = code;
-	info.si_errno = 0;
-	info.si_addr = (void __user *) addr;
-	info.si_trapno = 0;
-
 	if (unlikely(show_unhandled_signals))
-		show_signal_msg(regs, sig, info.si_code,
+		show_signal_msg(regs, sig, code,
 				addr, current);
 
-	force_sig_info (sig, &info, current);
+	force_sig_fault(sig, code, (void __user *) addr, 0, current);
 }
 
 static unsigned long compute_si_addr(struct pt_regs *regs, int text_fault)
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c
index 46ccff95d10e..63166fcf9e25 100644
--- a/arch/sparc/mm/fault_64.c
+++ b/arch/sparc/mm/fault_64.c
@@ -170,12 +170,7 @@ static void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
 			     int fault_code)
 {
 	unsigned long addr;
-	siginfo_t info;
 
-	clear_siginfo(&info);
-	info.si_code = code;
-	info.si_signo = sig;
-	info.si_errno = 0;
 	if (fault_code & FAULT_CODE_ITLB) {
 		addr = regs->tpc;
 	} else {
@@ -188,13 +183,11 @@ static void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
 		else
 			addr = fault_addr;
 	}
-	info.si_addr = (void __user *) addr;
-	info.si_trapno = 0;
 
 	if (unlikely(show_unhandled_signals))
 		show_signal_msg(regs, sig, code, addr, current);
 
-	force_sig_info(sig, &info, current);
+	force_sig_fault(sig, code, (void __user *) addr, 0, current);
 }
 
 static unsigned int get_fault_insn(struct pt_regs *regs, unsigned int insn)
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 19/22] signal/um: Use force_sig_fault in relay_signal.
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
                     ` (17 preceding siblings ...)
  2018-04-20 14:38   ` [REVIEW][PATCH 18/22] signal/sparc: Use force_sig_fault " Eric W. Biederman
@ 2018-04-20 14:38   ` Eric W. Biederman
  2018-04-20 16:06     ` [uml-devel] " Anton Ivanov
  2018-04-20 14:38   ` [REVIEW][PATCH 20/22] signal/um: Use force_sig_fault where appropriate Eric W. Biederman
                     ` (2 subsequent siblings)
  21 siblings, 1 reply; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20 14:38 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, Eric W. Biederman, Jeff Dike, Richard Weinberger,
	user-mode-linux-devel

Today user mode linux only works on x86 and x86_64 and this allows
simplifications of relay_signal.

- x86 always set si_errno to 0 in fault handlers.
- x86 does not implement si_trapno.
- Only si_codes between SI_USER and SI_KERNEL have a fault address.

Therefore warn if si_errno is set (it should never be).
Use force_sig_info in the case where we know we have a good fault.

For signals whose content it is not clear how to relay use plain
force_sig and let the signal sending code come up with an
appropriate generic siginfo.

Cc: Jeff Dike <jdike@addtoit.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: user-mode-linux-devel@lists.sourceforge.net
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/um/kernel/trap.c | 28 +++++++++++++---------------
 1 file changed, 13 insertions(+), 15 deletions(-)

diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index d4d38520c4c6..5f0ff17cd790 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -296,9 +296,6 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
 
 void relay_signal(int sig, struct siginfo *si, struct uml_pt_regs *regs)
 {
-	struct faultinfo *fi;
-	struct siginfo clean_si;
-
 	if (!UPT_IS_USER(regs)) {
 		if (sig == SIGBUS)
 			printk(KERN_ERR "Bus error - the host /dev/shm or /tmp "
@@ -308,29 +305,30 @@ void relay_signal(int sig, struct siginfo *si, struct uml_pt_regs *regs)
 
 	arch_examine_signal(sig, regs);
 
-	clear_siginfo(&clean_si);
-	clean_si.si_signo = si->si_signo;
-	clean_si.si_errno = si->si_errno;
-	clean_si.si_code = si->si_code;
+	if (unlikely(si->si_errno)) {
+		printk(KERN_ERR "Attempted to relay signal %d (si_code = %d) with errno %d\n",
+		       sig, si->si_code, si->si_errno);
+	}
 	switch (sig) {
 	case SIGILL:
 	case SIGFPE:
 	case SIGSEGV:
 	case SIGBUS:
 	case SIGTRAP:
-		fi = UPT_FAULTINFO(regs);
-		clean_si.si_addr = (void __user *) FAULT_ADDRESS(*fi);
-		current->thread.arch.faultinfo = *fi;
-#ifdef __ARCH_SI_TRAPNO
-		clean_si.si_trapno = si->si_trapno;
-#endif
-		break;
+		if ((si->si_code > SI_USER) && (si->si_code < SI_KERNEL)) {
+			struct faultinfo *fi = UPT_FAULTINFO(regs);
+			current->thread.arch.faultinfo = *fi;
+			force_sig_fault(sig, si->si_code,
+					(void __user *)FAULT_ADDRESS(*fi),
+					current);
+			break;
+		}
 	default:
 		printk(KERN_ERR "Attempted to relay unknown signal %d (si_code = %d)\n",
 			sig, si->si_code);
 	}
 
-	force_sig_info(sig, &clean_si, current);
+	force_sig(sig, current);
 }
 
 void bus_handler(int sig, struct siginfo *si, struct uml_pt_regs *regs)
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 20/22] signal/um: Use force_sig_fault where appropriate
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
                     ` (18 preceding siblings ...)
  2018-04-20 14:38   ` [REVIEW][PATCH 19/22] signal/um: Use force_sig_fault in relay_signal Eric W. Biederman
@ 2018-04-20 14:38   ` Eric W. Biederman
  2018-04-20 14:38   ` [REVIEW][PATCH 21/22] signal/xtensa: Consistenly use SIGBUS in do_unaligned_user Eric W. Biederman
  2018-04-20 14:38   ` [REVIEW][PATCH 22/22] signal/xtensa: Use force_sig_fault where appropriate Eric W. Biederman
  21 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20 14:38 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, Eric W. Biederman, Jeff Dike, Richard Weinberger,
	user-mode-linux-devel

Filling in struct siginfo before calling force_sig_info a tedious and
error prone process, where once in a great while the wrong fields
are filled out, and siginfo has been inconsistently cleared.

Simplify this process by using the helper force_sig_fault.  Which
takes as a parameters all of the information it needs, ensures
all of the fiddly bits of filling in struct siginfo are done properly
and then calls force_sig_info.

In short about a 5 line reduction in code for every time force_sig_info
is called, which makes the calling function clearer.

Cc: Jeff Dike <jdike@addtoit.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: user-mode-linux-devel@lists.sourceforge.net
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/um/kernel/ptrace.c | 13 +++----------
 arch/um/kernel/trap.c   | 26 ++++++++------------------
 2 files changed, 11 insertions(+), 28 deletions(-)

diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index bc2a516c190f..1a1d88a4d940 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -115,17 +115,10 @@ long arch_ptrace(struct task_struct *child, long request,
 static void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs,
 		  int error_code)
 {
-	struct siginfo info;
-
-	memset(&info, 0, sizeof(info));
-	info.si_signo = SIGTRAP;
-	info.si_code = TRAP_BRKPT;
-
-	/* User-mode eip? */
-	info.si_addr = UPT_IS_USER(regs) ? (void __user *) UPT_IP(regs) : NULL;
-
 	/* Send us the fake SIGTRAP */
-	force_sig_info(SIGTRAP, &info, tsk);
+	force_sig_fault(SIGTRAP, TRAP_BRKPT,
+			/* User-mode eip? */
+			UPT_IS_USER(regs) ? (void __user *) UPT_IP(regs) : NULL, tsk);
 }
 
 /*
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index 5f0ff17cd790..48b70dcb6963 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -162,14 +162,9 @@ static void show_segv_info(struct uml_pt_regs *regs)
 
 static void bad_segv(struct faultinfo fi, unsigned long ip)
 {
-	struct siginfo si;
-
-	clear_siginfo(&si);
-	si.si_signo = SIGSEGV;
-	si.si_code = SEGV_ACCERR;
-	si.si_addr = (void __user *) FAULT_ADDRESS(fi);
 	current->thread.arch.faultinfo = fi;
-	force_sig_info(SIGSEGV, &si, current);
+	force_sig_fault(SIGSEGV, SEGV_ACCERR, (void __user *) FAULT_ADDRESS(fi),
+			current);
 }
 
 void fatal_sigsegv(void)
@@ -215,13 +210,12 @@ void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs)
 unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
 		   struct uml_pt_regs *regs)
 {
-	struct siginfo si;
 	jmp_buf *catcher;
+	int si_code;
 	int err;
 	int is_write = FAULT_WRITE(fi);
 	unsigned long address = FAULT_ADDRESS(fi);
 
-	clear_siginfo(&si);
 	if (!is_user && regs)
 		current->thread.segv_regs = container_of(regs, struct pt_regs, regs);
 
@@ -241,7 +235,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
 
 	if (SEGV_IS_FIXABLE(&fi))
 		err = handle_page_fault(address, ip, is_write, is_user,
-					&si.si_code);
+					&si_code);
 	else {
 		err = -EFAULT;
 		/*
@@ -273,18 +267,14 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
 	show_segv_info(regs);
 
 	if (err == -EACCES) {
-		si.si_signo = SIGBUS;
-		si.si_errno = 0;
-		si.si_code = BUS_ADRERR;
-		si.si_addr = (void __user *)address;
 		current->thread.arch.faultinfo = fi;
-		force_sig_info(SIGBUS, &si, current);
+		force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)address,
+				current);
 	} else {
 		BUG_ON(err != -EFAULT);
-		si.si_signo = SIGSEGV;
-		si.si_addr = (void __user *) address;
 		current->thread.arch.faultinfo = fi;
-		force_sig_info(SIGSEGV, &si, current);
+		force_sig_fault(SIGSEGV, si_code, (void __user *) address,
+				current);
 	}
 
 out:
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 21/22] signal/xtensa: Consistenly use SIGBUS in do_unaligned_user
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
                     ` (19 preceding siblings ...)
  2018-04-20 14:38   ` [REVIEW][PATCH 20/22] signal/um: Use force_sig_fault where appropriate Eric W. Biederman
@ 2018-04-20 14:38   ` Eric W. Biederman
  2018-04-20 16:06     ` Max Filippov
  2018-04-20 14:38   ` [REVIEW][PATCH 22/22] signal/xtensa: Use force_sig_fault where appropriate Eric W. Biederman
  21 siblings, 1 reply; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20 14:38 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, Eric W. Biederman, Chris Zankel, Max Filippov,
	linux-xtensa, stable

While working on changing this code to use force_sig_fault I
discovered that do_unaliged_user is sets si_signo to SIGBUS and passes
SIGSEGV to force_sig_info.  Which is just b0rked.

The code is reporting a SIGBUS error so replace the SIGSEGV with SIGBUS.

Cc: Chris Zankel <chris@zankel.net>
Cc: Max Filippov <jcmvbkbc@gmail.com>
Cc: linux-xtensa@linux-xtensa.org
Cc: stable@vger.kernel.org
Fixes: 5a0015d62668 ("[PATCH] xtensa: Architecture support for Tensilica Xtensa Part 3")
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/xtensa/kernel/traps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index 51771929f341..90b509f65b6f 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -339,7 +339,7 @@ do_unaligned_user (struct pt_regs *regs)
 	info.si_errno = 0;
 	info.si_code = BUS_ADRALN;
 	info.si_addr = (void *) regs->excvaddr;
-	force_sig_info(SIGSEGV, &info, current);
+	force_sig_info(SIGBUS, &info, current);
 
 }
 #endif
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 22/22] signal/xtensa: Use force_sig_fault where appropriate
  2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
                     ` (20 preceding siblings ...)
  2018-04-20 14:38   ` [REVIEW][PATCH 21/22] signal/xtensa: Consistenly use SIGBUS in do_unaligned_user Eric W. Biederman
@ 2018-04-20 14:38   ` Eric W. Biederman
  2018-04-20 16:27     ` Max Filippov
  21 siblings, 1 reply; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-20 14:38 UTC (permalink / raw)
  To: linux-arch
  Cc: linux-kernel, Eric W. Biederman, Max Filippov, Chris Zankel,
	linux-xtensa

Filling in struct siginfo before calling force_sig_info a tedious and
error prone process, where once in a great while the wrong fields
are filled out, and siginfo has been inconsistently cleared.

Simplify this process by using the helper force_sig_fault.  Which
takes as a parameters all of the information it needs, ensures
all of the fiddly bits of filling in struct siginfo are done properly
and then calls force_sig_info.

In short about a 5 line reduction in code for every time force_sig_info
is called, which makes the calling function clearer.

Cc: Max Filippov <jcmvbkbc@gmail.com>
Cc: Chris Zankel <chris@zankel.net>
Cc: linux-xtensa@linux-xtensa.org
Cc: linux-xtensa@linux-xtensa.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/xtensa/kernel/traps.c | 10 +---------
 arch/xtensa/mm/fault.c     | 19 +++++--------------
 2 files changed, 6 insertions(+), 23 deletions(-)

diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index 90b509f65b6f..86507fa7c2d7 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -323,8 +323,6 @@ do_illegal_instruction(struct pt_regs *regs)
 void
 do_unaligned_user (struct pt_regs *regs)
 {
-	siginfo_t info;
-
 	__die_if_kernel("Unhandled unaligned exception in kernel",
 			regs, SIGKILL);
 
@@ -334,13 +332,7 @@ do_unaligned_user (struct pt_regs *regs)
 			    "(pid = %d, pc = %#010lx)\n",
 			    regs->excvaddr, current->comm,
 			    task_pid_nr(current), regs->pc);
-	clear_siginfo(&info);
-	info.si_signo = SIGBUS;
-	info.si_errno = 0;
-	info.si_code = BUS_ADRALN;
-	info.si_addr = (void *) regs->excvaddr;
-	force_sig_info(SIGBUS, &info, current);
-
+	force_sig_fault(SIGBUS, BUS_ADRALN, (void *) regs->excvaddr, current);
 }
 #endif
 
diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c
index f9323a3e61ce..c111a833205a 100644
--- a/arch/xtensa/mm/fault.c
+++ b/arch/xtensa/mm/fault.c
@@ -39,14 +39,13 @@ void do_page_fault(struct pt_regs *regs)
 	struct mm_struct *mm = current->mm;
 	unsigned int exccause = regs->exccause;
 	unsigned int address = regs->excvaddr;
-	siginfo_t info;
+	int code;
 
 	int is_write, is_exec;
 	int fault;
 	unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
 
-	clear_siginfo(&info);
-	info.si_code = SEGV_MAPERR;
+	code = SEGV_MAPERR;
 
 	/* We fault-in kernel-space virtual memory on-demand. The
 	 * 'reference' page table is init_mm.pgd.
@@ -92,7 +91,7 @@ void do_page_fault(struct pt_regs *regs)
 	 */
 
 good_area:
-	info.si_code = SEGV_ACCERR;
+	code = SEGV_ACCERR;
 
 	if (is_write) {
 		if (!(vma->vm_flags & VM_WRITE))
@@ -158,11 +157,7 @@ void do_page_fault(struct pt_regs *regs)
 	if (user_mode(regs)) {
 		current->thread.bad_vaddr = address;
 		current->thread.error_code = is_write;
-		info.si_signo = SIGSEGV;
-		info.si_errno = 0;
-		/* info.si_code has been set above */
-		info.si_addr = (void *) address;
-		force_sig_info(SIGSEGV, &info, current);
+		force_sig_fault(SIGSEGV, code, (void *) address, current);
 		return;
 	}
 	bad_page_fault(regs, address, SIGSEGV);
@@ -187,11 +182,7 @@ void do_page_fault(struct pt_regs *regs)
 	 * or user mode.
 	 */
 	current->thread.bad_vaddr = address;
-	info.si_code = SIGBUS;
-	info.si_errno = 0;
-	info.si_code = BUS_ADRERR;
-	info.si_addr = (void *) address;
-	force_sig_info(SIGBUS, &info, current);
+	force_sig_fault(SIGBUS, BUS_ADRERR, (void *) address, current);
 
 	/* Kernel mode? Handle exceptions or die */
 	if (!user_mode(regs))
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [REVIEW][PATCH 16/22] signal/sh: Use force_sig_fault where appropriate
  2018-04-20 14:38   ` [REVIEW][PATCH 16/22] signal/sh: " Eric W. Biederman
@ 2018-04-20 14:55     ` Rich Felker
  2018-05-28  9:19       ` Geert Uytterhoeven
  0 siblings, 1 reply; 77+ messages in thread
From: Rich Felker @ 2018-04-20 14:55 UTC (permalink / raw)
  To: Eric W. Biederman; +Cc: linux-arch, linux-kernel, Yoshinori Sato, linux-sh

On Fri, Apr 20, 2018 at 09:38:05AM -0500, Eric W. Biederman wrote:
> Filling in struct siginfo before calling force_sig_info a tedious and
> error prone process, where once in a great while the wrong fields
> are filled out, and siginfo has been inconsistently cleared.
> 
> Simplify this process by using the helper force_sig_fault.  Which
> takes as a parameters all of the information it needs, ensures
> all of the fiddly bits of filling in struct siginfo are done properly
> and then calls force_sig_info.
> 
> In short about a 5 line reduction in code for every time force_sig_info
> is called, which makes the calling function clearer.
> 
> Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
> Cc: Rich Felker <dalias@libc.org>
> Cc: linux-sh@vger.kernel.org
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
>  arch/sh/kernel/traps_32.c | 19 +++++--------------
>  arch/sh/math-emu/math.c   |  9 ++-------
>  arch/sh/mm/fault.c        | 10 +---------
>  3 files changed, 8 insertions(+), 30 deletions(-)
> 
> diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
> index e85e59c3d6df..660a4bc17698 100644
> --- a/arch/sh/kernel/traps_32.c
> +++ b/arch/sh/kernel/traps_32.c
> @@ -477,7 +477,6 @@ asmlinkage void do_address_error(struct pt_regs *regs,
>  {
>  	unsigned long error_code = 0;
>  	mm_segment_t oldfs;
> -	siginfo_t info;
>  	insn_size_t instruction;
>  	int tmp;
>  
> @@ -537,12 +536,7 @@ asmlinkage void do_address_error(struct pt_regs *regs,
>  		       "access (PC %lx PR %lx)\n", current->comm, regs->pc,
>  		       regs->pr);
>  
> -		clear_siginfo(&info);
> -		info.si_signo = SIGBUS;
> -		info.si_errno = 0;
> -		info.si_code = si_code;
> -		info.si_addr = (void __user *)address;
> -		force_sig_info(SIGBUS, &info, current);
> +		force_sig_fault(SIGBUS, si_code, (void __user *)address, current);
>  	} else {
>  		inc_unaligned_kernel_access();
>  
> @@ -599,20 +593,17 @@ int is_dsp_inst(struct pt_regs *regs)
>  #ifdef CONFIG_CPU_SH2A
>  asmlinkage void do_divide_error(unsigned long r4)
>  {
> -	siginfo_t info;
> +	int code;
>  
> -	clear_siginfo(&info);
>  	switch (r4) {
>  	case TRAP_DIVZERO_ERROR:
> -		info.si_code = FPE_INTDIV;
> +		code = FPE_INTDIV;
>  		break;
>  	case TRAP_DIVOVF_ERROR:
> -		info.si_code = FPE_INTOVF;
> +		code = FPE_INTOVF;
>  		break;
>  	}
> -
> -	info.si_signo = SIGFPE;
> -	force_sig_info(info.si_signo, &info, current);
> +	force_sig_fault(SIGFPE, code, NULL, current);
>  }
>  #endif
>  
> diff --git a/arch/sh/math-emu/math.c b/arch/sh/math-emu/math.c
> index d6d2213df078..a0fa8fc88739 100644
> --- a/arch/sh/math-emu/math.c
> +++ b/arch/sh/math-emu/math.c
> @@ -507,7 +507,6 @@ static int ieee_fpe_handler(struct pt_regs *regs)
>  	unsigned short insn = *(unsigned short *)regs->pc;
>  	unsigned short finsn;
>  	unsigned long nextpc;
> -	siginfo_t info;
>  	int nib[4] = {
>  		(insn >> 12) & 0xf,
>  		(insn >> 8) & 0xf,
> @@ -560,12 +559,8 @@ static int ieee_fpe_handler(struct pt_regs *regs)
>  				~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK);
>  			task_thread_info(tsk)->status |= TS_USEDFPU;
>  		} else {
> -			clear_siginfo(&info);
> -			info.si_signo = SIGFPE;
> -			info.si_errno = 0;
> -			info.si_code = FPE_FLTINV;
> -			info.si_addr = (void __user *)regs->pc;
> -			force_sig_info(SIGFPE, &info, tsk);
> +			force_sig_fault(SIGFPE, FPE_FLTINV,
> +					(void __user *)regs->pc, tsk);
>  		}
>  
>  		regs->pc = nextpc;
> diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
> index 4c98b6f20e02..b8e7bb84b6b1 100644
> --- a/arch/sh/mm/fault.c
> +++ b/arch/sh/mm/fault.c
> @@ -42,15 +42,7 @@ static void
>  force_sig_info_fault(int si_signo, int si_code, unsigned long address,
>  		     struct task_struct *tsk)
>  {
> -	siginfo_t info;
> -
> -	clear_siginfo(&info);
> -	info.si_signo	= si_signo;
> -	info.si_errno	= 0;
> -	info.si_code	= si_code;
> -	info.si_addr	= (void __user *)address;
> -
> -	force_sig_info(si_signo, &info, tsk);
> +	force_sig_fault(si_signo, si_code, (void __user *)address, tsk);
>  }
>  
>  /*
> -- 
> 2.14.1

Acked-by: Rich Felker <dalias@libc.org>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [uml-devel] [REVIEW][PATCH 19/22] signal/um: Use force_sig_fault in relay_signal.
  2018-04-20 14:38   ` [REVIEW][PATCH 19/22] signal/um: Use force_sig_fault in relay_signal Eric W. Biederman
@ 2018-04-20 16:06     ` Anton Ivanov
  2018-04-24  8:32       ` Richard Weinberger
  0 siblings, 1 reply; 77+ messages in thread
From: Anton Ivanov @ 2018-04-20 16:06 UTC (permalink / raw)
  To: Eric W. Biederman, linux-arch
  Cc: Richard Weinberger, Jeff Dike, linux-kernel, linux-um,
	user-mode-linux-devel


On 04/20/18 15:38, Eric W. Biederman wrote:
> Today user mode linux only works on x86 and x86_64 and this allows
> simplifications of relay_signal.

I believe someone recently fixed the ARM port. I have not had the time 
to try the fixes though.

I have added the new list we are migrating to the cc list.

A.



>
> - x86 always set si_errno to 0 in fault handlers.
> - x86 does not implement si_trapno.
> - Only si_codes between SI_USER and SI_KERNEL have a fault address.
>
> Therefore warn if si_errno is set (it should never be).
> Use force_sig_info in the case where we know we have a good fault.
>
> For signals whose content it is not clear how to relay use plain
> force_sig and let the signal sending code come up with an
> appropriate generic siginfo.
>
> Cc: Jeff Dike <jdike@addtoit.com>
> Cc: Richard Weinberger <richard@nod.at>
> Cc: user-mode-linux-devel@lists.sourceforge.net
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
>   arch/um/kernel/trap.c | 28 +++++++++++++---------------
>   1 file changed, 13 insertions(+), 15 deletions(-)
>
> diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
> index d4d38520c4c6..5f0ff17cd790 100644
> --- a/arch/um/kernel/trap.c
> +++ b/arch/um/kernel/trap.c
> @@ -296,9 +296,6 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
>   
>   void relay_signal(int sig, struct siginfo *si, struct uml_pt_regs *regs)
>   {
> -	struct faultinfo *fi;
> -	struct siginfo clean_si;
> -
>   	if (!UPT_IS_USER(regs)) {
>   		if (sig == SIGBUS)
>   			printk(KERN_ERR "Bus error - the host /dev/shm or /tmp "
> @@ -308,29 +305,30 @@ void relay_signal(int sig, struct siginfo *si, struct uml_pt_regs *regs)
>   
>   	arch_examine_signal(sig, regs);
>   
> -	clear_siginfo(&clean_si);
> -	clean_si.si_signo = si->si_signo;
> -	clean_si.si_errno = si->si_errno;
> -	clean_si.si_code = si->si_code;
> +	if (unlikely(si->si_errno)) {
> +		printk(KERN_ERR "Attempted to relay signal %d (si_code = %d) with errno %d\n",
> +		       sig, si->si_code, si->si_errno);
> +	}
>   	switch (sig) {
>   	case SIGILL:
>   	case SIGFPE:
>   	case SIGSEGV:
>   	case SIGBUS:
>   	case SIGTRAP:
> -		fi = UPT_FAULTINFO(regs);
> -		clean_si.si_addr = (void __user *) FAULT_ADDRESS(*fi);
> -		current->thread.arch.faultinfo = *fi;
> -#ifdef __ARCH_SI_TRAPNO
> -		clean_si.si_trapno = si->si_trapno;
> -#endif
> -		break;
> +		if ((si->si_code > SI_USER) && (si->si_code < SI_KERNEL)) {
> +			struct faultinfo *fi = UPT_FAULTINFO(regs);
> +			current->thread.arch.faultinfo = *fi;
> +			force_sig_fault(sig, si->si_code,
> +					(void __user *)FAULT_ADDRESS(*fi),
> +					current);
> +			break;
> +		}
>   	default:
>   		printk(KERN_ERR "Attempted to relay unknown signal %d (si_code = %d)\n",
>   			sig, si->si_code);
>   	}
>   
> -	force_sig_info(sig, &clean_si, current);
> +	force_sig(sig, current);
>   }
>   
>   void bus_handler(int sig, struct siginfo *si, struct uml_pt_regs *regs)

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [REVIEW][PATCH 21/22] signal/xtensa: Consistenly use SIGBUS in do_unaligned_user
  2018-04-20 14:38   ` [REVIEW][PATCH 21/22] signal/xtensa: Consistenly use SIGBUS in do_unaligned_user Eric W. Biederman
@ 2018-04-20 16:06     ` Max Filippov
  0 siblings, 0 replies; 77+ messages in thread
From: Max Filippov @ 2018-04-20 16:06 UTC (permalink / raw)
  To: Eric W. Biederman; +Cc: Linux-Arch, LKML, Chris Zankel, linux-xtensa, stable

On Fri, Apr 20, 2018 at 7:38 AM, Eric W. Biederman
<ebiederm@xmission.com> wrote:
> While working on changing this code to use force_sig_fault I
> discovered that do_unaliged_user is sets si_signo to SIGBUS and passes
> SIGSEGV to force_sig_info.  Which is just b0rked.
>
> The code is reporting a SIGBUS error so replace the SIGSEGV with SIGBUS.
>
> Cc: Chris Zankel <chris@zankel.net>
> Cc: Max Filippov <jcmvbkbc@gmail.com>
> Cc: linux-xtensa@linux-xtensa.org
> Cc: stable@vger.kernel.org
> Fixes: 5a0015d62668 ("[PATCH] xtensa: Architecture support for Tensilica Xtensa Part 3")
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
>  arch/xtensa/kernel/traps.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Acked-by: Max Filippov <jcmvbkbc@gmail.com>

-- 
Thanks.
-- Max

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [REVIEW][PATCH 22/22] signal/xtensa: Use force_sig_fault where appropriate
  2018-04-20 14:38   ` [REVIEW][PATCH 22/22] signal/xtensa: Use force_sig_fault where appropriate Eric W. Biederman
@ 2018-04-20 16:27     ` Max Filippov
  0 siblings, 0 replies; 77+ messages in thread
From: Max Filippov @ 2018-04-20 16:27 UTC (permalink / raw)
  To: Eric W. Biederman; +Cc: Linux-Arch, LKML, Chris Zankel, linux-xtensa

On Fri, Apr 20, 2018 at 7:38 AM, Eric W. Biederman
<ebiederm@xmission.com> wrote:
> Filling in struct siginfo before calling force_sig_info a tedious and
> error prone process, where once in a great while the wrong fields
> are filled out, and siginfo has been inconsistently cleared.
>
> Simplify this process by using the helper force_sig_fault.  Which
> takes as a parameters all of the information it needs, ensures
> all of the fiddly bits of filling in struct siginfo are done properly
> and then calls force_sig_info.
>
> In short about a 5 line reduction in code for every time force_sig_info
> is called, which makes the calling function clearer.
>
> Cc: Max Filippov <jcmvbkbc@gmail.com>
> Cc: Chris Zankel <chris@zankel.net>
> Cc: linux-xtensa@linux-xtensa.org
> Cc: linux-xtensa@linux-xtensa.org
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
>  arch/xtensa/kernel/traps.c | 10 +---------
>  arch/xtensa/mm/fault.c     | 19 +++++--------------
>  2 files changed, 6 insertions(+), 23 deletions(-)

Acked-by: Max Filippov <jcmvbkbc@gmail.com>

-- 
Thanks.
-- Max

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [REVIEW][PATCH 14/22] signal/riscv: Use force_sig_fault where appropriate
  2018-04-20 14:38   ` [REVIEW][PATCH 14/22] signal/riscv: " Eric W. Biederman
@ 2018-04-21  7:25     ` Christoph Hellwig
  2018-04-24 15:31       ` [REVIEW][PATCH 23/22] signal/riscv: Replace do_trap_siginfo with force_sig_fault Eric W. Biederman
  2018-04-23 19:11     ` [REVIEW][PATCH 14/22] signal/riscv: Use force_sig_fault where appropriate Palmer Dabbelt
  1 sibling, 1 reply; 77+ messages in thread
From: Christoph Hellwig @ 2018-04-21  7:25 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: linux-arch, linux-riscv, Palmer Dabbelt, linux-kernel, Albert Ou

On Fri, Apr 20, 2018 at 09:38:03AM -0500, Eric W. Biederman wrote:
> Filling in struct siginfo before calling force_sig_info a tedious and
> error prone process, where once in a great while the wrong fields
> are filled out, and siginfo has been inconsistently cleared.
> 
> Simplify this process by using the helper force_sig_fault.  Which
> takes as a parameters all of the information it needs, ensures
> all of the fiddly bits of filling in struct siginfo are done properly
> and then calls force_sig_info.
> 
> In short about a 5 line reduction in code for every time force_sig_info
> is called, which makes the calling function clearer.
> 
> Cc: Palmer Dabbelt <palmer@sifive.com>
> Cc: Albert Ou <albert@sifive.com>
> Cc: linux-riscv@lists.infradead.org
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
>  arch/riscv/kernel/traps.c | 9 +--------
>  1 file changed, 1 insertion(+), 8 deletions(-)
> 
> diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
> index 48aa6471cede..3087940008f4 100644
> --- a/arch/riscv/kernel/traps.c
> +++ b/arch/riscv/kernel/traps.c
> @@ -66,14 +66,7 @@ void die(struct pt_regs *regs, const char *str)
>  static inline void do_trap_siginfo(int signo, int code,
>  	unsigned long addr, struct task_struct *tsk)
>  {
> -	siginfo_t info;
> -
> -	clear_siginfo(&info);
> -	info.si_signo = signo;
> -	info.si_errno = 0;
> -	info.si_code = code;
> -	info.si_addr = (void __user *)addr;
> -	force_sig_info(signo, &info, tsk);
> +	force_sig_fault(signo, code, (void __user *)addr, tsk);
>  }

Please kill the do_trap_siginfo helper and use force_sig_fault
directly in both callers.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [REVIEW][PATCH 13/22] signal/parisc: Use force_sig_fault where appropriate
  2018-04-20 14:38   ` [REVIEW][PATCH 13/22] signal/parisc: Use force_sig_fault " Eric W. Biederman
@ 2018-04-21 17:24     ` Helge Deller
  0 siblings, 0 replies; 77+ messages in thread
From: Helge Deller @ 2018-04-21 17:24 UTC (permalink / raw)
  To: Eric W. Biederman, linux-arch; +Cc: linux-kernel, James Bottomley, linux-parisc

On 20.04.2018 16:38, Eric W. Biederman wrote:
> Filling in struct siginfo before calling force_sig_info a tedious and
> error prone process, where once in a great while the wrong fields
> are filled out, and siginfo has been inconsistently cleared.
> 
> Simplify this process by using the helper force_sig_fault.  Which
> takes as a parameters all of the information it needs, ensures
> all of the fiddly bits of filling in struct siginfo are done properly
> and then calls force_sig_info.
> 
> In short about a 5 line reduction in code for every time force_sig_info
> is called, which makes the calling function clearer.
> 
> Cc: James Bottomley <jejb@parisc-linux.org>
> Cc: Helge Deller <deller@gmx.de>
> Cc: linux-parisc@vger.kernel.org
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>

I pulled this whole patch series from your git tree and 
booted it on 32- and 64-bit parisc kernels.
 
Acked-by: Helge Deller <deller@gmx.de>   # parisc

Thanks!
Helge

> ---
>  arch/parisc/kernel/ptrace.c    | 11 ++------
>  arch/parisc/kernel/traps.c     | 63 ++++++++++++++----------------------------
>  arch/parisc/kernel/unaligned.c | 16 +++--------
>  arch/parisc/math-emu/driver.c  |  9 ++----
>  arch/parisc/mm/fault.c         | 25 +++++++----------
>  5 files changed, 39 insertions(+), 85 deletions(-)
> 
> diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
> index b1c12ceb1c88..7aa1d4d0d444 100644
> --- a/arch/parisc/kernel/ptrace.c
> +++ b/arch/parisc/kernel/ptrace.c
> @@ -76,8 +76,6 @@ void user_enable_single_step(struct task_struct *task)
>  	set_tsk_thread_flag(task, TIF_SINGLESTEP);
>  
>  	if (pa_psw(task)->n) {
> -		struct siginfo si;
> -
>  		/* Nullified, just crank over the queue. */
>  		task_regs(task)->iaoq[0] = task_regs(task)->iaoq[1];
>  		task_regs(task)->iasq[0] = task_regs(task)->iasq[1];
> @@ -90,12 +88,9 @@ void user_enable_single_step(struct task_struct *task)
>  		ptrace_disable(task);
>  		/* Don't wake up the task, but let the
>  		   parent know something happened. */
> -		clear_siginfo(&si);
> -		si.si_code = TRAP_TRACE;
> -		si.si_addr = (void __user *) (task_regs(task)->iaoq[0] & ~3);
> -		si.si_signo = SIGTRAP;
> -		si.si_errno = 0;
> -		force_sig_info(SIGTRAP, &si, task);
> +		force_sig_fault(SIGTRAP, TRAP_TRACE,
> +				(void __user *) (task_regs(task)->iaoq[0] & ~3),
> +				task);
>  		/* notify_parent(task, SIGCHLD); */
>  		return;
>  	}
> diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
> index 98f9f2f85940..132b09c657ff 100644
> --- a/arch/parisc/kernel/traps.c
> +++ b/arch/parisc/kernel/traps.c
> @@ -297,14 +297,8 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err)
>  #define GDB_BREAK_INSN 0x10004
>  static void handle_gdb_break(struct pt_regs *regs, int wot)
>  {
> -	struct siginfo si;
> -
> -	clear_siginfo(&si);
> -	si.si_signo = SIGTRAP;
> -	si.si_errno = 0;
> -	si.si_code = wot;
> -	si.si_addr = (void __user *) (regs->iaoq[0] & ~3);
> -	force_sig_info(SIGTRAP, &si, current);
> +	force_sig_fault(SIGTRAP, wot,
> +			(void __user *) (regs->iaoq[0] & ~3), current);
>  }
>  
>  static void handle_break(struct pt_regs *regs)
> @@ -488,9 +482,8 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
>  {
>  	unsigned long fault_address = 0;
>  	unsigned long fault_space = 0;
> -	struct siginfo si;
> +	int si_code;
>  
> -	clear_siginfo(&si);
>  	if (code == 1)
>  	    pdc_console_restart();  /* switch back to pdc if HPMC */
>  	else
> @@ -573,7 +566,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
>  	case  8:
>  		/* Illegal instruction trap */
>  		die_if_kernel("Illegal instruction", regs, code);
> -		si.si_code = ILL_ILLOPC;
> +		si_code = ILL_ILLOPC;
>  		goto give_sigill;
>  
>  	case  9:
> @@ -584,7 +577,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
>  	case 10:
>  		/* Privileged operation trap */
>  		die_if_kernel("Privileged operation", regs, code);
> -		si.si_code = ILL_PRVOPC;
> +		si_code = ILL_PRVOPC;
>  		goto give_sigill;
>  
>  	case 11:
> @@ -607,20 +600,16 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
>  		}
>  
>  		die_if_kernel("Privileged register usage", regs, code);
> -		si.si_code = ILL_PRVREG;
> +		si_code = ILL_PRVREG;
>  	give_sigill:
> -		si.si_signo = SIGILL;
> -		si.si_errno = 0;
> -		si.si_addr = (void __user *) regs->iaoq[0];
> -		force_sig_info(SIGILL, &si, current);
> +		force_sig_fault(SIGILL, si_code,
> +				(void __user *) regs->iaoq[0], current);
>  		return;
>  
>  	case 12:
>  		/* Overflow Trap, let the userland signal handler do the cleanup */
> -		si.si_signo = SIGFPE;
> -		si.si_code = FPE_INTOVF;
> -		si.si_addr = (void __user *) regs->iaoq[0];
> -		force_sig_info(SIGFPE, &si, current);
> +		force_sig_fault(SIGFPE, FPE_INTOVF,
> +				(void __user *) regs->iaoq[0], current);
>  		return;
>  		
>  	case 13:
> @@ -628,13 +617,11 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
>  		   The condition succeeds in an instruction which traps
>  		   on condition  */
>  		if(user_mode(regs)){
> -			si.si_signo = SIGFPE;
>  			/* Let userspace app figure it out from the insn pointed
>  			 * to by si_addr.
>  			 */
> -			si.si_code = FPE_CONDTRAP;
> -			si.si_addr = (void __user *) regs->iaoq[0];
> -			force_sig_info(SIGFPE, &si, current);
> +			force_sig_fault(SIGFPE, FPE_CONDTRAP,
> +					(void __user *) regs->iaoq[0], current);
>  			return;
>  		} 
>  		/* The kernel doesn't want to handle condition codes */
> @@ -743,14 +730,10 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
>  			return;
>  
>  		die_if_kernel("Protection id trap", regs, code);
> -		si.si_code = SEGV_MAPERR;
> -		si.si_signo = SIGSEGV;
> -		si.si_errno = 0;
> -		if (code == 7)
> -		    si.si_addr = (void __user *) regs->iaoq[0];
> -		else
> -		    si.si_addr = (void __user *) regs->ior;
> -		force_sig_info(SIGSEGV, &si, current);
> +		force_sig_fault(SIGSEGV, SEGV_MAPERR,
> +				(code == 7)?
> +				((void __user *) regs->iaoq[0]) :
> +				((void __user *) regs->ior), current);
>  		return;
>  
>  	case 28: 
> @@ -764,11 +747,8 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
>  				"handle_interruption() pid=%d command='%s'\n",
>  				task_pid_nr(current), current->comm);
>  			/* SIGBUS, for lack of a better one. */
> -			si.si_signo = SIGBUS;
> -			si.si_code = BUS_OBJERR;
> -			si.si_errno = 0;
> -			si.si_addr = (void __user *) regs->ior;
> -			force_sig_info(SIGBUS, &si, current);
> +			force_sig_fault(SIGBUS, BUS_OBJERR,
> +					(void __user *)regs->ior, current);
>  			return;
>  		}
>  		pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
> @@ -783,11 +763,8 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
>  				"User fault %d on space 0x%08lx, pid=%d command='%s'\n",
>  				code, fault_space,
>  				task_pid_nr(current), current->comm);
> -		si.si_signo = SIGSEGV;
> -		si.si_errno = 0;
> -		si.si_code = SEGV_MAPERR;
> -		si.si_addr = (void __user *) regs->ior;
> -		force_sig_info(SIGSEGV, &si, current);
> +		force_sig_fault(SIGSEGV, SEGV_MAPERR,
> +				(void __user *)regs->ior, current);
>  		return;
>  	    }
>  	}
> diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c
> index 30b7c7f6c471..932bfc0b7cd8 100644
> --- a/arch/parisc/kernel/unaligned.c
> +++ b/arch/parisc/kernel/unaligned.c
> @@ -452,10 +452,8 @@ void handle_unaligned(struct pt_regs *regs)
>  	unsigned long newbase = R1(regs->iir)?regs->gr[R1(regs->iir)]:0;
>  	int modify = 0;
>  	int ret = ERR_NOTHANDLED;
> -	struct siginfo si;
>  	register int flop=0;	/* true if this is a flop */
>  
> -	clear_siginfo(&si);
>  	__inc_irq_stat(irq_unaligned_count);
>  
>  	/* log a message with pacing */
> @@ -691,21 +689,15 @@ void handle_unaligned(struct pt_regs *regs)
>  
>  		if (ret == ERR_PAGEFAULT)
>  		{
> -			si.si_signo = SIGSEGV;
> -			si.si_errno = 0;
> -			si.si_code = SEGV_MAPERR;
> -			si.si_addr = (void __user *)regs->ior;
> -			force_sig_info(SIGSEGV, &si, current);
> +			force_sig_fault(SIGSEGV, SEGV_MAPERR,
> +					(void __user *)regs->ior, current);
>  		}
>  		else
>  		{
>  force_sigbus:
>  			/* couldn't handle it ... */
> -			si.si_signo = SIGBUS;
> -			si.si_errno = 0;
> -			si.si_code = BUS_ADRALN;
> -			si.si_addr = (void __user *)regs->ior;
> -			force_sig_info(SIGBUS, &si, current);
> +			force_sig_fault(SIGBUS, BUS_ADRALN,
> +					(void __user *)regs->ior, current);
>  		}
>  		
>  		return;
> diff --git a/arch/parisc/math-emu/driver.c b/arch/parisc/math-emu/driver.c
> index 0d10efb53361..0590e05571d1 100644
> --- a/arch/parisc/math-emu/driver.c
> +++ b/arch/parisc/math-emu/driver.c
> @@ -81,7 +81,6 @@ int
>  handle_fpe(struct pt_regs *regs)
>  {
>  	extern void printbinary(unsigned long x, int nbits);
> -	struct siginfo si;
>  	unsigned int orig_sw, sw;
>  	int signalcode;
>  	/* need an intermediate copy of float regs because FPU emulation
> @@ -93,7 +92,6 @@ handle_fpe(struct pt_regs *regs)
>  	 */
>  	__u64 frcopy[36];
>  
> -	clear_siginfo(&si);
>  	memcpy(frcopy, regs->fr, sizeof regs->fr);
>  	frcopy[32] = 0;
>  
> @@ -118,11 +116,8 @@ handle_fpe(struct pt_regs *regs)
>  
>  	memcpy(regs->fr, frcopy, sizeof regs->fr);
>  	if (signalcode != 0) {
> -	    si.si_signo = signalcode >> 24;
> -	    si.si_errno = 0;
> -	    si.si_code = signalcode & 0xffffff;
> -	    si.si_addr = (void __user *) regs->iaoq[0];
> -	    force_sig_info(si.si_signo, &si, current);
> +	    force_sig_fault(signalcode >> 24, signalcode & 0xffffff,
> +			    (void __user *) regs->iaoq[0], current);
>  	    return -1;
>  	}
>  
> diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
> index 51215b0048ef..a80117980fc2 100644
> --- a/arch/parisc/mm/fault.c
> +++ b/arch/parisc/mm/fault.c
> @@ -353,23 +353,22 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
>  	up_read(&mm->mmap_sem);
>  
>  	if (user_mode(regs)) {
> -		struct siginfo si;
> +		int signo, si_code;
>  
> -		clear_siginfo(&si);
>  		switch (code) {
>  		case 15:	/* Data TLB miss fault/Data page fault */
>  			/* send SIGSEGV when outside of vma */
>  			if (!vma ||
>  			    address < vma->vm_start || address >= vma->vm_end) {
> -				si.si_signo = SIGSEGV;
> -				si.si_code = SEGV_MAPERR;
> +				signo = SIGSEGV;
> +				si_code = SEGV_MAPERR;
>  				break;
>  			}
>  
>  			/* send SIGSEGV for wrong permissions */
>  			if ((vma->vm_flags & acc_type) != acc_type) {
> -				si.si_signo = SIGSEGV;
> -				si.si_code = SEGV_ACCERR;
> +				signo = SIGSEGV;
> +				si_code = SEGV_ACCERR;
>  				break;
>  			}
>  
> @@ -377,17 +376,16 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
>  			/* fall through */
>  		case 17:	/* NA data TLB miss / page fault */
>  		case 18:	/* Unaligned access - PCXS only */
> -			si.si_signo = SIGBUS;
> -			si.si_code = (code == 18) ? BUS_ADRALN : BUS_ADRERR;
> +			signo = SIGBUS;
> +			si_code = (code == 18) ? BUS_ADRALN : BUS_ADRERR;
>  			break;
>  		case 16:	/* Non-access instruction TLB miss fault */
>  		case 26:	/* PCXL: Data memory access rights trap */
>  		default:
> -			si.si_signo = SIGSEGV;
> -			si.si_code = (code == 26) ? SEGV_ACCERR : SEGV_MAPERR;
> +			signo = SIGSEGV;
> +			si_code = (code == 26) ? SEGV_ACCERR : SEGV_MAPERR;
>  			break;
>  		}
> -
>  #ifdef CONFIG_MEMORY_FAILURE
>  		if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) {
>  			unsigned int lsb = 0;
> @@ -409,12 +407,9 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
>  			return;
>  		}
>  #endif
> -
>  		show_signal_msg(regs, code, address, tsk, vma);
>  
> -		si.si_errno = 0;
> -		si.si_addr = (void __user *) address;
> -		force_sig_info(si.si_signo, &si, current);
> +		force_sig_fault(signo, si_code, (void __user *) address, current);
>  		return;
>  	}
>  
> 

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [REVIEW][PATCH 15/22] signal/s390: Use force_sig_fault where appropriate
  2018-04-20 14:38   ` [REVIEW][PATCH 15/22] signal/s390: " Eric W. Biederman
@ 2018-04-23  5:44     ` Martin Schwidefsky
  0 siblings, 0 replies; 77+ messages in thread
From: Martin Schwidefsky @ 2018-04-23  5:44 UTC (permalink / raw)
  To: Eric W. Biederman; +Cc: linux-arch, linux-kernel, Heiko Carstens, linux-s390

On Fri, 20 Apr 2018 09:38:04 -0500
"Eric W. Biederman" <ebiederm@xmission.com> wrote:

> Filling in struct siginfo before calling force_sig_info a tedious and
> error prone process, where once in a great while the wrong fields
> are filled out, and siginfo has been inconsistently cleared.
> 
> Simplify this process by using the helper force_sig_fault.  Which
> takes as a parameters all of the information it needs, ensures
> all of the fiddly bits of filling in struct siginfo are done properly
> and then calls force_sig_info.
> 
> In short about a 5 line reduction in code for every time force_sig_info
> is called, which makes the calling function clearer.
> 
> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
> Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
> Cc: linux-s390@vger.kernel.org
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
>  arch/s390/kernel/traps.c | 32 ++++++--------------------------
>  arch/s390/mm/fault.c     | 23 ++++++-----------------
>  2 files changed, 12 insertions(+), 43 deletions(-)
 
Compiles & boots. Comparing old vs. new the same values are
set in siginfo. Looks good.

Acked-by: Martin Schwidefsky >schwidefsky@de.ibm.com>

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [REVIEW][PATCH 14/22] signal/riscv: Use force_sig_fault where appropriate
  2018-04-20 14:38   ` [REVIEW][PATCH 14/22] signal/riscv: " Eric W. Biederman
  2018-04-21  7:25     ` Christoph Hellwig
@ 2018-04-23 19:11     ` Palmer Dabbelt
  2018-04-24 15:28       ` Eric W. Biederman
  1 sibling, 1 reply; 77+ messages in thread
From: Palmer Dabbelt @ 2018-04-23 19:11 UTC (permalink / raw)
  To: ebiederm; +Cc: linux-arch, linux-kernel, ebiederm, albert, linux-riscv

On Fri, 20 Apr 2018 07:38:03 PDT (-0700), ebiederm@xmission.com wrote:
> Filling in struct siginfo before calling force_sig_info a tedious and
> error prone process, where once in a great while the wrong fields
> are filled out, and siginfo has been inconsistently cleared.
>
> Simplify this process by using the helper force_sig_fault.  Which
> takes as a parameters all of the information it needs, ensures
> all of the fiddly bits of filling in struct siginfo are done properly
> and then calls force_sig_info.
>
> In short about a 5 line reduction in code for every time force_sig_info
> is called, which makes the calling function clearer.
>
> Cc: Palmer Dabbelt <palmer@sifive.com>
> Cc: Albert Ou <albert@sifive.com>
> Cc: linux-riscv@lists.infradead.org
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
>  arch/riscv/kernel/traps.c | 9 +--------
>  1 file changed, 1 insertion(+), 8 deletions(-)
>
> diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
> index 48aa6471cede..3087940008f4 100644
> --- a/arch/riscv/kernel/traps.c
> +++ b/arch/riscv/kernel/traps.c
> @@ -66,14 +66,7 @@ void die(struct pt_regs *regs, const char *str)
>  static inline void do_trap_siginfo(int signo, int code,
>  	unsigned long addr, struct task_struct *tsk)
>  {
> -	siginfo_t info;
> -
> -	clear_siginfo(&info);
> -	info.si_signo = signo;
> -	info.si_errno = 0;
> -	info.si_code = code;
> -	info.si_addr = (void __user *)addr;
> -	force_sig_info(signo, &info, tsk);
> +	force_sig_fault(signo, code, (void __user *)addr, tsk);
>  }
>
>  void do_trap(struct pt_regs *regs, int signo, int code,

If I understand this correctly, any change in behavior this causes would have 
been a bug on our end not filling out siginfo correctly?  In that case then 
feel free to add an

    Acked-by: Palmer Dabbelt <palmer@sifive.com>

Thanks!

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [uml-devel] [REVIEW][PATCH 19/22] signal/um: Use force_sig_fault in relay_signal.
  2018-04-20 16:06     ` [uml-devel] " Anton Ivanov
@ 2018-04-24  8:32       ` Richard Weinberger
  2018-04-24  8:44         ` Anton Ivanov
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Weinberger @ 2018-04-24  8:32 UTC (permalink / raw)
  To: Anton Ivanov
  Cc: Eric W. Biederman, Linux-Arch, Richard Weinberger, Jeff Dike,
	linux-um, LKML, user-mode-linux-devel

On Fri, Apr 20, 2018 at 6:06 PM, Anton Ivanov
<anton.ivanov@kot-begemot.co.uk> wrote:
>
> On 04/20/18 15:38, Eric W. Biederman wrote:
>>
>> Today user mode linux only works on x86 and x86_64 and this allows
>> simplifications of relay_signal.
>
>
> I believe someone recently fixed the ARM port. I have not had the time to
> try the fixes though.

Huh? UML is for ages x86 only.

-- 
Thanks,
//richard

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [uml-devel] [REVIEW][PATCH 19/22] signal/um: Use force_sig_fault in relay_signal.
  2018-04-24  8:32       ` Richard Weinberger
@ 2018-04-24  8:44         ` Anton Ivanov
  2018-04-24 15:59           ` Eric W. Biederman
  0 siblings, 1 reply; 77+ messages in thread
From: Anton Ivanov @ 2018-04-24  8:44 UTC (permalink / raw)
  To: Richard Weinberger
  Cc: Eric W. Biederman, Linux-Arch, Richard Weinberger, Jeff Dike,
	linux-um, LKML, user-mode-linux-devel

Hi Richard,

There was a post to uml-devel during the days when the sourceforge 
mailing list was working in random drop mode which claimed that "this 
fixes the arm build".

I have not kept it locally and I do not see it the archive (I do not see 
a few other posts there either - including some of mine).

The joys of having a broken list :(

Whoever posted it, if you are reading it, please re-post again so we can 
have a look.

In the meantime we are as you said - x86 only.

A.

On 04/24/18 09:32, Richard Weinberger wrote:
> On Fri, Apr 20, 2018 at 6:06 PM, Anton Ivanov
> <anton.ivanov@kot-begemot.co.uk> wrote:
>> On 04/20/18 15:38, Eric W. Biederman wrote:
>>> Today user mode linux only works on x86 and x86_64 and this allows
>>> simplifications of relay_signal.
>>
>> I believe someone recently fixed the ARM port. I have not had the time to
>> try the fixes though.
> Huh? UML is for ages x86 only.
>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [REVIEW][PATCH 14/22] signal/riscv: Use force_sig_fault where appropriate
  2018-04-23 19:11     ` [REVIEW][PATCH 14/22] signal/riscv: Use force_sig_fault where appropriate Palmer Dabbelt
@ 2018-04-24 15:28       ` Eric W. Biederman
  0 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-24 15:28 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: linux-arch, linux-kernel, albert, linux-riscv

Palmer Dabbelt <palmer@sifive.com> writes:

> On Fri, 20 Apr 2018 07:38:03 PDT (-0700), ebiederm@xmission.com wrote:
>> Filling in struct siginfo before calling force_sig_info a tedious and
>> error prone process, where once in a great while the wrong fields
>> are filled out, and siginfo has been inconsistently cleared.
>>
>> Simplify this process by using the helper force_sig_fault.  Which
>> takes as a parameters all of the information it needs, ensures
>> all of the fiddly bits of filling in struct siginfo are done properly
>> and then calls force_sig_info.
>>
>> In short about a 5 line reduction in code for every time force_sig_info
>> is called, which makes the calling function clearer.
>>
>> Cc: Palmer Dabbelt <palmer@sifive.com>
>> Cc: Albert Ou <albert@sifive.com>
>> Cc: linux-riscv@lists.infradead.org
>> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
>> ---
>>  arch/riscv/kernel/traps.c | 9 +--------
>>  1 file changed, 1 insertion(+), 8 deletions(-)
>>
>> diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
>> index 48aa6471cede..3087940008f4 100644
>> --- a/arch/riscv/kernel/traps.c
>> +++ b/arch/riscv/kernel/traps.c
>> @@ -66,14 +66,7 @@ void die(struct pt_regs *regs, const char *str)
>>  static inline void do_trap_siginfo(int signo, int code,
>>  	unsigned long addr, struct task_struct *tsk)
>>  {
>> -	siginfo_t info;
>> -
>> -	clear_siginfo(&info);
>> -	info.si_signo = signo;
>> -	info.si_errno = 0;
>> -	info.si_code = code;
>> -	info.si_addr = (void __user *)addr;
>> -	force_sig_info(signo, &info, tsk);
>> +	force_sig_fault(signo, code, (void __user *)addr, tsk);
>>  }
>>
>>  void do_trap(struct pt_regs *regs, int signo, int code,
>
> If I understand this correctly, any change in behavior this causes would have
> been a bug on our end not filling out siginfo correctly?  In that case then feel
> free to add an

If this change above causes any user visible changes it is a bug.
As Christoph rightly pointed out force_sig_fault is simply the arch
generic version of do_trap_siginfo. 

Eric

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 23/22] signal/riscv: Replace do_trap_siginfo with force_sig_fault
  2018-04-21  7:25     ` Christoph Hellwig
@ 2018-04-24 15:31       ` Eric W. Biederman
  0 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-24 15:31 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-arch, linux-riscv, Palmer Dabbelt, linux-kernel, Albert Ou


The function force_sig_fault is just the generic version of
do_trap_siginfo with a (void __user *) instead of an unsigned long
parameter for the address.

So just use force_sig_fault to simplify the code.

Cc: Palmer Dabbelt <palmer@sifive.com>
Cc: Albert Ou <albert@sifive.com>
Cc: linux-riscv@lists.infradead.org
Suggested-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/riscv/kernel/traps.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 3087940008f4..b99d9dd21fd0 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -63,12 +63,6 @@ void die(struct pt_regs *regs, const char *str)
 		do_exit(SIGSEGV);
 }
 
-static inline void do_trap_siginfo(int signo, int code,
-	unsigned long addr, struct task_struct *tsk)
-{
-	force_sig_fault(signo, code, (void __user *)addr, tsk);
-}
-
 void do_trap(struct pt_regs *regs, int signo, int code,
 	unsigned long addr, struct task_struct *tsk)
 {
@@ -81,7 +75,7 @@ void do_trap(struct pt_regs *regs, int signo, int code,
 		show_regs(regs);
 	}
 
-	do_trap_siginfo(signo, code, addr, tsk);
+	force_sig_fault(signo, code, (void __user *)addr, tsk);
 }
 
 static void do_trap_error(struct pt_regs *regs, int signo, int code,
@@ -143,7 +137,7 @@ asmlinkage void do_trap_break(struct pt_regs *regs)
 	}
 #endif /* CONFIG_GENERIC_BUG */
 
-	do_trap_siginfo(SIGTRAP, TRAP_BRKPT, regs->sepc, current);
+	force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)(regs->sepc), current);
 	regs->sepc += 0x4;
 }
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [uml-devel] [REVIEW][PATCH 19/22] signal/um: Use force_sig_fault in relay_signal.
  2018-04-24  8:44         ` Anton Ivanov
@ 2018-04-24 15:59           ` Eric W. Biederman
       [not found]             ` <CAMD8JhwgcWCp6c=O4-spNW1VdY5M-eAjr7M5PieeAfeTSe_4yw@mail.gmail.com>
  0 siblings, 1 reply; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-24 15:59 UTC (permalink / raw)
  To: Anton Ivanov
  Cc: Richard Weinberger, Linux-Arch, Richard Weinberger, Jeff Dike,
	linux-um, LKML, user-mode-linux-devel, Martin Pärtel

Sigh I should have Cc'd Martin Partel as well as this bit is his
original code.

Anton Ivanov <anton.ivanov@kot-begemot.co.uk> writes:

> Hi Richard,
>
> There was a post to uml-devel during the days when the sourceforge mailing list
> was working in random drop mode which claimed that "this fixes the arm build".
>
> I have not kept it locally and I do not see it the archive (I do not see a few
> other posts there either - including some of mine).
>
> The joys of having a broken list :(
>
> Whoever posted it, if you are reading it, please re-post again so we can have a
> look.
>
> In the meantime we are as you said - x86 only.

The only case I can see my changed relay_signal affecting on arm is the
nasty hach where errno is set in conjunction with trap_trace.

Having a second look I really don't understand what relay_signal is
trying to do.

The function relay_signal does not pass siginfo through unchanged.
The function relay_signal does not handle cases where si_code is
not SI_USER or SI_KERNEL, or any of the other signal independent
si_codes.

In my change I believe I have preserved the character of relay_signal of
just passing through the fault.

Still even after reading the commit that upgraded relay_signal to
preserve si_code and si_addr I really don't understand the intended
logic.

Am I missing something subtle or have the subtle details of siginfo just
always been ignored?

commit d3c1cfcdb43e023ab1b1c7a555cd9e929026500a
Author: Martin Pärtel <martin.partel@gmail.com>
Date:   Thu Aug 2 00:49:17 2012 +0200

    um: pass siginfo to guest process
    
    UML guest processes now get correct siginfo_t for SIGTRAP, SIGFPE,
    SIGILL and SIGBUS. Specifically, si_addr and si_code are now correct
    where previously they were si_addr = NULL and si_code = 128.
    
    Signed-off-by: Martin Pärtel <martin.partel@gmail.com>
    Signed-off-by: Richard Weinberger <richard@nod.at>

Eric

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [uml-devel] [REVIEW][PATCH 19/22] signal/um: Use force_sig_fault in relay_signal.
       [not found]             ` <CAMD8JhwgcWCp6c=O4-spNW1VdY5M-eAjr7M5PieeAfeTSe_4yw@mail.gmail.com>
@ 2018-04-24 22:03               ` Martin Pärtel
  2018-04-24 22:24                 ` Eric W. Biederman
  0 siblings, 1 reply; 77+ messages in thread
From: Martin Pärtel @ 2018-04-24 22:03 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Anton Ivanov, Richard Weinberger, Linux-Arch, Richard Weinberger,
	Jeff Dike, linux-um, LKML, user-mode-linux-devel

And once more in plain text..

On 25 April 2018 at 01:00, Martin Pärtel <martin.partel@gmail.com> wrote:
>
> Hi all,
>
> This was ages ago, but from what I remember...
>
>>
>> Having a second look I really don't understand what relay_signal is
>> trying to do.
>>
>> The function relay_signal does not pass siginfo through unchanged.
>
>
> Just copying the entire struct would do the wrong thing. It was discussed here:
> https://marc.info/?l=user-mode-linux-devel&m=133910707911999&w=2
>
>>
>> Am I missing something subtle or have the subtle details of siginfo just
>> always been ignored?
>
>
> My guess is they have. I was almost certainly oblivious to such subtleties when writing my commit.
>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [uml-devel] [REVIEW][PATCH 19/22] signal/um: Use force_sig_fault in relay_signal.
  2018-04-24 22:03               ` Martin Pärtel
@ 2018-04-24 22:24                 ` Eric W. Biederman
  2018-04-25 23:05                   ` Martin Pärtel
  0 siblings, 1 reply; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-24 22:24 UTC (permalink / raw)
  To: Martin Pärtel
  Cc: Anton Ivanov, Richard Weinberger, Linux-Arch, Richard Weinberger,
	Jeff Dike, linux-um, LKML, user-mode-linux-devel

Martin Pärtel <martin.partel@gmail.com> writes:

> And once more in plain text..
>
> On 25 April 2018 at 01:00, Martin Pärtel <martin.partel@gmail.com> wrote:
>>
>> Hi all,
>>
>> This was ages ago, but from what I remember...
>>
>>>
>>> Having a second look I really don't understand what relay_signal is
>>> trying to do.
>>>
>>> The function relay_signal does not pass siginfo through unchanged.
>>
>>
>> Just copying the entire struct would do the wrong thing. It was discussed here:
>> https://marc.info/?l=user-mode-linux-devel&m=133910707911999&w=2

So you are regnerating siginfo to ensure you don't copy unintended
things such as the host pid and host uid.

Then my analysis is correct that you simply missed filtering out the
si codes that are not signal specific and do not use the fault layout
in struct siginfo.

Is si_addr safe to copy across?  I presume so since the kernel just
ptraces an ordinary process, but I figure I should ask and double
check.

I am going to respin my patch.  I would say that you really need a
white-list of si_codes that whose use of struct siginfo that you know.
Otherwise you could get into the same problem of under or over copying
data.

Eric

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [REVIEW][PATCH 09/22] signal/nds32: Use force_sig_fault where appropriate
  2018-04-20 14:37   ` [REVIEW][PATCH 09/22] signal/nds32: " Eric W. Biederman
@ 2018-04-25 11:29     ` Vincent Chen
  2018-04-25 15:57       ` Eric W. Biederman
  0 siblings, 1 reply; 77+ messages in thread
From: Vincent Chen @ 2018-04-25 11:29 UTC (permalink / raw)
  To: Eric W. Biederman; +Cc: linux-arch, Linux Kernel Mailing List, Greentime Hu

2018-04-20 22:37 GMT+08:00 Eric W. Biederman <ebiederm@xmission.com>:
> Filling in struct siginfo before calling force_sig_info a tedious and
> error prone process, where once in a great while the wrong fields
> are filled out, and siginfo has been inconsistently cleared.
>
> Simplify this process by using the helper force_sig_fault.  Which
> takes as a parameters all of the information it needs, ensures
> all of the fiddly bits of filling in struct siginfo are done properly
> and then calls force_sig_info.
>
> In short about a 5 line reduction in code for every time force_sig_info
> is called, which makes the calling function clearer.
>
> Cc: Greentime Hu <green.hu@gmail.com>
> Cc: Vincent Chen <deanbo422@gmail.com>
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
>  arch/nds32/kernel/traps.c | 20 ++++----------------
>  arch/nds32/mm/fault.c     | 19 +++++--------------
>  2 files changed, 9 insertions(+), 30 deletions(-)
>
> diff --git a/arch/nds32/kernel/traps.c b/arch/nds32/kernel/traps.c
> index 46911768f4b5..636d1c7aa895 100644
> --- a/arch/nds32/kernel/traps.c
> +++ b/arch/nds32/kernel/traps.c
> @@ -222,20 +222,13 @@ void die_if_kernel(const char *str, struct pt_regs *regs, int err)
>
>  int bad_syscall(int n, struct pt_regs *regs)
>  {
> -       siginfo_t info;
> -
>         if (current->personality != PER_LINUX) {
>                 send_sig(SIGSEGV, current, 1);
>                 return regs->uregs[0];
>         }
>
> -       clear_siginfo(&info);
> -       info.si_signo = SIGILL;
> -       info.si_errno = 0;
> -       info.si_code = ILL_ILLTRP;
> -       info.si_addr = (void __user *)instruction_pointer(regs) - 4;
> -
> -       force_sig_info(SIGILL, &info, current);
> +       force_sig_fault(SIGILL, ILL_ILLTRP,
> +                       (void __user *)instruction_pointer(regs) - 4, current);
>         die_if_kernel("Oops - bad syscall", regs, n);
>         return regs->uregs[0];
>  }
> @@ -288,16 +281,11 @@ void __init early_trap_init(void)
>  void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
>                   int error_code, int si_code)
>  {
> -       struct siginfo info;
> -
>         tsk->thread.trap_no = ENTRY_DEBUG_RELATED;
>         tsk->thread.error_code = error_code;
>
> -       clear_siginfo(&info);
> -       info.si_signo = SIGTRAP;
> -       info.si_code = si_code;
> -       info.si_addr = (void __user *)instruction_pointer(regs);
> -       force_sig_info(SIGTRAP, &info, tsk);
> +       force_sig_fault(SIGTRAP, si_code
> +                       (void __user *)instruction_pointer(regs), tsk);
>  }
>

I found a comma is missing after argument si_code.

>  void do_debug_trap(unsigned long entry, unsigned long addr,
> diff --git a/arch/nds32/mm/fault.c b/arch/nds32/mm/fault.c
> index 876ee01ff80a..9bdb7c3ecbb6 100644
> --- a/arch/nds32/mm/fault.c
> +++ b/arch/nds32/mm/fault.c
> @@ -72,16 +72,15 @@ void do_page_fault(unsigned long entry, unsigned long addr,
>         struct task_struct *tsk;
>         struct mm_struct *mm;
>         struct vm_area_struct *vma;
> -       siginfo_t info;
> +       int si_code;
>         int fault;
>         unsigned int mask = VM_READ | VM_WRITE | VM_EXEC;
>         unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
>
> -       clear_siginfo(&info);
>         error_code = error_code & (ITYPE_mskINST | ITYPE_mskETYPE);
>         tsk = current;
>         mm = tsk->mm;
> -       info.si_code = SEGV_MAPERR;
> +       si_code = SEGV_MAPERR;
>         /*
>          * We fault-in kernel-space virtual memory on-demand. The
>          * 'reference' page table is init_mm.pgd.
> @@ -162,7 +161,7 @@ void do_page_fault(unsigned long entry, unsigned long addr,
>          */
>
>  good_area:
> -       info.si_code = SEGV_ACCERR;
> +       si_code = SEGV_ACCERR;
>
>         /* first do some preliminary protection checks */
>         if (entry == ENTRY_PTE_NOT_PRESENT) {
> @@ -267,11 +266,7 @@ void do_page_fault(unsigned long entry, unsigned long addr,
>                 tsk->thread.address = addr;
>                 tsk->thread.error_code = error_code;
>                 tsk->thread.trap_no = entry;
> -               info.si_signo = SIGSEGV;
> -               info.si_errno = 0;
> -               /* info.si_code has been set above */
> -               info.si_addr = (void *)addr;
> -               force_sig_info(SIGSEGV, &info, tsk);
> +               force_sig_fault(SIGSEGV, si_code, (void __user *)addr, tsk);
>                 return;
>         }
>
> @@ -340,11 +335,7 @@ void do_page_fault(unsigned long entry, unsigned long addr,
>         tsk->thread.address = addr;
>         tsk->thread.error_code = error_code;
>         tsk->thread.trap_no = entry;
> -       info.si_signo = SIGBUS;
> -       info.si_errno = 0;
> -       info.si_code = BUS_ADRERR;
> -       info.si_addr = (void *)addr;
> -       force_sig_info(SIGBUS, &info, tsk);
> +       force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)addr, tsk);
>
>         return;
>
> --
> 2.14.1
>


Except the missing comma in send_sigtrap(), I think this patch for nds32 is OK.

Vincent Chen

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [REVIEW][PATCH 05/17] signal/nds32: Use force_sig(SIGILL) in do_revisn
  2018-04-20  1:03 ` [REVIEW][PATCH 05/17] signal/nds32: Use force_sig(SIGILL) in do_revisn Eric W. Biederman
@ 2018-04-25 12:10   ` Vincent Chen
  2018-04-25 16:13     ` [PATCH] signal/nds32: More information in do_revinsn Eric W. Biederman
  0 siblings, 1 reply; 77+ messages in thread
From: Vincent Chen @ 2018-04-25 12:10 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: linux-arch, Linux Kernel Mailing List, linux-api, Vincent Chen,
	Greentime Hu, Arnd Bergmann

2018-04-20 9:03 GMT+08:00 Eric W. Biederman <ebiederm@xmission.com>:
> As originally committed do_revisn would deliver a siginfo for SIGILL
> with an si_code composed of random stack contents.  That makes no
> sense and is not something userspace can depend on.  So simplify
> the code and just use "force_sig(SIG_ILL, current)" instead.
>
> Fixes: 2923f5ea7738 ("nds32: Exception handling")
> Cc: Vincent Chen <vincentc@andestech.com>
> Cc: Greentime Hu <greentime@andestech.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
>  arch/nds32/kernel/traps.c | 5 +----
>  1 file changed, 1 insertion(+), 4 deletions(-)
>
> diff --git a/arch/nds32/kernel/traps.c b/arch/nds32/kernel/traps.c
> index 65961bf91d64..8e9a5b1f6234 100644
> --- a/arch/nds32/kernel/traps.c
> +++ b/arch/nds32/kernel/traps.c
> @@ -356,14 +356,11 @@ void do_dispatch_tlb_misc(unsigned long entry, unsigned long addr,
>
>  void do_revinsn(struct pt_regs *regs)
>  {
> -       siginfo_t si;
>         pr_emerg("Reserved Instruction\n");
>         show_regs(regs);
>         if (!user_mode(regs))
>                 do_exit(SIGILL);
> -       si.si_signo = SIGILL;
> -       si.si_errno = 0;
> -       force_sig_info(SIGILL, &si, current);
> +       force_sig(SIGILL, current);
>  }
>
>  #ifdef CONFIG_ALIGNMENT_TRAP
> --
> 2.14.1
>

You are right we do not store any valuable information in sigingo_t now.
However, We hope more information can be recorded by force_sig_fault()
as below instead of calling force_sig() directly.

-        force_sig(SIGILL, current);
+        force_sig_fault(SIGILL, ILL_ILLTRP,
+                        (void __user *)instruction_pointer(regs), current);

Thanks

Vincent Chen

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [REVIEW][PATCH 04/17] signal/nds32: Use force_sig in unhandled_interruption and unhandled_exceptions
  2018-04-20  1:03 ` [REVIEW][PATCH 04/17] signal/nds32: Use force_sig in unhandled_interruption and unhandled_exceptions Eric W. Biederman
@ 2018-04-25 12:14   ` Vincent Chen
  0 siblings, 0 replies; 77+ messages in thread
From: Vincent Chen @ 2018-04-25 12:14 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: linux-arch, Linux Kernel Mailing List, linux-api, Vincent Chen,
	Greentime Hu, Arnd Bergmann

2018-04-20 9:03 GMT+08:00 Eric W. Biederman <ebiederm@xmission.com>:
> Neither unhandled_interrupt nor unhandled_exceptions fills in any of the
> siginfo fields whend sending SIGKILL.  Further because it is SIGKILL
> even if all of the fields were filled out appropriately it would be impossible
> for the process to read any of the siginfo fields.  So simplfy things and
> just use force_sig instead of force_sig_info.
>
> Fixes: 2923f5ea7738 ("nds32: Exception handling")
> Cc: Vincent Chen <vincentc@andestech.com>
> Cc: Greentime Hu <greentime@andestech.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
>  arch/nds32/kernel/traps.c | 11 ++---------
>  1 file changed, 2 insertions(+), 9 deletions(-)
>
> diff --git a/arch/nds32/kernel/traps.c b/arch/nds32/kernel/traps.c
> index 6e34eb9824a4..65961bf91d64 100644
> --- a/arch/nds32/kernel/traps.c
> +++ b/arch/nds32/kernel/traps.c
> @@ -318,29 +318,22 @@ void do_debug_trap(unsigned long entry, unsigned long addr,
>
>  void unhandled_interruption(struct pt_regs *regs)
>  {
> -       siginfo_t si;
>         pr_emerg("unhandled_interruption\n");
>         show_regs(regs);
>         if (!user_mode(regs))
>                 do_exit(SIGKILL);
> -       si.si_signo = SIGKILL;
> -       si.si_errno = 0;
> -       force_sig_info(SIGKILL, &si, current);
> +       force_sig(SIGKILL, current);
>  }
>
>  void unhandled_exceptions(unsigned long entry, unsigned long addr,
>                           unsigned long type, struct pt_regs *regs)
>  {
> -       siginfo_t si;
>         pr_emerg("Unhandled Exception: entry: %lx addr:%lx itype:%lx\n", entry,
>                  addr, type);
>         show_regs(regs);
>         if (!user_mode(regs))
>                 do_exit(SIGKILL);
> -       si.si_signo = SIGKILL;
> -       si.si_errno = 0;
> -       si.si_addr = (void *)addr;
> -       force_sig_info(SIGKILL, &si, current);
> +       force_sig(SIGKILL, current);
>  }
>
>  extern int do_page_fault(unsigned long entry, unsigned long addr,
> --
> 2.14.1
>

Acked-by Vincent Chen

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [REVIEW][PATCH 09/22] signal/nds32: Use force_sig_fault where appropriate
  2018-04-25 11:29     ` Vincent Chen
@ 2018-04-25 15:57       ` Eric W. Biederman
  2018-04-26  1:24         ` Greentime Hu
  0 siblings, 1 reply; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-25 15:57 UTC (permalink / raw)
  To: Vincent Chen; +Cc: linux-arch, Linux Kernel Mailing List, Greentime Hu

Vincent Chen <deanbo422@gmail.com> writes:

> 2018-04-20 22:37 GMT+08:00 Eric W. Biederman <ebiederm@xmission.com>:
>> Filling in struct siginfo before calling force_sig_info a tedious and
>> error prone process, where once in a great while the wrong fields
>> are filled out, and siginfo has been inconsistently cleared.
>>
>> Simplify this process by using the helper force_sig_fault.  Which
>> takes as a parameters all of the information it needs, ensures
>> all of the fiddly bits of filling in struct siginfo are done properly
>> and then calls force_sig_info.
>>
>> In short about a 5 line reduction in code for every time force_sig_info
>> is called, which makes the calling function clearer.
>>
>> Cc: Greentime Hu <green.hu@gmail.com>
>> Cc: Vincent Chen <deanbo422@gmail.com>
>> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
>> ---
>>  arch/nds32/kernel/traps.c | 20 ++++----------------
>>  arch/nds32/mm/fault.c     | 19 +++++--------------
>>  2 files changed, 9 insertions(+), 30 deletions(-)
>>
>> diff --git a/arch/nds32/kernel/traps.c b/arch/nds32/kernel/traps.c
>> index 46911768f4b5..636d1c7aa895 100644
>> --- a/arch/nds32/kernel/traps.c
>> +++ b/arch/nds32/kernel/traps.c
>> @@ -222,20 +222,13 @@ void die_if_kernel(const char *str, struct pt_regs *regs, int err)
>>
>>  int bad_syscall(int n, struct pt_regs *regs)
>>  {
>> -       siginfo_t info;
>> -
>>         if (current->personality != PER_LINUX) {
>>                 send_sig(SIGSEGV, current, 1);
>>                 return regs->uregs[0];
>>         }
>>
>> -       clear_siginfo(&info);
>> -       info.si_signo = SIGILL;
>> -       info.si_errno = 0;
>> -       info.si_code = ILL_ILLTRP;
>> -       info.si_addr = (void __user *)instruction_pointer(regs) - 4;
>> -
>> -       force_sig_info(SIGILL, &info, current);
>> +       force_sig_fault(SIGILL, ILL_ILLTRP,
>> +                       (void __user *)instruction_pointer(regs) - 4, current);
>>         die_if_kernel("Oops - bad syscall", regs, n);
>>         return regs->uregs[0];
>>  }
>> @@ -288,16 +281,11 @@ void __init early_trap_init(void)
>>  void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
>>                   int error_code, int si_code)
>>  {
>> -       struct siginfo info;
>> -
>>         tsk->thread.trap_no = ENTRY_DEBUG_RELATED;
>>         tsk->thread.error_code = error_code;
>>
>> -       clear_siginfo(&info);
>> -       info.si_signo = SIGTRAP;
>> -       info.si_code = si_code;
>> -       info.si_addr = (void __user *)instruction_pointer(regs);
>> -       force_sig_info(SIGTRAP, &info, tsk);
>> +       force_sig_fault(SIGTRAP, si_code
>> +                       (void __user *)instruction_pointer(regs), tsk);
>>  }
>>
>
> I found a comma is missing after argument si_code.

Good catch.  Fixed.

Unfortunately the only compiler I have for nds32 is my eyeballs so
this slipped through.  Grr.


> Except the missing comma in send_sigtrap(), I think this patch for nds32 is OK.
>

I have corrected the change as you suggested and have added your Acked
by.

Eric

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [PATCH] signal/nds32: More information in do_revinsn
  2018-04-25 12:10   ` Vincent Chen
@ 2018-04-25 16:13     ` Eric W. Biederman
  2018-04-26  3:02       ` Vincent Chen
  0 siblings, 1 reply; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-25 16:13 UTC (permalink / raw)
  To: Vincent Chen
  Cc: linux-arch, Linux Kernel Mailing List, linux-api, Vincent Chen,
	Greentime Hu, Arnd Bergmann


While reviewing f6ed1ecad56f ("signal/nds32: Use force_sig(SIGILL) in do_revisn")
Vincent Chen asked if it was possible to provide more information in do_revinsn
with force_sig_fault.

That seems reasonable and the appropirate si_code appears to be
ILL_ILLOPC (illegal opcode) as the printk indicates this code path
is triggered when a reserved instruction is exectured.

So update do_revinsn to use force_sig_fault(SIGILL, ILL_ILLOPC, ...).
Giving userspace a much better experience when soemone attempts
to execute a reserved instruction.

Cc: Greentime Hu <green.hu@gmail.com>
Cc: Vincent Chen <deanbo422@gmail.com>
Suggested-by: Vincent Chen <deanbo422@gmail.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---

Vincent I have updated this from your suggestion to use
ILL_ILLOPC as that appears the more appropriate si_code.
Normally I expect you could just update your nds32 tree and
make this kind of change but since I am touching this code anyway I will
be happy to take this change along with the others.

Does this look good to you?

 arch/nds32/kernel/traps.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/nds32/kernel/traps.c b/arch/nds32/kernel/traps.c
index a6205fd4db52..5c2f61835ab9 100644
--- a/arch/nds32/kernel/traps.c
+++ b/arch/nds32/kernel/traps.c
@@ -349,7 +349,8 @@ void do_revinsn(struct pt_regs *regs)
 	show_regs(regs);
 	if (!user_mode(regs))
 		do_exit(SIGILL);
-	force_sig(SIGILL, current);
+	force_sig_fault(SIGILL, ILL_ILLOPC,
+			(void __user *)instruction_pointer(regs), current);
 }
 
 #ifdef CONFIG_ALIGNMENT_TRAP
-- 
2.14.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [uml-devel] [REVIEW][PATCH 19/22] signal/um: Use force_sig_fault in relay_signal.
  2018-04-24 22:24                 ` Eric W. Biederman
@ 2018-04-25 23:05                   ` Martin Pärtel
  2018-04-28 14:02                     ` [REVIEW][PATCH 0/5] Improving siginfo_layout and fixing uml's relay_signal Eric W. Biederman
  0 siblings, 1 reply; 77+ messages in thread
From: Martin Pärtel @ 2018-04-25 23:05 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: Anton Ivanov, Richard Weinberger, Linux-Arch, Richard Weinberger,
	Jeff Dike, linux-um, LKML, user-mode-linux-devel

>
> Then my analysis is correct that you simply missed filtering out the
> si codes that are not signal specific and do not use the fault layout
> in struct siginfo.
> ...
> I would say that you really need a
> white-list of si_codes that whose use of struct siginfo that you know.
> Otherwise you could get into the same problem of under or over copying
> data.
>

I think that's correct, but I'm not super familiar with either UML or
signal handling.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [REVIEW][PATCH 09/22] signal/nds32: Use force_sig_fault where appropriate
  2018-04-25 15:57       ` Eric W. Biederman
@ 2018-04-26  1:24         ` Greentime Hu
  0 siblings, 0 replies; 77+ messages in thread
From: Greentime Hu @ 2018-04-26  1:24 UTC (permalink / raw)
  To: Eric W. Biederman; +Cc: Vincent Chen, linux-arch, Linux Kernel Mailing List

2018-04-25 23:57 GMT+08:00 Eric W. Biederman <ebiederm@xmission.com>:
> Vincent Chen <deanbo422@gmail.com> writes:
>
>> 2018-04-20 22:37 GMT+08:00 Eric W. Biederman <ebiederm@xmission.com>:
>>> Filling in struct siginfo before calling force_sig_info a tedious and
>>> error prone process, where once in a great while the wrong fields
>>> are filled out, and siginfo has been inconsistently cleared.
>>>
>>> Simplify this process by using the helper force_sig_fault.  Which
>>> takes as a parameters all of the information it needs, ensures
>>> all of the fiddly bits of filling in struct siginfo are done properly
>>> and then calls force_sig_info.
>>>
>>> In short about a 5 line reduction in code for every time force_sig_info
>>> is called, which makes the calling function clearer.
>>>
>>> Cc: Greentime Hu <green.hu@gmail.com>
>>> Cc: Vincent Chen <deanbo422@gmail.com>
>>> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
>>> ---
>>>  arch/nds32/kernel/traps.c | 20 ++++----------------
>>>  arch/nds32/mm/fault.c     | 19 +++++--------------
>>>  2 files changed, 9 insertions(+), 30 deletions(-)
>>>
>>> diff --git a/arch/nds32/kernel/traps.c b/arch/nds32/kernel/traps.c
>>> index 46911768f4b5..636d1c7aa895 100644
>>> --- a/arch/nds32/kernel/traps.c
>>> +++ b/arch/nds32/kernel/traps.c
>>> @@ -222,20 +222,13 @@ void die_if_kernel(const char *str, struct pt_regs *regs, int err)
>>>
>>>  int bad_syscall(int n, struct pt_regs *regs)
>>>  {
>>> -       siginfo_t info;
>>> -
>>>         if (current->personality != PER_LINUX) {
>>>                 send_sig(SIGSEGV, current, 1);
>>>                 return regs->uregs[0];
>>>         }
>>>
>>> -       clear_siginfo(&info);
>>> -       info.si_signo = SIGILL;
>>> -       info.si_errno = 0;
>>> -       info.si_code = ILL_ILLTRP;
>>> -       info.si_addr = (void __user *)instruction_pointer(regs) - 4;
>>> -
>>> -       force_sig_info(SIGILL, &info, current);
>>> +       force_sig_fault(SIGILL, ILL_ILLTRP,
>>> +                       (void __user *)instruction_pointer(regs) - 4, current);
>>>         die_if_kernel("Oops - bad syscall", regs, n);
>>>         return regs->uregs[0];
>>>  }
>>> @@ -288,16 +281,11 @@ void __init early_trap_init(void)
>>>  void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
>>>                   int error_code, int si_code)
>>>  {
>>> -       struct siginfo info;
>>> -
>>>         tsk->thread.trap_no = ENTRY_DEBUG_RELATED;
>>>         tsk->thread.error_code = error_code;
>>>
>>> -       clear_siginfo(&info);
>>> -       info.si_signo = SIGTRAP;
>>> -       info.si_code = si_code;
>>> -       info.si_addr = (void __user *)instruction_pointer(regs);
>>> -       force_sig_info(SIGTRAP, &info, tsk);
>>> +       force_sig_fault(SIGTRAP, si_code
>>> +                       (void __user *)instruction_pointer(regs), tsk);
>>>  }
>>>
>>
>> I found a comma is missing after argument si_code.
>
> Good catch.  Fixed.
>
> Unfortunately the only compiler I have for nds32 is my eyeballs so
> this slipped through.  Grr.
>
>

Sorry for that. Our nds32 toolchain upstreaming is on-going.
You may try this one. It is able to build defconfig and allnoconfig

https://lkml.org/lkml/2018/4/17/395
https://www.kernel.org/pub/tools/crosstool/files/bin/x86_64/6.4.0/x86_64-gcc-6.4.0-nolibc-nds32le-linux.tar.xz

or this one with glibc support
https://github.com/andestech/build_script.git
https://github.com/greentime/prebuilt-nds32-toolchain/releases

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH] signal/nds32: More information in do_revinsn
  2018-04-25 16:13     ` [PATCH] signal/nds32: More information in do_revinsn Eric W. Biederman
@ 2018-04-26  3:02       ` Vincent Chen
  0 siblings, 0 replies; 77+ messages in thread
From: Vincent Chen @ 2018-04-26  3:02 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: linux-arch, Linux Kernel Mailing List, linux-api, Vincent Chen,
	Greentime Hu, Arnd Bergmann

2018-04-26 0:13 GMT+08:00 Eric W. Biederman <ebiederm@xmission.com>:
>
> While reviewing f6ed1ecad56f ("signal/nds32: Use force_sig(SIGILL) in do_revisn")
> Vincent Chen asked if it was possible to provide more information in do_revinsn
> with force_sig_fault.
>
> That seems reasonable and the appropirate si_code appears to be
> ILL_ILLOPC (illegal opcode) as the printk indicates this code path
> is triggered when a reserved instruction is exectured.
>

I think error code is set as ILL_ILLOPC is a good choice for normal
reserved instruction
but it seems a little bit inappropriate for nds32. For nds32 reserved
exception, It is possibly
triggered by illegal opcode, operand and immediate. Unfortunately,
do_revisn() can not
identify the actual reason now. Therefore, I chose ILLTRAP to avoid
confusing user when
the reserved exception is cauesd by wrong immediate or operand.



> So update do_revinsn to use force_sig_fault(SIGILL, ILL_ILLOPC, ...).
> Giving userspace a much better experience when soemone attempts
> to execute a reserved instruction.
>
> Cc: Greentime Hu <green.hu@gmail.com>
> Cc: Vincent Chen <deanbo422@gmail.com>
> Suggested-by: Vincent Chen <deanbo422@gmail.com>
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
>
> Vincent I have updated this from your suggestion to use
> ILL_ILLOPC as that appears the more appropriate si_code.
> Normally I expect you could just update your nds32 tree and
> make this kind of change but since I am touching this code anyway I will
> be happy to take this change along with the others.
>
> Does this look good to you?
>

It is fine to commit this change along with the others.

Vincent Chen


>  arch/nds32/kernel/traps.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/arch/nds32/kernel/traps.c b/arch/nds32/kernel/traps.c
> index a6205fd4db52..5c2f61835ab9 100644
> --- a/arch/nds32/kernel/traps.c
> +++ b/arch/nds32/kernel/traps.c
> @@ -349,7 +349,8 @@ void do_revinsn(struct pt_regs *regs)
>         show_regs(regs);
>         if (!user_mode(regs))
>                 do_exit(SIGILL);
> -       force_sig(SIGILL, current);
> +       force_sig_fault(SIGILL, ILL_ILLOPC,
> +                       (void __user *)instruction_pointer(regs), current);
>  }
>
>  #ifdef CONFIG_ALIGNMENT_TRAP
> --
> 2.14.1
>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 0/5] Improving siginfo_layout and fixing uml's relay_signal
  2018-04-25 23:05                   ` Martin Pärtel
@ 2018-04-28 14:02                     ` Eric W. Biederman
  2018-04-28 14:06                       ` [REVIEW][PATCH 1/5] signal/signalfd: Remove __put_user from signalfd_copyinfo Eric W. Biederman
                                         ` (4 more replies)
  0 siblings, 5 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-28 14:02 UTC (permalink / raw)
  To: Linux-Arch
  Cc: Anton Ivanov, Richard Weinberger, Richard Weinberger, Jeff Dike,
	linux-um, LKML, user-mode-linux-devel, Martin Pärtel


This patchset is a respin of my latest patch to relay_signal for uml.

As I understand relay_signal it very carefully scrubs the signal
information it gets from the host kernel before passing it on.
Basically making certain it recognizes what it is dealing with.

This patchset updates siginfo_layout so that relay_signal and arm64's
force_signal_inject can reliably use it to verify the kind of signal
being processed, by recognizing the specializations of SIL_FAULT as
separate cases.

To make the siginfo_layout changes clean.  signalfd is first brought
into the modern world of using a single copy_to_user, no default case
statement (so gcc will flag missing cases), and handling SIGSYS for
seccomp.

The net is a simpler relay_signal is also more careful about which
signals it relays.

Eric

The changes are also available at:
  git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace.git siginfo-review3

Eric W. Biederman (5):
      signal/signalfd: Remove __put_user from signalfd_copyinfo
      signal/signalfd: Add support for SIGSYS
      signal: Remove unncessary #ifdef SEGV_PKUERR in 32bit compat code
      signal: Extend siginfo_layout with SIL_FAULT_{MCEERR|BNDERR|PKUERR}
      signal/um: More carefully relay signals in relay_signal.

 arch/um/kernel/trap.c         | 38 ++++++++------------
 fs/signalfd.c                 | 84 +++++++++++++++++++++++++------------------
 include/linux/signal.h        |  3 ++
 include/uapi/linux/signalfd.h |  6 +++-
 kernel/signal.c               | 82 +++++++++++++++++++++++++++---------------
 5 files changed, 125 insertions(+), 88 deletions(-)

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 1/5] signal/signalfd: Remove __put_user from signalfd_copyinfo
  2018-04-28 14:02                     ` [REVIEW][PATCH 0/5] Improving siginfo_layout and fixing uml's relay_signal Eric W. Biederman
@ 2018-04-28 14:06                       ` Eric W. Biederman
  2018-04-28 14:06                       ` [REVIEW][PATCH 2/5] signal/signalfd: Add support for SIGSYS Eric W. Biederman
                                         ` (3 subsequent siblings)
  4 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-28 14:06 UTC (permalink / raw)
  To: Linux-Arch
  Cc: Anton Ivanov, Richard Weinberger, Richard Weinberger, Jeff Dike,
	linux-um, linux-kernel, user-mode-linux-devel,
	Martin Pärtel, Eric W. Biederman

Put a signalfd_siginfo structure on the stack fully initializae
it and then copy it to userspace.

The code is a little less wordy, and this avoids a long series
of the somewhat costly __put_user calls.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/signalfd.c | 56 +++++++++++++++++++++++++++++---------------------------
 1 file changed, 29 insertions(+), 27 deletions(-)

diff --git a/fs/signalfd.c b/fs/signalfd.c
index ff302bf50be4..31e960209a08 100644
--- a/fs/signalfd.c
+++ b/fs/signalfd.c
@@ -81,41 +81,41 @@ static __poll_t signalfd_poll(struct file *file, poll_table *wait)
 static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
 			     siginfo_t const *kinfo)
 {
-	long err;
+	struct signalfd_siginfo new;
 
 	BUILD_BUG_ON(sizeof(struct signalfd_siginfo) != 128);
 
 	/*
 	 * Unused members should be zero ...
 	 */
-	err = __clear_user(uinfo, sizeof(*uinfo));
+	memset(&new, 0, sizeof(new));
 
 	/*
 	 * If you change siginfo_t structure, please be sure
 	 * this code is fixed accordingly.
 	 */
-	err |= __put_user(kinfo->si_signo, &uinfo->ssi_signo);
-	err |= __put_user(kinfo->si_errno, &uinfo->ssi_errno);
-	err |= __put_user(kinfo->si_code, &uinfo->ssi_code);
+	new.ssi_signo = kinfo->si_signo;
+	new.ssi_errno = kinfo->si_errno;
+	new.ssi_code  = kinfo->si_code;
 	switch (siginfo_layout(kinfo->si_signo, kinfo->si_code)) {
 	case SIL_KILL:
-		err |= __put_user(kinfo->si_pid, &uinfo->ssi_pid);
-		err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid);
+		new.ssi_pid = kinfo->si_pid;
+		new.ssi_uid = kinfo->si_uid;
 		break;
 	case SIL_TIMER:
-		 err |= __put_user(kinfo->si_tid, &uinfo->ssi_tid);
-		 err |= __put_user(kinfo->si_overrun, &uinfo->ssi_overrun);
-		 err |= __put_user((long) kinfo->si_ptr, &uinfo->ssi_ptr);
-		 err |= __put_user(kinfo->si_int, &uinfo->ssi_int);
+		new.ssi_tid = kinfo->si_tid;
+		new.ssi_overrun = kinfo->si_overrun;
+		new.ssi_ptr = (long) kinfo->si_ptr;
+		new.ssi_int = kinfo->si_int;
 		break;
 	case SIL_POLL:
-		err |= __put_user(kinfo->si_band, &uinfo->ssi_band);
-		err |= __put_user(kinfo->si_fd, &uinfo->ssi_fd);
+		new.ssi_band = kinfo->si_band;
+		new.ssi_fd   = kinfo->si_fd;
 		break;
 	case SIL_FAULT:
-		err |= __put_user((long) kinfo->si_addr, &uinfo->ssi_addr);
+		new.ssi_addr = (long) kinfo->si_addr;
 #ifdef __ARCH_SI_TRAPNO
-		err |= __put_user(kinfo->si_trapno, &uinfo->ssi_trapno);
+		new.ssi_trapno = kinfo->si_trapno;
 #endif
 		/*
 		 * Other callers might not initialize the si_lsb field,
@@ -124,29 +124,31 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
 		if (kinfo->si_signo == SIGBUS &&
 		    ((kinfo->si_code == BUS_MCEERR_AR) ||
 		     (kinfo->si_code == BUS_MCEERR_AO)))
-			err |= __put_user((short) kinfo->si_addr_lsb,
-					  &uinfo->ssi_addr_lsb);
+			new.ssi_addr_lsb = (short) kinfo->si_addr_lsb;
 		break;
 	case SIL_CHLD:
-		err |= __put_user(kinfo->si_pid, &uinfo->ssi_pid);
-		err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid);
-		err |= __put_user(kinfo->si_status, &uinfo->ssi_status);
-		err |= __put_user(kinfo->si_utime, &uinfo->ssi_utime);
-		err |= __put_user(kinfo->si_stime, &uinfo->ssi_stime);
+		new.ssi_pid    = kinfo->si_pid;
+		new.ssi_uid    = kinfo->si_uid;
+		new.ssi_status = kinfo->si_status;
+		new.ssi_utime  = kinfo->si_utime;
+		new.ssi_stime  = kinfo->si_stime;
 		break;
 	case SIL_RT:
 	default:
 		/*
 		 * This case catches also the signals queued by sigqueue().
 		 */
-		err |= __put_user(kinfo->si_pid, &uinfo->ssi_pid);
-		err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid);
-		err |= __put_user((long) kinfo->si_ptr, &uinfo->ssi_ptr);
-		err |= __put_user(kinfo->si_int, &uinfo->ssi_int);
+		new.ssi_pid = kinfo->si_pid;
+		new.ssi_uid = kinfo->si_uid;
+		new.ssi_ptr = (long) kinfo->si_ptr;
+		new.ssi_int = kinfo->si_int;
 		break;
 	}
 
-	return err ? -EFAULT: sizeof(*uinfo);
+	if (copy_to_user(uinfo, &new, sizeof(struct signalfd_siginfo)))
+		return -EFAULT;
+
+	return sizeof(*uinfo);
 }
 
 static ssize_t signalfd_dequeue(struct signalfd_ctx *ctx, siginfo_t *info,
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 2/5] signal/signalfd: Add support for SIGSYS
  2018-04-28 14:02                     ` [REVIEW][PATCH 0/5] Improving siginfo_layout and fixing uml's relay_signal Eric W. Biederman
  2018-04-28 14:06                       ` [REVIEW][PATCH 1/5] signal/signalfd: Remove __put_user from signalfd_copyinfo Eric W. Biederman
@ 2018-04-28 14:06                       ` Eric W. Biederman
  2018-04-28 14:07                       ` [REVIEW][PATCH 3/5] signal: Remove unncessary #ifdef SEGV_PKUERR in 32bit compat code Eric W. Biederman
                                         ` (2 subsequent siblings)
  4 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-28 14:06 UTC (permalink / raw)
  To: Linux-Arch
  Cc: Anton Ivanov, Richard Weinberger, Richard Weinberger, Jeff Dike,
	linux-um, linux-kernel, user-mode-linux-devel,
	Martin Pärtel, Eric W. Biederman

I don't know why signalfd has never grown support for SIGSYS but grow it now.

This corrects an oversight and removes a need for a default in the
switch statement.  Allowing gcc to warn when future members are added
to the enum siginfo_layout, and signalfd does not handle them.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/signalfd.c                 | 6 +++++-
 include/uapi/linux/signalfd.h | 6 +++++-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/fs/signalfd.c b/fs/signalfd.c
index 31e960209a08..f652249f59f9 100644
--- a/fs/signalfd.c
+++ b/fs/signalfd.c
@@ -134,7 +134,6 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
 		new.ssi_stime  = kinfo->si_stime;
 		break;
 	case SIL_RT:
-	default:
 		/*
 		 * This case catches also the signals queued by sigqueue().
 		 */
@@ -143,6 +142,11 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
 		new.ssi_ptr = (long) kinfo->si_ptr;
 		new.ssi_int = kinfo->si_int;
 		break;
+	case SIL_SYS:
+		new.ssi_call_addr = (long) kinfo->si_call_addr;
+		new.ssi_syscall   = kinfo->si_syscall;
+		new.ssi_arch      = kinfo->si_arch;
+		break;
 	}
 
 	if (copy_to_user(uinfo, &new, sizeof(struct signalfd_siginfo)))
diff --git a/include/uapi/linux/signalfd.h b/include/uapi/linux/signalfd.h
index 6f0da42fc5ef..83429a05b698 100644
--- a/include/uapi/linux/signalfd.h
+++ b/include/uapi/linux/signalfd.h
@@ -35,6 +35,10 @@ struct signalfd_siginfo {
 	__u64 ssi_stime;
 	__u64 ssi_addr;
 	__u16 ssi_addr_lsb;
+	__u16 __pad2;
+	__s32 ssi_syscall;
+	__u64 ssi_call_addr;
+	__u32 ssi_arch;
 
 	/*
 	 * Pad strcture to 128 bytes. Remember to update the
@@ -45,7 +49,7 @@ struct signalfd_siginfo {
 	 * comes out of a read(2) and we really don't want to have
 	 * a compat on read(2).
 	 */
-	__u8 __pad[46];
+	__u8 __pad[28];
 };
 
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 3/5] signal: Remove unncessary #ifdef SEGV_PKUERR in 32bit compat code
  2018-04-28 14:02                     ` [REVIEW][PATCH 0/5] Improving siginfo_layout and fixing uml's relay_signal Eric W. Biederman
  2018-04-28 14:06                       ` [REVIEW][PATCH 1/5] signal/signalfd: Remove __put_user from signalfd_copyinfo Eric W. Biederman
  2018-04-28 14:06                       ` [REVIEW][PATCH 2/5] signal/signalfd: Add support for SIGSYS Eric W. Biederman
@ 2018-04-28 14:07                       ` Eric W. Biederman
  2018-04-28 14:07                       ` [REVIEW][PATCH 4/5] signal: Extend siginfo_layout with SIL_FAULT_{MCEERR|BNDERR|PKUERR} Eric W. Biederman
  2018-04-28 14:07                       ` [REVIEW][PATCH 5/5] signal/um: More carefully relay signals in relay_signal Eric W. Biederman
  4 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-28 14:07 UTC (permalink / raw)
  To: Linux-Arch
  Cc: Anton Ivanov, Richard Weinberger, Richard Weinberger, Jeff Dike,
	linux-um, linux-kernel, user-mode-linux-devel,
	Martin Pärtel, Eric W. Biederman

The only architecture that does not support SEGV_PKUERR is ia64 and
ia64 has not had 32bit support since some time in 2008.  Therefore
copy_siginfo_to_user32 and copy_siginfo_from_user32 do not need to
include support for a missing SEGV_PKUERR.

Compile test on ia64.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 kernel/signal.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/kernel/signal.c b/kernel/signal.c
index b87a9c21f698..376b42f26e6d 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2888,12 +2888,9 @@ int __copy_siginfo_to_user32(struct compat_siginfo __user *to,
 			new.si_lower = ptr_to_compat(from->si_lower);
 			new.si_upper = ptr_to_compat(from->si_upper);
 		}
-#ifdef SEGV_PKUERR
 		if ((from->si_signo == SIGSEGV) &&
 		    (from->si_code == SEGV_PKUERR))
 			new.si_pkey = from->si_pkey;
-#endif
-
 		break;
 	case SIL_CHLD:
 		new.si_pid    = from->si_pid;
@@ -2968,10 +2965,8 @@ int copy_siginfo_from_user32(struct siginfo *to,
 			to->si_lower = compat_ptr(from.si_lower);
 			to->si_upper = compat_ptr(from.si_upper);
 		}
-#ifdef SEGV_PKUERR
 		if ((from.si_signo == SIGSEGV) && (from.si_code == SEGV_PKUERR))
 			to->si_pkey = from.si_pkey;
-#endif
 		break;
 	case SIL_CHLD:
 		to->si_pid    = from.si_pid;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 4/5] signal: Extend siginfo_layout with SIL_FAULT_{MCEERR|BNDERR|PKUERR}
  2018-04-28 14:02                     ` [REVIEW][PATCH 0/5] Improving siginfo_layout and fixing uml's relay_signal Eric W. Biederman
                                         ` (2 preceding siblings ...)
  2018-04-28 14:07                       ` [REVIEW][PATCH 3/5] signal: Remove unncessary #ifdef SEGV_PKUERR in 32bit compat code Eric W. Biederman
@ 2018-04-28 14:07                       ` Eric W. Biederman
  2018-04-28 14:07                       ` [REVIEW][PATCH 5/5] signal/um: More carefully relay signals in relay_signal Eric W. Biederman
  4 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-28 14:07 UTC (permalink / raw)
  To: Linux-Arch
  Cc: Anton Ivanov, Richard Weinberger, Richard Weinberger, Jeff Dike,
	linux-um, linux-kernel, user-mode-linux-devel,
	Martin Pärtel, Eric W. Biederman

Update the siginfo_layout function and enum siginfo_layout to represent
all of the possible field layouts of struct siginfo.

This allows the uses of siginfo_layout in um and arm64 where they are testing
for SIL_FAULT to be more accurate as this rules out the other cases.

Further this allows the switch statements on siginfo_layout to be simpler
if perhaps a little more wordy.  Making it easier to understand what is
actually going on.

As SIL_FAULT_BNDERR and SIL_FAULT_PKUERR are never expected to appear
in signalfd just treat them as SIL_FAULT.  To include them would take
20 extra bytes an pretty much fill up what is left of
signalfd_siginfo.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/signalfd.c          | 24 ++++++++++-----
 include/linux/signal.h |  3 ++
 kernel/signal.c        | 81 ++++++++++++++++++++++++++++++++++----------------
 3 files changed, 75 insertions(+), 33 deletions(-)

diff --git a/fs/signalfd.c b/fs/signalfd.c
index f652249f59f9..cbb42f77a2bd 100644
--- a/fs/signalfd.c
+++ b/fs/signalfd.c
@@ -112,19 +112,27 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
 		new.ssi_band = kinfo->si_band;
 		new.ssi_fd   = kinfo->si_fd;
 		break;
+	case SIL_FAULT_BNDERR:
+	case SIL_FAULT_PKUERR:
+		/*
+		 * Fall through to the SIL_FAULT case.  Both SIL_FAULT_BNDERR
+		 * and SIL_FAULT_PKUERR are only generated by faults that
+		 * deliver them synchronously to userspace.  In case someone
+		 * injects one of these signals and signalfd catches it treat
+		 * it as SIL_FAULT.
+		 */
 	case SIL_FAULT:
 		new.ssi_addr = (long) kinfo->si_addr;
 #ifdef __ARCH_SI_TRAPNO
 		new.ssi_trapno = kinfo->si_trapno;
 #endif
-		/*
-		 * Other callers might not initialize the si_lsb field,
-		 * so check explicitly for the right codes here.
-		 */
-		if (kinfo->si_signo == SIGBUS &&
-		    ((kinfo->si_code == BUS_MCEERR_AR) ||
-		     (kinfo->si_code == BUS_MCEERR_AO)))
-			new.ssi_addr_lsb = (short) kinfo->si_addr_lsb;
+		break;
+	case SIL_FAULT_MCEERR:
+		new.ssi_addr = (long) kinfo->si_addr;
+#ifdef __ARCH_SI_TRAPNO
+		new.ssi_trapno = kinfo->si_trapno;
+#endif
+		new.ssi_addr_lsb = (short) kinfo->si_addr_lsb;
 		break;
 	case SIL_CHLD:
 		new.ssi_pid    = kinfo->si_pid;
diff --git a/include/linux/signal.h b/include/linux/signal.h
index a9bc7e1b077e..3c5200137b24 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -28,6 +28,9 @@ enum siginfo_layout {
 	SIL_TIMER,
 	SIL_POLL,
 	SIL_FAULT,
+	SIL_FAULT_MCEERR,
+	SIL_FAULT_BNDERR,
+	SIL_FAULT_PKUERR,
 	SIL_CHLD,
 	SIL_RT,
 	SIL_SYS,
diff --git a/kernel/signal.c b/kernel/signal.c
index 376b42f26e6d..8a85da8aaa7c 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2820,8 +2820,19 @@ enum siginfo_layout siginfo_layout(int sig, int si_code)
 			[SIGPOLL] = { NSIGPOLL, SIL_POLL },
 			[SIGSYS]  = { NSIGSYS,  SIL_SYS },
 		};
-		if ((sig < ARRAY_SIZE(filter)) && (si_code <= filter[sig].limit))
+		if ((sig < ARRAY_SIZE(filter)) && (si_code <= filter[sig].limit)) {
 			layout = filter[sig].layout;
+			/* Handle the exceptions */
+			if ((sig == SIGBUS) &&
+			    (si_code >= BUS_MCEERR_AR) && (si_code <= BUS_MCEERR_AO))
+				layout = SIL_FAULT_MCEERR;
+			else if ((sig == SIGSEGV) && (si_code == SEGV_BNDERR))
+				layout = SIL_FAULT_BNDERR;
+#ifdef SEGV_PKUERR
+			else if ((sig == SIGSEGV) && (si_code == SEGV_PKUERR))
+				layout = SIL_FAULT_PKUERR;
+#endif
+		}
 		else if (si_code <= NSIGPOLL)
 			layout = SIL_POLL;
 	} else {
@@ -2878,19 +2889,28 @@ int __copy_siginfo_to_user32(struct compat_siginfo __user *to,
 #ifdef __ARCH_SI_TRAPNO
 		new.si_trapno = from->si_trapno;
 #endif
-		if ((from->si_signo == SIGBUS) &&
-		    ((from->si_code == BUS_MCEERR_AR) ||
-		     (from->si_code == BUS_MCEERR_AO)))
-			new.si_addr_lsb = from->si_addr_lsb;
-
-		if ((from->si_signo == SIGSEGV) &&
-		    (from->si_code == SEGV_BNDERR)) {
-			new.si_lower = ptr_to_compat(from->si_lower);
-			new.si_upper = ptr_to_compat(from->si_upper);
-		}
-		if ((from->si_signo == SIGSEGV) &&
-		    (from->si_code == SEGV_PKUERR))
-			new.si_pkey = from->si_pkey;
+		break;
+	case SIL_FAULT_MCEERR:
+		new.si_addr = ptr_to_compat(from->si_addr);
+#ifdef __ARCH_SI_TRAPNO
+		new.si_trapno = from->si_trapno;
+#endif
+		new.si_addr_lsb = from->si_addr_lsb;
+		break;
+	case SIL_FAULT_BNDERR:
+		new.si_addr = ptr_to_compat(from->si_addr);
+#ifdef __ARCH_SI_TRAPNO
+		new.si_trapno = from->si_trapno;
+#endif
+		new.si_lower = ptr_to_compat(from->si_lower);
+		new.si_upper = ptr_to_compat(from->si_upper);
+		break;
+	case SIL_FAULT_PKUERR:
+		new.si_addr = ptr_to_compat(from->si_addr);
+#ifdef __ARCH_SI_TRAPNO
+		new.si_trapno = from->si_trapno;
+#endif
+		new.si_pkey = from->si_pkey;
 		break;
 	case SIL_CHLD:
 		new.si_pid    = from->si_pid;
@@ -2956,17 +2976,28 @@ int copy_siginfo_from_user32(struct siginfo *to,
 #ifdef __ARCH_SI_TRAPNO
 		to->si_trapno = from.si_trapno;
 #endif
-		if ((from.si_signo == SIGBUS) &&
-		    ((from.si_code == BUS_MCEERR_AR) ||
-		     (from.si_code == BUS_MCEERR_AO)))
-			to->si_addr_lsb = from.si_addr_lsb;
-
-		if ((from.si_signo == SIGSEGV) && (from.si_code == SEGV_BNDERR)) {
-			to->si_lower = compat_ptr(from.si_lower);
-			to->si_upper = compat_ptr(from.si_upper);
-		}
-		if ((from.si_signo == SIGSEGV) && (from.si_code == SEGV_PKUERR))
-			to->si_pkey = from.si_pkey;
+		break;
+	case SIL_FAULT_MCEERR:
+		to->si_addr = compat_ptr(from.si_addr);
+#ifdef __ARCH_SI_TRAPNO
+		to->si_trapno = from.si_trapno;
+#endif
+		to->si_addr_lsb = from.si_addr_lsb;
+		break;
+	case SIL_FAULT_BNDERR:
+		to->si_addr = compat_ptr(from.si_addr);
+#ifdef __ARCH_SI_TRAPNO
+		to->si_trapno = from.si_trapno;
+#endif
+		to->si_lower = compat_ptr(from.si_lower);
+		to->si_upper = compat_ptr(from.si_upper);
+		break;
+	case SIL_FAULT_PKUERR:
+		to->si_addr = compat_ptr(from.si_addr);
+#ifdef __ARCH_SI_TRAPNO
+		to->si_trapno = from.si_trapno;
+#endif
+		to->si_pkey = from.si_pkey;
 		break;
 	case SIL_CHLD:
 		to->si_pid    = from.si_pid;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [REVIEW][PATCH 5/5] signal/um: More carefully relay signals in relay_signal.
  2018-04-28 14:02                     ` [REVIEW][PATCH 0/5] Improving siginfo_layout and fixing uml's relay_signal Eric W. Biederman
                                         ` (3 preceding siblings ...)
  2018-04-28 14:07                       ` [REVIEW][PATCH 4/5] signal: Extend siginfo_layout with SIL_FAULT_{MCEERR|BNDERR|PKUERR} Eric W. Biederman
@ 2018-04-28 14:07                       ` Eric W. Biederman
  4 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-04-28 14:07 UTC (permalink / raw)
  To: Linux-Arch
  Cc: Anton Ivanov, Richard Weinberger, Richard Weinberger, Jeff Dike,
	linux-um, linux-kernel, user-mode-linux-devel,
	Martin Pärtel, Eric W. Biederman

There is a bug in relay signal.  It assumes that when a signal is
relayed the signal never uses a signal independent si_code, such
as SI_USER, SI_KERNEL, SI_QUEUE, ... SI_SIGIO etc.  In practice
siginfo was assuming it was relaying a signal with the SIL_FAULT
layout.  As that is the common cases for the signals it supported
that is a reasonable assumption.

Further user mode linux must be very careful when relaying different
kinds of signals to prevent an information leak.  This means simply
increasing the kinds of signals that are handled in relay_signal
is non-trivial.

Therefore use siginfo_layout and force_sig_fault to simplify
the signal relaying in relay_signal.

By taking advantage of the fact that user mode linux only works
on x86 and x86_64 we can assume that si_trapno can be ignored,
and that si_errno is always zero.

For the signals SIGLL, SIGFPE, SIGSEGV, SIGBUS, and SIGTRAP the only
fault handler I know of that sets si_errno is SIGTRAP TRAP_HWBKPT on a
few oddball architectures.  Those architectures have been modified to
use force_sig_ptrace_errno_trap.

Similarly only a few architectures set __ARCH_SI_TRAPNO.

At the point uml supports those architectures again these additional
cases can be examined and supported if desired in relay_signal.

Cc: Jeff Dike <jdike@addtoit.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: Anton Ivanov <anton.ivanov@kot-begemot.co.uk>
Cc: Martin Pärtel <martin.partel@gmail.com>
Cc: user-mode-linux-devel@lists.sourceforge.net
Cc: linux-um@lists.infradead.org
Fixes: d3c1cfcdb43e ("um: pass siginfo to guest process")
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 arch/um/kernel/trap.c | 38 ++++++++++++++------------------------
 1 file changed, 14 insertions(+), 24 deletions(-)

diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index d18be983814a..ec9a42c14c56 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -286,9 +286,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
 
 void relay_signal(int sig, struct siginfo *si, struct uml_pt_regs *regs)
 {
-	struct faultinfo *fi;
-	struct siginfo clean_si;
-
+	int code, err;
 	if (!UPT_IS_USER(regs)) {
 		if (sig == SIGBUS)
 			printk(KERN_ERR "Bus error - the host /dev/shm or /tmp "
@@ -298,29 +296,21 @@ void relay_signal(int sig, struct siginfo *si, struct uml_pt_regs *regs)
 
 	arch_examine_signal(sig, regs);
 
-	clear_siginfo(&clean_si);
-	clean_si.si_signo = si->si_signo;
-	clean_si.si_errno = si->si_errno;
-	clean_si.si_code = si->si_code;
-	switch (sig) {
-	case SIGILL:
-	case SIGFPE:
-	case SIGSEGV:
-	case SIGBUS:
-	case SIGTRAP:
-		fi = UPT_FAULTINFO(regs);
-		clean_si.si_addr = (void __user *) FAULT_ADDRESS(*fi);
+	/* Is the signal layout for the signal known?
+	 * Signal data must be scrubbed to prevent information leaks.
+	 */
+	code = si->si_code;
+	err = si->si_errno;
+	if ((err == 0) && (siginfo_layout(sig, code) == SIL_FAULT)) {
+		struct faultinfo *fi = UPT_FAULTINFO(regs);
 		current->thread.arch.faultinfo = *fi;
-#ifdef __ARCH_SI_TRAPNO
-		clean_si.si_trapno = si->si_trapno;
-#endif
-		break;
-	default:
-		printk(KERN_ERR "Attempted to relay unknown signal %d (si_code = %d)\n",
-			sig, si->si_code);
+		force_sig_fault(sig, code, (void __user *)FAULT_ADDRESS(*fi),
+				current);
+	} else {
+		printk(KERN_ERR "Attempted to relay unknown signal %d (si_code = %d) with errno %d\n",
+		       sig, code, err);
+		force_sig(sig, current);
 	}
-
-	force_sig_info(sig, &clean_si, current);
 }
 
 void bus_handler(int sig, struct siginfo *si, struct uml_pt_regs *regs)
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [REVIEW][PATCH 08/22] signal/mips: Use force_sig_fault where appropriate
  2018-04-20 14:37   ` [REVIEW][PATCH 08/22] signal/mips: " Eric W. Biederman
@ 2018-05-09 15:14     ` Matt Redfearn
  2018-05-10  2:39       ` Eric W. Biederman
  0 siblings, 1 reply; 77+ messages in thread
From: Matt Redfearn @ 2018-05-09 15:14 UTC (permalink / raw)
  To: Eric W. Biederman, linux-arch
  Cc: linux-kernel, Ralf Baechle, James Hogan, linux-mips

Hi Eric,

On 20/04/18 15:37, Eric W. Biederman wrote:
> Filling in struct siginfo before calling force_sig_info a tedious and
> error prone process, where once in a great while the wrong fields
> are filled out, and siginfo has been inconsistently cleared.
> 
> Simplify this process by using the helper force_sig_fault.  Which
> takes as a parameters all of the information it needs, ensures
> all of the fiddly bits of filling in struct siginfo are done properly
> and then calls force_sig_info.
> 
> In short about a 5 line reduction in code for every time force_sig_info
> is called, which makes the calling function clearer.
> 
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: James Hogan <jhogan@kernel.org>
> Cc: linux-mips@linux-mips.org
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
>   arch/mips/kernel/traps.c | 65 ++++++++++++++----------------------------------
>   arch/mips/mm/fault.c     | 19 ++++----------
>   2 files changed, 23 insertions(+), 61 deletions(-)
> 
> diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
> index 967e9e4e795e..66ec4b0b484d 100644
> --- a/arch/mips/kernel/traps.c
> +++ b/arch/mips/kernel/traps.c
> @@ -699,17 +699,11 @@ 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;
> -
> -	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);
>   
> -	force_sig_info(SIGFPE, &info, current);
> +	force_sig_fault(SIGFPE, FPE_INTOVF, (void __user *)regs->cp0_epc, current);
>   	exception_exit(prev_state);
>   }
>   
> @@ -722,32 +716,27 @@ 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;
> -
> -	clear_siginfo(&si);
> -	si.si_addr = fault_addr;
> -	si.si_signo = SIGFPE;
> +	int si_code;

This is giving build errors in Linux next 
(https://storage.kernelci.org/next/master/next-20180509/mips/defconfig+kselftest/build.log)

si_code would have ended up as 0 before from the clear_siginfo(), but 
perhaps

int si_code = FPE_FLTUNK;

Would make a more sensible default?

Thanks,
Matt


>   
>   	if (fcr31 & FPU_CSR_INV_X)
> -		si.si_code = FPE_FLTINV;
> +		si_code = FPE_FLTINV;
>   	else if (fcr31 & FPU_CSR_DIV_X)
> -		si.si_code = FPE_FLTDIV;
> +		si_code = FPE_FLTDIV;
>   	else if (fcr31 & FPU_CSR_OVF_X)
> -		si.si_code = FPE_FLTOVF;
> +		si_code = FPE_FLTOVF;
>   	else if (fcr31 & FPU_CSR_UDF_X)
> -		si.si_code = FPE_FLTUND;
> +		si_code = FPE_FLTUND;
>   	else if (fcr31 & FPU_CSR_INE_X)
> -		si.si_code = FPE_FLTRES;
> +		si_code = FPE_FLTRES;
>   
> -	force_sig_info(SIGFPE, &si, tsk);
> +	force_sig_fault(SIGFPE, si_code, fault_addr, tsk);
>   }
>   
>   int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcr31)
>   {
> -	struct siginfo si;
> +	int si_code;
>   	struct vm_area_struct *vma;
>   
> -	clear_siginfo(&si);
>   	switch (sig) {
>   	case 0:
>   		return 0;
> @@ -757,23 +746,18 @@ int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcr31)
>   		return 1;
>   
>   	case SIGBUS:
> -		si.si_addr = fault_addr;
> -		si.si_signo = sig;
> -		si.si_code = BUS_ADRERR;
> -		force_sig_info(sig, &si, current);
> +		force_sig_fault(SIGBUS, BUS_ADRERR, fault_addr, current);
>   		return 1;
>   
>   	case SIGSEGV:
> -		si.si_addr = fault_addr;
> -		si.si_signo = sig;
>   		down_read(&current->mm->mmap_sem);
>   		vma = find_vma(current->mm, (unsigned long)fault_addr);
>   		if (vma && (vma->vm_start <= (unsigned long)fault_addr))
> -			si.si_code = SEGV_ACCERR;
> +			si_code = SEGV_ACCERR;
>   		else
> -			si.si_code = SEGV_MAPERR;
> +			si_code = SEGV_MAPERR;
>   		up_read(&current->mm->mmap_sem);
> -		force_sig_info(sig, &si, current);
> +		force_sig_fault(SIGSEGV, si_code, fault_addr, current);
>   		return 1;
>   
>   	default:
> @@ -896,10 +880,8 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
>   void do_trap_or_bp(struct pt_regs *regs, unsigned int code, int si_code,
>   	const char *str)
>   {
> -	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)
> @@ -921,13 +903,9 @@ void do_trap_or_bp(struct pt_regs *regs, unsigned int code, int si_code,
>   	case BRK_DIVZERO:
>   		scnprintf(b, sizeof(b), "%s instruction in kernel code", str);
>   		die_if_kernel(b, regs);
> -		if (code == BRK_DIVZERO)
> -			info.si_code = FPE_INTDIV;
> -		else
> -			info.si_code = FPE_INTOVF;
> -		info.si_signo = SIGFPE;
> -		info.si_addr = (void __user *) regs->cp0_epc;
> -		force_sig_info(SIGFPE, &info, current);
> +		force_sig_fault(SIGFPE,
> +				code == BRK_DIVZERO ? FPE_INTDIV : FPE_INTOVF,
> +				(void __user *) regs->cp0_epc, current);
>   		break;
>   	case BRK_BUG:
>   		die_if_kernel("Kernel bug detected", regs);
> @@ -952,9 +930,7 @@ void do_trap_or_bp(struct pt_regs *regs, unsigned int code, int si_code,
>   		scnprintf(b, sizeof(b), "%s instruction in kernel code", str);
>   		die_if_kernel(b, regs);
>   		if (si_code) {
> -			info.si_signo = SIGTRAP;
> -			info.si_code = si_code;
> -			force_sig_info(SIGTRAP, &info, current);
> +			force_sig_fault(SIGTRAP, si_code, NULL,	current);
>   		} else {
>   			force_sig(SIGTRAP, current);
>   		}
> @@ -1506,13 +1482,8 @@ asmlinkage void do_mdmx(struct pt_regs *regs)
>    */
>   asmlinkage void do_watch(struct pt_regs *regs)
>   {
> -	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
> @@ -1528,7 +1499,7 @@ asmlinkage void do_watch(struct pt_regs *regs)
>   	if (test_tsk_thread_flag(current, TIF_LOAD_WATCH)) {
>   		mips_read_watch_registers();
>   		local_irq_enable();
> -		force_sig_info(SIGTRAP, &info, current);
> +		force_sig_fault(SIGTRAP, TRAP_HWBKPT, NULL, current);
>   	} else {
>   		mips_clear_watch_registers();
>   		local_irq_enable();
> diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
> index 75392becd933..5f71f2b903b7 100644
> --- a/arch/mips/mm/fault.c
> +++ b/arch/mips/mm/fault.c
> @@ -42,7 +42,7 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
>   	struct task_struct *tsk = current;
>   	struct mm_struct *mm = tsk->mm;
>   	const int field = sizeof(unsigned long) * 2;
> -	siginfo_t info;
> +	int si_code;
>   	int fault;
>   	unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
>   
> @@ -63,8 +63,7 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
>   		return;
>   #endif
>   
> -	clear_siginfo(&info);
> -	info.si_code = SEGV_MAPERR;
> +	si_code = SEGV_MAPERR;
>   
>   	/*
>   	 * We fault-in kernel-space virtual memory on-demand. The
> @@ -113,7 +112,7 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
>    * we can handle it..
>    */
>   good_area:
> -	info.si_code = SEGV_ACCERR;
> +	si_code = SEGV_ACCERR;
>   
>   	if (write) {
>   		if (!(vma->vm_flags & VM_WRITE))
> @@ -224,11 +223,7 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
>   			pr_cont("\n");
>   		}
>   		current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
> -		info.si_signo = SIGSEGV;
> -		info.si_errno = 0;
> -		/* info.si_code has been set above */
> -		info.si_addr = (void __user *) address;
> -		force_sig_info(SIGSEGV, &info, tsk);
> +		force_sig_fault(SIGSEGV, si_code, (void __user *)address, tsk);
>   		return;
>   	}
>   
> @@ -284,11 +279,7 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
>   #endif
>   	current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
>   	tsk->thread.cp0_badvaddr = address;
> -	info.si_signo = SIGBUS;
> -	info.si_errno = 0;
> -	info.si_code = BUS_ADRERR;
> -	info.si_addr = (void __user *) address;
> -	force_sig_info(SIGBUS, &info, tsk);
> +	force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)address, tsk);
>   
>   	return;
>   #ifndef CONFIG_64BIT
> 

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [REVIEW][PATCH 08/22] signal/mips: Use force_sig_fault where appropriate
  2018-05-09 15:14     ` Matt Redfearn
@ 2018-05-10  2:39       ` Eric W. Biederman
  2018-05-10  7:59         ` Matt Redfearn
  0 siblings, 1 reply; 77+ messages in thread
From: Eric W. Biederman @ 2018-05-10  2:39 UTC (permalink / raw)
  To: Matt Redfearn
  Cc: linux-arch, linux-kernel, Ralf Baechle, James Hogan, linux-mips

Matt Redfearn <matt.redfearn@mips.com> writes:

> Hi Eric,
>
> On 20/04/18 15:37, Eric W. Biederman wrote:
>> Filling in struct siginfo before calling force_sig_info a tedious and
>> error prone process, where once in a great while the wrong fields
>> are filled out, and siginfo has been inconsistently cleared.
>>
>> Simplify this process by using the helper force_sig_fault.  Which
>> takes as a parameters all of the information it needs, ensures
>> all of the fiddly bits of filling in struct siginfo are done properly
>> and then calls force_sig_info.
>>
>> In short about a 5 line reduction in code for every time force_sig_info
>> is called, which makes the calling function clearer.
>>
>> Cc: Ralf Baechle <ralf@linux-mips.org>
>> Cc: James Hogan <jhogan@kernel.org>
>> Cc: linux-mips@linux-mips.org
>> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
>> ---
>>   arch/mips/kernel/traps.c | 65 ++++++++++++++----------------------------------
>>   arch/mips/mm/fault.c     | 19 ++++----------
>>   2 files changed, 23 insertions(+), 61 deletions(-)
>>
>> diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
>> index 967e9e4e795e..66ec4b0b484d 100644
>> --- a/arch/mips/kernel/traps.c
>> +++ b/arch/mips/kernel/traps.c
>> @@ -699,17 +699,11 @@ 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;
>> -
>> -	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);
>>   -	force_sig_info(SIGFPE, &info, current);
>> +	force_sig_fault(SIGFPE, FPE_INTOVF, (void __user *)regs->cp0_epc, current);
>>   	exception_exit(prev_state);
>>   }
>>   @@ -722,32 +716,27 @@ 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;
>> -
>> -	clear_siginfo(&si);
>> -	si.si_addr = fault_addr;
>> -	si.si_signo = SIGFPE;
>> +	int si_code;
>
> This is giving build errors in Linux next
> (https://storage.kernelci.org/next/master/next-20180509/mips/defconfig+kselftest/build.log)
>
> si_code would have ended up as 0 before from the clear_siginfo(), but perhaps

And si_code 0 is not a valid si_code to use with a floating point
siginfo layout.

> int si_code = FPE_FLTUNK;
>
> Would make a more sensible default?

FPE_FLTUNK would make a more sensible default.

I seem to remember someone telling me that case can never happen in
practice so I have simply not worried about it.  Perhaps I am
misremembering this.

Eric

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [REVIEW][PATCH 08/22] signal/mips: Use force_sig_fault where appropriate
  2018-05-10  2:39       ` Eric W. Biederman
@ 2018-05-10  7:59         ` Matt Redfearn
  2018-05-11  2:31           ` Eric W. Biederman
  0 siblings, 1 reply; 77+ messages in thread
From: Matt Redfearn @ 2018-05-10  7:59 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: linux-arch, linux-kernel, Ralf Baechle, James Hogan, linux-mips

Hi Eric,

On 10/05/18 03:39, Eric W. Biederman wrote:
> Matt Redfearn <matt.redfearn@mips.com> writes:
> 
>> Hi Eric,
>>
>> On 20/04/18 15:37, Eric W. Biederman wrote:
>>> Filling in struct siginfo before calling force_sig_info a tedious and
>>> error prone process, where once in a great while the wrong fields
>>> are filled out, and siginfo has been inconsistently cleared.
>>>
>>> Simplify this process by using the helper force_sig_fault.  Which
>>> takes as a parameters all of the information it needs, ensures
>>> all of the fiddly bits of filling in struct siginfo are done properly
>>> and then calls force_sig_info.
>>>
>>> In short about a 5 line reduction in code for every time force_sig_info
>>> is called, which makes the calling function clearer.
>>>
>>> Cc: Ralf Baechle <ralf@linux-mips.org>
>>> Cc: James Hogan <jhogan@kernel.org>
>>> Cc: linux-mips@linux-mips.org
>>> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
>>> ---
>>>    arch/mips/kernel/traps.c | 65 ++++++++++++++----------------------------------
>>>    arch/mips/mm/fault.c     | 19 ++++----------
>>>    2 files changed, 23 insertions(+), 61 deletions(-)
>>>
>>> diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
>>> index 967e9e4e795e..66ec4b0b484d 100644
>>> --- a/arch/mips/kernel/traps.c
>>> +++ b/arch/mips/kernel/traps.c
>>> @@ -699,17 +699,11 @@ 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;
>>> -
>>> -	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);
>>>    -	force_sig_info(SIGFPE, &info, current);
>>> +	force_sig_fault(SIGFPE, FPE_INTOVF, (void __user *)regs->cp0_epc, current);
>>>    	exception_exit(prev_state);
>>>    }
>>>    @@ -722,32 +716,27 @@ 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;
>>> -
>>> -	clear_siginfo(&si);
>>> -	si.si_addr = fault_addr;
>>> -	si.si_signo = SIGFPE;
>>> +	int si_code;
>>
>> This is giving build errors in Linux next
>> (https://storage.kernelci.org/next/master/next-20180509/mips/defconfig+kselftest/build.log)
>>
>> si_code would have ended up as 0 before from the clear_siginfo(), but perhaps
> 
> And si_code 0 is not a valid si_code to use with a floating point
> siginfo layout.
> 
>> int si_code = FPE_FLTUNK;
>>
>> Would make a more sensible default?
> 
> FPE_FLTUNK would make a more sensible default.
> 
> I seem to remember someone telling me that case can never happen in
> practice so I have simply not worried about it.  Perhaps I am
> misremembering this.

It probably can't happen in practise - but the issue is that the kernel 
doesn't even compile because -Werror=maybe-uninitialized results in a 
build error since the compiler can't know that one of the branches will 
definitely be taken to set si_code.

Thanks,
Matt

> 
> Eric
> 

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [REVIEW][PATCH 08/22] signal/mips: Use force_sig_fault where appropriate
  2018-05-10  7:59         ` Matt Redfearn
@ 2018-05-11  2:31           ` Eric W. Biederman
  0 siblings, 0 replies; 77+ messages in thread
From: Eric W. Biederman @ 2018-05-11  2:31 UTC (permalink / raw)
  To: Matt Redfearn
  Cc: linux-arch, linux-kernel, Ralf Baechle, James Hogan, linux-mips

Matt Redfearn <matt.redfearn@mips.com> writes:

> Hi Eric,
>
> On 10/05/18 03:39, Eric W. Biederman wrote:
>> Matt Redfearn <matt.redfearn@mips.com> writes:
>>
>>> Hi Eric,
>>>
>>> On 20/04/18 15:37, Eric W. Biederman wrote:
>>>> Filling in struct siginfo before calling force_sig_info a tedious and
>>>> error prone process, where once in a great while the wrong fields
>>>> are filled out, and siginfo has been inconsistently cleared.
>>>>
>>>> Simplify this process by using the helper force_sig_fault.  Which
>>>> takes as a parameters all of the information it needs, ensures
>>>> all of the fiddly bits of filling in struct siginfo are done properly
>>>> and then calls force_sig_info.
>>>>
>>>> In short about a 5 line reduction in code for every time force_sig_info
>>>> is called, which makes the calling function clearer.
>>>>
>>>> Cc: Ralf Baechle <ralf@linux-mips.org>
>>>> Cc: James Hogan <jhogan@kernel.org>
>>>> Cc: linux-mips@linux-mips.org
>>>> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
>>>> ---
>>>>    arch/mips/kernel/traps.c | 65 ++++++++++++++----------------------------------
>>>>    arch/mips/mm/fault.c     | 19 ++++----------
>>>>    2 files changed, 23 insertions(+), 61 deletions(-)
>>>>
>>>> diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
>>>> index 967e9e4e795e..66ec4b0b484d 100644
>>>> --- a/arch/mips/kernel/traps.c
>>>> +++ b/arch/mips/kernel/traps.c
>>>> @@ -699,17 +699,11 @@ 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;
>>>> -
>>>> -	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);
>>>>    -	force_sig_info(SIGFPE, &info, current);
>>>> +	force_sig_fault(SIGFPE, FPE_INTOVF, (void __user *)regs->cp0_epc, current);
>>>>    	exception_exit(prev_state);
>>>>    }
>>>>    @@ -722,32 +716,27 @@ 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;
>>>> -
>>>> -	clear_siginfo(&si);
>>>> -	si.si_addr = fault_addr;
>>>> -	si.si_signo = SIGFPE;
>>>> +	int si_code;
>>>
>>> This is giving build errors in Linux next
>>> (https://storage.kernelci.org/next/master/next-20180509/mips/defconfig+kselftest/build.log)
>>>
>>> si_code would have ended up as 0 before from the clear_siginfo(), but perhaps
>>
>> And si_code 0 is not a valid si_code to use with a floating point
>> siginfo layout.
>>
>>> int si_code = FPE_FLTUNK;
>>>
>>> Would make a more sensible default?
>>
>> FPE_FLTUNK would make a more sensible default.
>>
>> I seem to remember someone telling me that case can never happen in
>> practice so I have simply not worried about it.  Perhaps I am
>> misremembering this.
>
> It probably can't happen in practise - but the issue is that the
> kernel doesn't even compile because -Werror=maybe-uninitialized
> results in a build error since the compiler can't know that one of the
> branches will definitely be taken to set si_code.

My cross compile work.  So I don't know where that
-Werror=maybe-unitialized comes from.

I agree it is an issue.   I agree that FPE_FLTUNK is one of the good
solutions.  Another is to add a final else where you return without
doing anything.

Right now this looks like mips people issue that I have unearthed.
I could appreciate some guidance on which way mips folks would like to
handle this.

If you can point me to where the fatal error is coming from I will
definitely do something in my tree so that this is not a harmful issue.

Eric

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [REVIEW][PATCH 16/22] signal/sh: Use force_sig_fault where appropriate
  2018-04-20 14:55     ` Rich Felker
@ 2018-05-28  9:19       ` Geert Uytterhoeven
  2018-05-29 15:00         ` [PATCH] signal/sh: Stop gcc warning about an impossible case in do_divide_error Eric W. Biederman
  0 siblings, 1 reply; 77+ messages in thread
From: Geert Uytterhoeven @ 2018-05-28  9:19 UTC (permalink / raw)
  To: Rich Felker
  Cc: Eric W. Biederman, Linux-Arch, Linux Kernel Mailing List,
	Yoshinori Sato, Linux-sh list

On Fri, Apr 20, 2018 at 4:55 PM, Rich Felker <dalias@libc.org> wrote:
> On Fri, Apr 20, 2018 at 09:38:05AM -0500, Eric W. Biederman wrote:
>> Filling in struct siginfo before calling force_sig_info a tedious and
>> error prone process, where once in a great while the wrong fields
>> are filled out, and siginfo has been inconsistently cleared.
>>
>> Simplify this process by using the helper force_sig_fault.  Which
>> takes as a parameters all of the information it needs, ensures
>> all of the fiddly bits of filling in struct siginfo are done properly
>> and then calls force_sig_info.
>>
>> In short about a 5 line reduction in code for every time force_sig_info
>> is called, which makes the calling function clearer.
>>
>> Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
>> Cc: Rich Felker <dalias@libc.org>
>> Cc: linux-sh@vger.kernel.org
>> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>

>> --- a/arch/sh/kernel/traps_32.c
>> +++ b/arch/sh/kernel/traps_32.c

>> @@ -599,20 +593,17 @@ int is_dsp_inst(struct pt_regs *regs)
>>  #ifdef CONFIG_CPU_SH2A
>>  asmlinkage void do_divide_error(unsigned long r4)
>>  {
>> -     siginfo_t info;
>> +     int code;
>>
>> -     clear_siginfo(&info);
>>       switch (r4) {
>>       case TRAP_DIVZERO_ERROR:
>> -             info.si_code = FPE_INTDIV;
>> +             code = FPE_INTDIV;
>>               break;
>>       case TRAP_DIVOVF_ERROR:
>> -             info.si_code = FPE_INTOVF;
>> +             code = FPE_INTOVF;
>>               break;
>>       }
>> -
>> -     info.si_signo = SIGFPE;
>> -     force_sig_info(info.si_signo, &info, current);
>> +     force_sig_fault(SIGFPE, code, NULL, current);

/kisskb/src/arch/sh/kernel/traps_32.c:606:17: error: 'code' may be
used uninitialized in this function [-Werror=uninitialized]

http://kisskb.ellerman.id.au/kisskb/buildresult/13366052/
http://kisskb.ellerman.id.au/kisskb/buildresult/13366048/
http://kisskb.ellerman.id.au/kisskb/buildresult/13366072/

>>  }

> Acked-by: Rich Felker <dalias@libc.org>


Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [PATCH] signal/sh: Stop gcc warning about an impossible case in do_divide_error
  2018-05-28  9:19       ` Geert Uytterhoeven
@ 2018-05-29 15:00         ` Eric W. Biederman
  2018-05-30  7:54           ` Sergei Shtylyov
  0 siblings, 1 reply; 77+ messages in thread
From: Eric W. Biederman @ 2018-05-29 15:00 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Rich Felker, Linux-Arch, Linux Kernel Mailing List,
	Yoshinori Sato, Linux-sh list


Geert Uytterhoeven <geert@linux-m68k.org> reported:
>   HOSTLD  scripts/mod/modpost
>   CC      arch/sh/kernel/traps_32.o
> arch/sh/kernel/traps_32.c: In function 'do_divide_error':
> arch/sh/kernel/traps_32.c:606:17: error: 'code' may be used uninitialized in this function [-Werror=uninitialized]
> cc1: all warnings being treated as errors

It is clear from inspection that do_divide_error is only called with
TRAP_DIVZERO_ERROR or TRAP_DIVOVF_ERROR, as that is the way
set_exception_table_vec is called.  So let gcc know the other cases
should not be considered by returning in all other cases.

This removes the warning and let's the code continue to build.

Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
Fixes: c65626c0cd4d ("signal/sh: Use force_sig_fault where appropriate")
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---

I am adding this fix to my tree to at least let the code build.

 arch/sh/kernel/traps_32.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 660a4bc17698..60709ad17fc7 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -602,6 +602,9 @@ asmlinkage void do_divide_error(unsigned long r4)
 	case TRAP_DIVOVF_ERROR:
 		code = FPE_INTOVF;
 		break;
+	default:
+		/* Let gcc know unhandled cases don't make it past here */
+		return;
 	}
 	force_sig_fault(SIGFPE, code, NULL, current);
 }
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [PATCH] signal/sh: Stop gcc warning about an impossible case in do_divide_error
  2018-05-29 15:00         ` [PATCH] signal/sh: Stop gcc warning about an impossible case in do_divide_error Eric W. Biederman
@ 2018-05-30  7:54           ` Sergei Shtylyov
  0 siblings, 0 replies; 77+ messages in thread
From: Sergei Shtylyov @ 2018-05-30  7:54 UTC (permalink / raw)
  To: Eric W. Biederman, Geert Uytterhoeven
  Cc: Rich Felker, Linux-Arch, Linux Kernel Mailing List,
	Yoshinori Sato, Linux-sh list

Hello!

On 5/29/2018 6:00 PM, Eric W. Biederman wrote:

> Geert Uytterhoeven <geert@linux-m68k.org> reported:
>>    HOSTLD  scripts/mod/modpost
>>    CC      arch/sh/kernel/traps_32.o
>> arch/sh/kernel/traps_32.c: In function 'do_divide_error':
>> arch/sh/kernel/traps_32.c:606:17: error: 'code' may be used uninitialized in this function [-Werror=uninitialized]
>> cc1: all warnings being treated as errors
> 
> It is clear from inspection that do_divide_error is only called with
> TRAP_DIVZERO_ERROR or TRAP_DIVOVF_ERROR, as that is the way
> set_exception_table_vec is called.  So let gcc know the other cases
> should not be considered by returning in all other cases.
> 
> This removes the warning and let's the code continue to build.

    Lets. :-)

> Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
> Fixes: c65626c0cd4d ("signal/sh: Use force_sig_fault where appropriate")
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
[...]

MBR, Sergei

^ permalink raw reply	[flat|nested] 77+ messages in thread

end of thread, other threads:[~2018-05-30  7:55 UTC | newest]

Thread overview: 77+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-20  1:01 [REVIEW][PATCH 00/17] siginfo bugfixes and cleanups Eric W. Biederman
2018-04-20  1:03 ` [REVIEW][PATCH 01/17] signal/alpha: Document a conflict with SI_USER for SIGFPE Eric W. Biederman
2018-04-20  1:03 ` [REVIEW][PATCH 02/17] sparc: fix compat siginfo ABI regression Eric W. Biederman
2018-04-20  1:03 ` [REVIEW][PATCH 03/17] signal/sh: Use force_sig_fault in hw_breakpoint_handler Eric W. Biederman
2018-04-20  1:03 ` [REVIEW][PATCH 04/17] signal/nds32: Use force_sig in unhandled_interruption and unhandled_exceptions Eric W. Biederman
2018-04-25 12:14   ` Vincent Chen
2018-04-20  1:03 ` [REVIEW][PATCH 05/17] signal/nds32: Use force_sig(SIGILL) in do_revisn Eric W. Biederman
2018-04-25 12:10   ` Vincent Chen
2018-04-25 16:13     ` [PATCH] signal/nds32: More information in do_revinsn Eric W. Biederman
2018-04-26  3:02       ` Vincent Chen
2018-04-20  1:03 ` [REVIEW][PATCH 06/17] signal: Ensure every siginfo we send has all bits initialized Eric W. Biederman
2018-04-20  1:03 ` [REVIEW][PATCH 07/17] signal: Reduce copy_siginfo_to_user to just copy_to_user Eric W. Biederman
2018-04-20  1:03 ` [REVIEW][PATCH 08/17] signal: Stop special casing TRAP_FIXME and FPE_FIXME in siginfo_layout Eric W. Biederman
2018-04-20  1:04 ` [REVIEW][PATCH 09/17] signal: Remove SEGV_BNDERR ifdefs Eric W. Biederman
2018-04-20  1:04 ` [REVIEW][PATCH 10/17] signal: Remove ifdefs for BUS_MCEERR_AR and BUS_MCEERR_AO Eric W. Biederman
2018-04-20  1:04 ` [REVIEW][PATCH 11/17] signal/alpha: Replace FPE_FIXME with FPE_FLTUNK Eric W. Biederman
2018-04-20  1:04 ` [REVIEW][PATCH 12/17] signal/ia64: " Eric W. Biederman
2018-04-20  1:04 ` [REVIEW][PATCH 13/17] signal/powerpc: " Eric W. Biederman
2018-04-20  1:04 ` [REVIEW][PATCH 14/17] signal/unicore32: Use FPE_FLTUNK instead of 0 in ucf64_raise_sigfpe Eric W. Biederman
2018-04-20  1:04 ` [REVIEW][PATCH 15/17] signal: Add TRAP_UNK si_code for undiagnosted trap exceptions Eric W. Biederman
2018-04-20  1:04 ` [REVIEW][PATCH 16/17] signal/alpha: Replace TRAP_FIXME with TRAP_UNK Eric W. Biederman
2018-04-20  1:04 ` [REVIEW][PATCH 17/17] signal/powerpc: " Eric W. Biederman
2018-04-20 14:35 ` [REVIEW][PATCH 00/22] Simplifying siginfo users Eric W. Biederman
2018-04-20 14:37   ` [REVIEW][PATCH 01/22] signal/alpha: Use send_sig_fault where appropriate Eric W. Biederman
2018-04-20 14:37   ` [REVIEW][PATCH 02/22] signal/alpha: Use force_sig_fault " Eric W. Biederman
2018-04-20 14:37   ` [REVIEW][PATCH 03/22] signal/c6x: " Eric W. Biederman
2018-04-20 14:37   ` [REVIEW][PATCH 04/22] signal/hexagon: Use force_sig_fault as appropriate Eric W. Biederman
2018-04-20 14:37   ` [REVIEW][PATCH 05/22] signal/m68k: Use force_sig_fault where appropriate Eric W. Biederman
2018-04-20 14:37   ` [REVIEW][PATCH 06/22] signal/microblaze: Remove the commented out force_sig_info in do_page_fault Eric W. Biederman
2018-04-20 14:37   ` [REVIEW][PATCH 07/22] signal/microblaze: Use force_sig_fault where appropriate Eric W. Biederman
2018-04-20 14:37   ` [REVIEW][PATCH 08/22] signal/mips: " Eric W. Biederman
2018-05-09 15:14     ` Matt Redfearn
2018-05-10  2:39       ` Eric W. Biederman
2018-05-10  7:59         ` Matt Redfearn
2018-05-11  2:31           ` Eric W. Biederman
2018-04-20 14:37   ` [REVIEW][PATCH 09/22] signal/nds32: " Eric W. Biederman
2018-04-25 11:29     ` Vincent Chen
2018-04-25 15:57       ` Eric W. Biederman
2018-04-26  1:24         ` Greentime Hu
2018-04-20 14:37   ` [REVIEW][PATCH 10/22] signal/nios2: " Eric W. Biederman
2018-04-20 14:38   ` [REVIEW][PATCH 11/22] signal/openrisc: " Eric W. Biederman
2018-04-20 14:38   ` [REVIEW][PATCH 12/22] signal/parisc: Use force_sig_mceerr " Eric W. Biederman
2018-04-20 14:38   ` [REVIEW][PATCH 13/22] signal/parisc: Use force_sig_fault " Eric W. Biederman
2018-04-21 17:24     ` Helge Deller
2018-04-20 14:38   ` [REVIEW][PATCH 14/22] signal/riscv: " Eric W. Biederman
2018-04-21  7:25     ` Christoph Hellwig
2018-04-24 15:31       ` [REVIEW][PATCH 23/22] signal/riscv: Replace do_trap_siginfo with force_sig_fault Eric W. Biederman
2018-04-23 19:11     ` [REVIEW][PATCH 14/22] signal/riscv: Use force_sig_fault where appropriate Palmer Dabbelt
2018-04-24 15:28       ` Eric W. Biederman
2018-04-20 14:38   ` [REVIEW][PATCH 15/22] signal/s390: " Eric W. Biederman
2018-04-23  5:44     ` Martin Schwidefsky
2018-04-20 14:38   ` [REVIEW][PATCH 16/22] signal/sh: " Eric W. Biederman
2018-04-20 14:55     ` Rich Felker
2018-05-28  9:19       ` Geert Uytterhoeven
2018-05-29 15:00         ` [PATCH] signal/sh: Stop gcc warning about an impossible case in do_divide_error Eric W. Biederman
2018-05-30  7:54           ` Sergei Shtylyov
2018-04-20 14:38   ` [REVIEW][PATCH 17/22] signal/sparc: Use send_sig_fault where appropriate Eric W. Biederman
2018-04-20 14:38   ` [REVIEW][PATCH 18/22] signal/sparc: Use force_sig_fault " Eric W. Biederman
2018-04-20 14:38   ` [REVIEW][PATCH 19/22] signal/um: Use force_sig_fault in relay_signal Eric W. Biederman
2018-04-20 16:06     ` [uml-devel] " Anton Ivanov
2018-04-24  8:32       ` Richard Weinberger
2018-04-24  8:44         ` Anton Ivanov
2018-04-24 15:59           ` Eric W. Biederman
     [not found]             ` <CAMD8JhwgcWCp6c=O4-spNW1VdY5M-eAjr7M5PieeAfeTSe_4yw@mail.gmail.com>
2018-04-24 22:03               ` Martin Pärtel
2018-04-24 22:24                 ` Eric W. Biederman
2018-04-25 23:05                   ` Martin Pärtel
2018-04-28 14:02                     ` [REVIEW][PATCH 0/5] Improving siginfo_layout and fixing uml's relay_signal Eric W. Biederman
2018-04-28 14:06                       ` [REVIEW][PATCH 1/5] signal/signalfd: Remove __put_user from signalfd_copyinfo Eric W. Biederman
2018-04-28 14:06                       ` [REVIEW][PATCH 2/5] signal/signalfd: Add support for SIGSYS Eric W. Biederman
2018-04-28 14:07                       ` [REVIEW][PATCH 3/5] signal: Remove unncessary #ifdef SEGV_PKUERR in 32bit compat code Eric W. Biederman
2018-04-28 14:07                       ` [REVIEW][PATCH 4/5] signal: Extend siginfo_layout with SIL_FAULT_{MCEERR|BNDERR|PKUERR} Eric W. Biederman
2018-04-28 14:07                       ` [REVIEW][PATCH 5/5] signal/um: More carefully relay signals in relay_signal Eric W. Biederman
2018-04-20 14:38   ` [REVIEW][PATCH 20/22] signal/um: Use force_sig_fault where appropriate Eric W. Biederman
2018-04-20 14:38   ` [REVIEW][PATCH 21/22] signal/xtensa: Consistenly use SIGBUS in do_unaligned_user Eric W. Biederman
2018-04-20 16:06     ` Max Filippov
2018-04-20 14:38   ` [REVIEW][PATCH 22/22] signal/xtensa: Use force_sig_fault where appropriate Eric W. Biederman
2018-04-20 16:27     ` Max Filippov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).