diff options
author | brooks <brooks@FreeBSD.org> | 2017-05-12 17:40:34 +0000 |
---|---|---|
committer | brooks <brooks@FreeBSD.org> | 2017-05-12 17:40:34 +0000 |
commit | 4d2f018c82bbae44270cd376e30c08b4f6c02b77 (patch) | |
tree | 0f8e0daf59a1e57f305f0d84eba8c812529fb7e6 /sys/kern | |
parent | 2d1b658f1483422dc496ae5fe3392b5d11b7715b (diff) | |
download | FreeBSD-src-4d2f018c82bbae44270cd376e30c08b4f6c02b77.zip FreeBSD-src-4d2f018c82bbae44270cd376e30c08b4f6c02b77.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 fc3ab29..a3ff180 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1862,33 +1862,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); |