From owner-svn-src-stable@freebsd.org Fri May 12 17:40:36 2017 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D2DCCD69213; Fri, 12 May 2017 17:40:36 +0000 (UTC) (envelope-from brooks@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A3657FE3; Fri, 12 May 2017 17:40:36 +0000 (UTC) (envelope-from brooks@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v4CHeZA2044724; Fri, 12 May 2017 17:40:35 GMT (envelope-from brooks@FreeBSD.org) Received: (from brooks@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v4CHeYaG044714; Fri, 12 May 2017 17:40:34 GMT (envelope-from brooks@FreeBSD.org) Message-Id: <201705121740.v4CHeYaG044714@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: brooks set sender to brooks@FreeBSD.org using -f From: Brooks Davis Date: Fri, 12 May 2017 17:40:34 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r318244 - in stable/11: lib/libc/sys sys/compat/freebsd32 sys/kern sys/sys X-SVN-Group: stable-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 12 May 2017 17:40:36 -0000 Author: brooks Date: Fri May 12 17:40:34 2017 New Revision: 318244 URL: https://svnweb.freebsd.org/changeset/base/318244 Log: 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 Modified: stable/11/lib/libc/sys/sigqueue.2 stable/11/sys/compat/freebsd32/freebsd32_misc.c stable/11/sys/compat/freebsd32/freebsd32_proto.h stable/11/sys/compat/freebsd32/freebsd32_syscall.h stable/11/sys/compat/freebsd32/freebsd32_syscalls.c stable/11/sys/compat/freebsd32/freebsd32_sysent.c stable/11/sys/compat/freebsd32/freebsd32_systrace_args.c stable/11/sys/compat/freebsd32/syscalls.master stable/11/sys/kern/kern_sig.c stable/11/sys/sys/syscallsubr.h Directory Properties: stable/11/ (props changed) Modified: stable/11/lib/libc/sys/sigqueue.2 ============================================================================== --- stable/11/lib/libc/sys/sigqueue.2 Fri May 12 15:34:59 2017 (r318243) +++ stable/11/lib/libc/sys/sigqueue.2 Fri May 12 17:40:34 2017 (r318244) @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 10, 2012 +.Dd May 5, 2017 .Dt SIGQUEUE 2 .Os .Sh NAME @@ -129,7 +129,6 @@ does not exist. .Xr kill 2 , .Xr sigaction 2 , .Xr sigpending 2 , -.Xr sigqueue 2 , .Xr sigsuspend 2 , .Xr sigtimedwait 2 , .Xr sigwait 2 , @@ -147,3 +146,18 @@ Support for .Tn POSIX realtime signal queue first appeared in .Fx 7.0 . +.Sh CAVEATS +When using +.Nm +to send signals to a process which might have a different ABI +(for instance, one is 32-bit and the other 64-bit), +the +.Va sival_int +member of +.Fa value +can be delivered reliably, but the +.Va sival_ptr +may be truncated in endian dependent ways and must not be relied on. +Further, many pointer integrity schemes disallow sending pointers to other +processes, and this technique should not be used in programs intended to +be portable. Modified: stable/11/sys/compat/freebsd32/freebsd32_misc.c ============================================================================== --- stable/11/sys/compat/freebsd32/freebsd32_misc.c Fri May 12 15:34:59 2017 (r318243) +++ stable/11/sys/compat/freebsd32/freebsd32_misc.c Fri May 12 17:40:34 2017 (r318244) @@ -2477,6 +2477,32 @@ siginfo_to_siginfo32(const siginfo_t *sr dst->si_overrun = src->si_overrun; } +#ifndef _FREEBSD32_SYSPROTO_H_ +struct freebsd32_sigqueue_args { + pid_t pid; + int signum; + /* union sigval32 */ int value; +}; +#endif +int +freebsd32_sigqueue(struct thread *td, struct freebsd32_sigqueue_args *uap) +{ + union sigval sv; + + /* + * On 32-bit ABIs, sival_int and sival_ptr are the same. + * On 64-bit little-endian ABIs, the low bits are the same. + * In 64-bit big-endian ABIs, sival_int overlaps with + * sival_ptr's HIGH bits. We choose to support sival_int + * rather than sival_ptr in this case as it seems to be + * more common. + */ + bzero(&sv, sizeof(sv)); + sv.sival_int = uap->value; + + return (kern_sigqueue(td, uap->pid, uap->signum, &sv)); +} + int freebsd32_sigtimedwait(struct thread *td, struct freebsd32_sigtimedwait_args *uap) { Modified: stable/11/sys/compat/freebsd32/freebsd32_proto.h ============================================================================== --- stable/11/sys/compat/freebsd32/freebsd32_proto.h Fri May 12 15:34:59 2017 (r318243) +++ stable/11/sys/compat/freebsd32/freebsd32_proto.h Fri May 12 17:40:34 2017 (r318244) @@ -382,6 +382,11 @@ struct freebsd32_thr_new_args { char param_l_[PADL_(struct thr_param32 *)]; struct thr_param32 * param; char param_r_[PADR_(struct thr_param32 *)]; char param_size_l_[PADL_(int)]; int param_size; char param_size_r_[PADR_(int)]; }; +struct freebsd32_sigqueue_args { + char pid_l_[PADL_(pid_t)]; pid_t pid; char pid_r_[PADR_(pid_t)]; + char signum_l_[PADL_(int)]; int signum; char signum_r_[PADR_(int)]; + char value_l_[PADL_(int)]; int value; char value_r_[PADR_(int)]; +}; struct freebsd32_kmq_open_args { char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)]; char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)]; @@ -764,6 +769,7 @@ int freebsd32_ksem_timedwait(struct thre int freebsd32_thr_suspend(struct thread *, struct freebsd32_thr_suspend_args *); int freebsd32_umtx_op(struct thread *, struct freebsd32_umtx_op_args *); int freebsd32_thr_new(struct thread *, struct freebsd32_thr_new_args *); +int freebsd32_sigqueue(struct thread *, struct freebsd32_sigqueue_args *); int freebsd32_kmq_open(struct thread *, struct freebsd32_kmq_open_args *); int freebsd32_kmq_setattr(struct thread *, struct freebsd32_kmq_setattr_args *); int freebsd32_kmq_timedreceive(struct thread *, struct freebsd32_kmq_timedreceive_args *); @@ -1230,6 +1236,7 @@ int freebsd10_freebsd32_pipe(struct thre #define FREEBSD32_SYS_AUE_freebsd32_thr_suspend AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_umtx_op AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_thr_new AUE_NULL +#define FREEBSD32_SYS_AUE_freebsd32_sigqueue AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_kmq_open AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_kmq_setattr AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_kmq_timedreceive AUE_NULL Modified: stable/11/sys/compat/freebsd32/freebsd32_syscall.h ============================================================================== --- stable/11/sys/compat/freebsd32/freebsd32_syscall.h Fri May 12 15:34:59 2017 (r318243) +++ stable/11/sys/compat/freebsd32/freebsd32_syscall.h Fri May 12 17:40:34 2017 (r318244) @@ -358,7 +358,7 @@ #define FREEBSD32_SYS_auditctl 453 #define FREEBSD32_SYS_freebsd32_umtx_op 454 #define FREEBSD32_SYS_freebsd32_thr_new 455 -#define FREEBSD32_SYS_sigqueue 456 +#define FREEBSD32_SYS_freebsd32_sigqueue 456 #define FREEBSD32_SYS_freebsd32_kmq_open 457 #define FREEBSD32_SYS_freebsd32_kmq_setattr 458 #define FREEBSD32_SYS_freebsd32_kmq_timedreceive 459 Modified: stable/11/sys/compat/freebsd32/freebsd32_syscalls.c ============================================================================== --- stable/11/sys/compat/freebsd32/freebsd32_syscalls.c Fri May 12 15:34:59 2017 (r318243) +++ stable/11/sys/compat/freebsd32/freebsd32_syscalls.c Fri May 12 17:40:34 2017 (r318244) @@ -465,7 +465,7 @@ const char *freebsd32_syscallnames[] = { "auditctl", /* 453 = auditctl */ "freebsd32_umtx_op", /* 454 = freebsd32_umtx_op */ "freebsd32_thr_new", /* 455 = freebsd32_thr_new */ - "sigqueue", /* 456 = sigqueue */ + "freebsd32_sigqueue", /* 456 = freebsd32_sigqueue */ "freebsd32_kmq_open", /* 457 = freebsd32_kmq_open */ "freebsd32_kmq_setattr", /* 458 = freebsd32_kmq_setattr */ "freebsd32_kmq_timedreceive", /* 459 = freebsd32_kmq_timedreceive */ Modified: stable/11/sys/compat/freebsd32/freebsd32_sysent.c ============================================================================== --- stable/11/sys/compat/freebsd32/freebsd32_sysent.c Fri May 12 15:34:59 2017 (r318243) +++ stable/11/sys/compat/freebsd32/freebsd32_sysent.c Fri May 12 17:40:34 2017 (r318244) @@ -508,7 +508,7 @@ struct sysent freebsd32_sysent[] = { { AS(auditctl_args), (sy_call_t *)sys_auditctl, AUE_AUDITCTL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 453 = auditctl */ { AS(freebsd32_umtx_op_args), (sy_call_t *)freebsd32_umtx_op, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 454 = freebsd32_umtx_op */ { AS(freebsd32_thr_new_args), (sy_call_t *)freebsd32_thr_new, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 455 = freebsd32_thr_new */ - { AS(sigqueue_args), (sy_call_t *)sys_sigqueue, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 456 = sigqueue */ + { AS(freebsd32_sigqueue_args), (sy_call_t *)freebsd32_sigqueue, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 456 = freebsd32_sigqueue */ { AS(freebsd32_kmq_open_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 457 = freebsd32_kmq_open */ { AS(freebsd32_kmq_setattr_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_ABSENT }, /* 458 = freebsd32_kmq_setattr */ { AS(freebsd32_kmq_timedreceive_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_ABSENT }, /* 459 = freebsd32_kmq_timedreceive */ Modified: stable/11/sys/compat/freebsd32/freebsd32_systrace_args.c ============================================================================== --- stable/11/sys/compat/freebsd32/freebsd32_systrace_args.c Fri May 12 15:34:59 2017 (r318243) +++ stable/11/sys/compat/freebsd32/freebsd32_systrace_args.c Fri May 12 17:40:34 2017 (r318244) @@ -2364,12 +2364,12 @@ systrace_args(int sysnum, void *params, *n_args = 2; break; } - /* sigqueue */ + /* freebsd32_sigqueue */ case 456: { - struct sigqueue_args *p = params; + struct freebsd32_sigqueue_args *p = params; iarg[0] = p->pid; /* pid_t */ iarg[1] = p->signum; /* int */ - uarg[2] = (intptr_t) p->value; /* void * */ + iarg[2] = p->value; /* int */ *n_args = 3; break; } @@ -7155,7 +7155,7 @@ systrace_entry_setargdesc(int sysnum, in break; }; break; - /* sigqueue */ + /* freebsd32_sigqueue */ case 456: switch(ndx) { case 0: @@ -7165,7 +7165,7 @@ systrace_entry_setargdesc(int sysnum, in p = "int"; break; case 2: - p = "void *"; + p = "int"; break; default: break; @@ -10335,7 +10335,7 @@ systrace_return_setargdesc(int sysnum, i if (ndx == 0 || ndx == 1) p = "int"; break; - /* sigqueue */ + /* freebsd32_sigqueue */ case 456: if (ndx == 0 || ndx == 1) p = "int"; Modified: stable/11/sys/compat/freebsd32/syscalls.master ============================================================================== --- stable/11/sys/compat/freebsd32/syscalls.master Fri May 12 15:34:59 2017 (r318243) +++ stable/11/sys/compat/freebsd32/syscalls.master Fri May 12 17:40:34 2017 (r318244) @@ -820,8 +820,8 @@ 455 AUE_NULL STD { int freebsd32_thr_new( \ struct thr_param32 *param, \ int param_size); } -456 AUE_NULL NOPROTO { int sigqueue(pid_t pid, int signum, \ - void *value); } +456 AUE_NULL STD { int freebsd32_sigqueue(pid_t pid, \ + int signum, int value); } 457 AUE_NULL NOSTD { int freebsd32_kmq_open( \ const char *path, int flags, mode_t mode, \ const struct mq_attr32 *attr); } Modified: stable/11/sys/kern/kern_sig.c ============================================================================== --- stable/11/sys/kern/kern_sig.c Fri May 12 15:34:59 2017 (r318243) +++ stable/11/sys/kern/kern_sig.c Fri May 12 17:40:34 2017 (r318244) @@ -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); Modified: stable/11/sys/sys/syscallsubr.h ============================================================================== --- stable/11/sys/sys/syscallsubr.h Fri May 12 15:34:59 2017 (r318243) +++ stable/11/sys/sys/syscallsubr.h Fri May 12 17:40:34 2017 (r318244) @@ -252,6 +252,8 @@ int kern_sigprocmask(struct thread *td, int kern_sigsuspend(struct thread *td, sigset_t mask); int kern_sigtimedwait(struct thread *td, sigset_t waitset, struct ksiginfo *ksi, struct timespec *timeout); +int kern_sigqueue(struct thread *td, pid_t pid, int signum, + union sigval *value); int kern_socket(struct thread *td, int domain, int type, int protocol); int kern_statat(struct thread *td, int flag, int fd, char *path, enum uio_seg pathseg, struct stat *sbp,