git: 109fd18ad969 - main - linux(4): Properly build argument list for the signal handler
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 30 May 2022 17:04:20 UTC
The branch main has been updated by dchagin: URL: https://cgit.FreeBSD.org/src/commit/?id=109fd18ad96957c25cfaa78da2f825c729e33fef commit 109fd18ad96957c25cfaa78da2f825c729e33fef Author: Dmitry Chagin <dchagin@FreeBSD.org> AuthorDate: 2022-05-30 16:53:12 +0000 Commit: Dmitry Chagin <dchagin@FreeBSD.org> CommitDate: 2022-05-30 16:53:12 +0000 linux(4): Properly build argument list for the signal handler Provide arguments 2 and 3 if signal handler installed with SA_SIGINFO. MFC after: 2 weeks --- sys/amd64/linux/linux_sysvec.c | 28 ++++++++++++++++------------ sys/arm64/linux/linux_sysvec.c | 12 +++++++++--- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c index 4cd41b364b95..25fc8b10e903 100644 --- a/sys/amd64/linux/linux_sysvec.c +++ b/sys/amd64/linux/linux_sysvec.c @@ -558,13 +558,14 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) caddr_t sp; struct trapframe *regs; int sig, code; - int oonstack; + int oonstack, issiginfo; td = curthread; p = td->td_proc; PROC_LOCK_ASSERT(p, MA_OWNED); sig = linux_translate_traps(ksi->ksi_signo, ksi->ksi_trapno); psp = p->p_sigacts; + issiginfo = SIGISMEMBER(psp->ps_siginfo, sig); code = ksi->ksi_code; mtx_assert(&psp->ps_mtx, MA_OWNED); regs = td->td_frame; @@ -616,22 +617,14 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) /* Align to 16 bytes. */ sfp = (struct l_rt_sigframe *)((unsigned long)sp & ~0xFul); + mtx_unlock(&psp->ps_mtx); + PROC_UNLOCK(p); + /* Translate the signal. */ sig = bsd_to_linux_signal(sig); - - /* Build the argument list for the signal handler. */ - regs->tf_rdi = sig; /* arg 1 in %rdi */ - regs->tf_rax = 0; - regs->tf_rsi = (register_t)&sfp->sf_si; /* arg 2 in %rsi */ - regs->tf_rdx = (register_t)&sfp->sf_uc; /* arg 3 in %rdx */ - regs->tf_rcx = (register_t)catcher; - /* Fill in POSIX parts. */ siginfo_to_lsiginfo(&ksi->ksi_info, &sf.sf_si, sig); - mtx_unlock(&psp->ps_mtx); - PROC_UNLOCK(p); - /* Copy the sigframe out to the user's stack. */ if (copyout(&sf, sfp, sizeof(*sfp)) != 0) { uprintf("pid %d comm %s has trashed its stack, killing\n", @@ -640,6 +633,17 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) sigexit(td, SIGILL); } + /* Build the argument list for the signal handler. */ + regs->tf_rdi = sig; /* arg 1 in %rdi */ + regs->tf_rax = 0; + if (issiginfo) { + regs->tf_rsi = (register_t)&sfp->sf_si; /* arg 2 in %rsi */ + regs->tf_rdx = (register_t)&sfp->sf_uc; /* arg 3 in %rdx */ + } else { + regs->tf_rsi = 0; + regs->tf_rdx = 0; + } + regs->tf_rcx = (register_t)catcher; regs->tf_rsp = (long)sfp; regs->tf_rip = linux_rt_sigcode; regs->tf_rflags &= ~(PSL_T | PSL_D); diff --git a/sys/arm64/linux/linux_sysvec.c b/sys/arm64/linux/linux_sysvec.c index 72465285dfed..732eddf0c308 100644 --- a/sys/arm64/linux/linux_sysvec.c +++ b/sys/arm64/linux/linux_sysvec.c @@ -430,7 +430,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) ucontext_t uc; uint8_t *scr; struct sigacts *psp; - int onstack, sig; + int onstack, sig, issiginfo; td = curthread; p = td->td_proc; @@ -442,6 +442,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) tf = td->td_frame; onstack = sigonstack(tf->tf_sp); + issiginfo = SIGISMEMBER(psp->ps_siginfo, sig); CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm, catcher, sig); @@ -528,8 +529,13 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) free(frame, M_LINUX); tf->tf_x[0]= sig; - tf->tf_x[1] = (register_t)&fp->sf.sf_si; - tf->tf_x[2] = (register_t)&fp->sf.sf_uc; + if (issiginfo) { + tf->tf_x[1] = (register_t)&fp->sf.sf_si; + tf->tf_x[2] = (register_t)&fp->sf.sf_uc; + } else { + tf->tf_x[1] = 0; + tf->tf_x[2] = 0; + } tf->tf_x[8] = (register_t)catcher; tf->tf_sp = (register_t)fp; tf->tf_elr = (register_t)linux_vdso_sigcode;