|
@@ -286,9 +286,7 @@ out:
|
|
|
|
|
|
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)
|