aboutsummaryrefslogtreecommitdiff
path: root/sys/amd64
diff options
context:
space:
mode:
authorDmitry Chagin <dchagin@FreeBSD.org>2022-05-30 16:53:12 +0000
committerDmitry Chagin <dchagin@FreeBSD.org>2022-05-30 16:53:12 +0000
commit109fd18ad96957c25cfaa78da2f825c729e33fef (patch)
tree35ccbc5d533de143ffe68b03d480841fa2e35f95 /sys/amd64
parentc30a767c6fd6d3f19e897fb800513e75175249b9 (diff)
downloadsrc-109fd18ad96957c25cfaa78da2f825c729e33fef.tar.gz
src-109fd18ad96957c25cfaa78da2f825c729e33fef.zip
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
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/linux/linux_sysvec.c28
1 files changed, 16 insertions, 12 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);