diff options
author | brooks <brooks@FreeBSD.org> | 2017-05-15 22:50:54 +0000 |
---|---|---|
committer | brooks <brooks@FreeBSD.org> | 2017-05-15 22:50:54 +0000 |
commit | 55f52c0df184d00af839c0781e20e389b1fb1d65 (patch) | |
tree | e9b08c17737ec3e3f734a9793f494b514786b0b5 /sys/kern | |
parent | 60604a2c5e0a093503dd49542afcf9e3b586ea7c (diff) | |
download | FreeBSD-src-55f52c0df184d00af839c0781e20e389b1fb1d65.zip FreeBSD-src-55f52c0df184d00af839c0781e20e389b1fb1d65.tar.gz |
MFC r317845-r317846
r317845:
Provide a freebsd32 implementation of sigqueue()
The previous misuse of sys_sigqueue() was sending random register or
stack garbage to 64-bit targets. The freebsd32 implementation preserves
the sival_int member of value when signaling a 64-bit process.
Document the mixed ABI implementation of union sigval and the
incompability of sival_ptr with pointer integrity schemes.
Reviewed by: kib, wblock
Sponsored by: DARPA, AFRL
Differential Revision: https://reviews.freebsd.org/D10605
r317846:
Regen post r317845.
MFC with: r317845
Sponsored by: DARPA, AFRL
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_sig.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index b88bcd4..f80ac3d 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1846,33 +1846,43 @@ struct sigqueue_args { int sys_sigqueue(struct thread *td, struct sigqueue_args *uap) { + union sigval sv; + + sv.sival_ptr = uap->value; + + return (kern_sigqueue(td, uap->pid, uap->signum, &sv)); +} + +int +kern_sigqueue(struct thread *td, pid_t pid, int signum, union sigval *value) +{ ksiginfo_t ksi; struct proc *p; int error; - if ((u_int)uap->signum > _SIG_MAXSIG) + if ((u_int)signum > _SIG_MAXSIG) return (EINVAL); /* * Specification says sigqueue can only send signal to * single process. */ - if (uap->pid <= 0) + if (pid <= 0) return (EINVAL); - if ((p = pfind(uap->pid)) == NULL) { - if ((p = zpfind(uap->pid)) == NULL) + if ((p = pfind(pid)) == NULL) { + if ((p = zpfind(pid)) == NULL) return (ESRCH); } - error = p_cansignal(td, p, uap->signum); - if (error == 0 && uap->signum != 0) { + error = p_cansignal(td, p, signum); + if (error == 0 && signum != 0) { ksiginfo_init(&ksi); ksi.ksi_flags = KSI_SIGQ; - ksi.ksi_signo = uap->signum; + ksi.ksi_signo = signum; ksi.ksi_code = SI_QUEUE; ksi.ksi_pid = td->td_proc->p_pid; ksi.ksi_uid = td->td_ucred->cr_ruid; - ksi.ksi_value.sival_ptr = uap->value; + ksi.ksi_value = *value; error = pksignal(p, ksi.ksi_signo, &ksi); } PROC_UNLOCK(p); |