summaryrefslogtreecommitdiffstats
path: root/fs/signalfd.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2018-04-24 20:59:47 -0500
committerEric W. Biederman <ebiederm@xmission.com>2018-04-26 19:51:14 -0500
commit31931c93dfe05a76385a443ed28244a50e915a46 (patch)
tree775adc3dc17cc2006a6106f2a783d6deb32cce64 /fs/signalfd.c
parent36a4ca3d9b5205819e4c47686cafb4e9b7ae76d3 (diff)
downloadlinux-31931c93dfe05a76385a443ed28244a50e915a46.tar.bz2
signal: Extend siginfo_layout with SIL_FAULT_{MCEERR|BNDERR|PKUERR}
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>
Diffstat (limited to 'fs/signalfd.c')
-rw-r--r--fs/signalfd.c24
1 files changed, 16 insertions, 8 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;