summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortruckman <truckman@FreeBSD.org>1998-11-11 10:04:13 +0000
committertruckman <truckman@FreeBSD.org>1998-11-11 10:04:13 +0000
commitde184682fa22833c7b18a96a136bc031ae786434 (patch)
treeb9b62a0e361f25bc4ed8f9636cce5f2fd2f12423
parent225b2f25416b4a11b425250105d4acbfc5bd5638 (diff)
downloadFreeBSD-src-de184682fa22833c7b18a96a136bc031ae786434.zip
FreeBSD-src-de184682fa22833c7b18a96a136bc031ae786434.tar.gz
Installed the second patch attached to kern/7899 with some changes suggested
by bde, a few other tweaks to get the patch to apply cleanly again and some improvements to the comments. This change closes some fairly minor security holes associated with F_SETOWN, fixes a few bugs, and removes some limitations that F_SETOWN had on tty devices. For more details, see the description on the PR. Because this patch increases the size of the proc and pgrp structures, it is necessary to re-install the includes and recompile libkvm, the vinum lkm, fstat, gcore, gdb, ipfilter, ps, top, and w. PR: kern/7899 Reviewed by: bde, elvind
-rw-r--r--sys/kern/kern_descrip.c142
-rw-r--r--sys/kern/kern_exit.c8
-rw-r--r--sys/kern/kern_proc.c10
-rw-r--r--sys/kern/kern_sig.c39
-rw-r--r--sys/kern/subr_log.c30
-rw-r--r--sys/kern/sys_generic.c33
-rw-r--r--sys/kern/sys_pipe.c26
-rw-r--r--sys/kern/sys_socket.c15
-rw-r--r--sys/kern/tty.c27
-rw-r--r--sys/kern/uipc_sockbuf.c14
-rw-r--r--sys/kern/uipc_socket.c9
-rw-r--r--sys/kern/uipc_socket2.c14
-rw-r--r--sys/net/bpf.c31
-rw-r--r--sys/net/bpfdesc.h4
-rw-r--r--sys/net/if_tun.c29
-rw-r--r--sys/net/if_tunvar.h4
-rw-r--r--sys/sys/filedesc.h32
-rw-r--r--sys/sys/pipe.h4
-rw-r--r--sys/sys/proc.h5
-rw-r--r--sys/sys/signalvar.h4
-rw-r--r--sys/sys/socketvar.h4
-rw-r--r--sys/sys/tty.h3
22 files changed, 342 insertions, 145 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index e3d736b..d2ef3e1 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_descrip.c 8.6 (Berkeley) 4/19/94
- * $Id: kern_descrip.c,v 1.54 1998/07/15 06:10:16 bde Exp $
+ * $Id: kern_descrip.c,v 1.55 1998/07/29 17:38:13 bde Exp $
*/
#include "opt_compat.h"
@@ -71,6 +71,7 @@
static MALLOC_DEFINE(M_FILEDESC, "file desc", "Open file descriptor table");
MALLOC_DEFINE(M_FILE, "file", "Open file structure");
+static MALLOC_DEFINE(M_SIGIO, "sigio", "sigio structures");
static d_open_t fdopen;
@@ -257,30 +258,13 @@ fcntl(p, uap)
return (error);
case F_GETOWN:
- if (fp->f_type == DTYPE_SOCKET) {
- p->p_retval[0] = ((struct socket *)fp->f_data)->so_pgid;
- return (0);
- }
error = (*fp->f_ops->fo_ioctl)
- (fp, TIOCGPGRP, (caddr_t)p->p_retval, p);
- p->p_retval[0] = - p->p_retval[0];
+ (fp, FIOGETOWN, (caddr_t)p->p_retval, p);
return (error);
case F_SETOWN:
- if (fp->f_type == DTYPE_SOCKET) {
- ((struct socket *)fp->f_data)->so_pgid = uap->arg;
- return (0);
- }
- if (uap->arg <= 0) {
- uap->arg = -uap->arg;
- } else {
- struct proc *p1 = pfind(uap->arg);
- if (p1 == 0)
- return (ESRCH);
- uap->arg = p1->p_pgrp->pg_id;
- }
return ((*fp->f_ops->fo_ioctl)
- (fp, TIOCSPGRP, (caddr_t)&uap->arg, p));
+ (fp, FIOSETOWN, (caddr_t)&uap->arg, p));
case F_SETLKW:
flg |= F_WAIT;
@@ -366,6 +350,124 @@ finishdup(fdp, old, new, retval)
}
/*
+ * If sigio is on the list associated with a process or process group,
+ * disable signalling from the device, remove sigio from the list and
+ * free sigio.
+ */
+void
+funsetown(sigio)
+ struct sigio *sigio;
+{
+ int s;
+
+ if (sigio == NULL)
+ return;
+ s = splhigh();
+ *(sigio->sio_myref) = NULL;
+ splx(s);
+ if (sigio->sio_pgid < 0) {
+ SLIST_REMOVE(&sigio->sio_pgrp->pg_sigiolst, sigio,
+ sigio, sio_pgsigio);
+ } else /* if ((*sigiop)->sio_pgid > 0) */ {
+ SLIST_REMOVE(&sigio->sio_proc->p_sigiolst, sigio,
+ sigio, sio_pgsigio);
+ }
+ crfree(sigio->sio_ucred);
+ FREE(sigio, M_SIGIO);
+}
+
+/* Free a list of sigio structures. */
+void
+funsetownlst(sigiolst)
+ struct sigiolst *sigiolst;
+{
+ struct sigio *sigio;
+
+ while ((sigio = sigiolst->slh_first) != NULL)
+ funsetown(sigio);
+}
+
+/*
+ * This is common code for FIOSETOWN ioctl called by fcntl(fd, F_SETOWN, arg).
+ *
+ * After permission checking, add a sigio structure to the sigio list for
+ * the process or process group.
+ */
+int
+fsetown(pgid, sigiop)
+ pid_t pgid;
+ struct sigio **sigiop;
+{
+ struct proc *proc = NULL;
+ struct pgrp *pgrp = NULL;
+ struct sigio *sigio;
+ int s;
+
+ if (pgid == 0) {
+ funsetown(*sigiop);
+ return (0);
+ } else if (pgid > 0) {
+ proc = pfind(pgid);
+ if (proc == NULL)
+ return (ESRCH);
+ /*
+ * Policy - Don't allow a process to FSETOWN a process
+ * in another session.
+ *
+ * Remove this test to allow maximum flexibility or
+ * restrict FSETOWN to the current process or process
+ * group for maximum safety.
+ */
+ else if (proc->p_session != curproc->p_session)
+ return (EPERM);
+ } else /* if (pgid < 0) */ {
+ pgrp = pgfind(-pgid);
+ if (pgrp == NULL)
+ return (ESRCH);
+ /*
+ * Policy - Don't allow a process to FSETOWN a process
+ * in another session.
+ *
+ * Remove this test to allow maximum flexibility or
+ * restrict FSETOWN to the current process or process
+ * group for maximum safety.
+ */
+ else if (pgrp->pg_session != curproc->p_session)
+ return (EPERM);
+ }
+ funsetown(*sigiop);
+ MALLOC(sigio, struct sigio *, sizeof(struct sigio), M_SIGIO,
+ M_WAITOK);
+ if (pgid > 0) {
+ SLIST_INSERT_HEAD(&proc->p_sigiolst, sigio, sio_pgsigio);
+ sigio->sio_proc = proc;
+ } else {
+ SLIST_INSERT_HEAD(&pgrp->pg_sigiolst, sigio, sio_pgsigio);
+ sigio->sio_pgrp = pgrp;
+ }
+ sigio->sio_pgid = pgid;
+ crhold(curproc->p_ucred);
+ sigio->sio_ucred = curproc->p_ucred;
+ /* It would be convenient if p_ruid was in ucred. */
+ sigio->sio_ruid = curproc->p_cred->p_ruid;
+ sigio->sio_myref = sigiop;
+ s = splhigh();
+ *sigiop = sigio;
+ splx(s);
+ return (0);
+}
+
+/*
+ * This is common code for FIOGETOWN ioctl called by fcntl(fd, F_GETOWN, arg).
+ */
+pid_t
+fgetown(sigio)
+ struct sigio *sigio;
+{
+ return (sigio != NULL ? sigio->sio_pgid : 0);
+}
+
+/*
* Close a file descriptor.
*/
#ifndef _SYS_SYSPROTO_H_
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 84ae1a1d..fd5e23e 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_exit.c 8.7 (Berkeley) 2/12/94
- * $Id: kern_exit.c,v 1.67 1998/06/05 21:44:20 dg Exp $
+ * $Id: kern_exit.c,v 1.68 1998/11/10 09:16:29 peter Exp $
*/
#include "opt_compat.h"
@@ -187,6 +187,12 @@ exit1(p, rv)
untimeout(realitexpire, (caddr_t)p, p->p_ithandle);
/*
+ * Reset any sigio structures pointing to us as a result of
+ * F_SETOWN with our pid.
+ */
+ funsetownlst(&p->p_sigiolst);
+
+ /*
* Close open files and release open-file table.
* This may block!
*/
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index d546ad7..a517358 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)kern_proc.c 8.7 (Berkeley) 2/14/95
- * $Id: kern_proc.c,v 1.37 1998/07/11 07:45:40 bde Exp $
+ * $Id: kern_proc.c,v 1.38 1998/11/09 15:07:41 truckman Exp $
*/
#include <sys/param.h>
@@ -48,6 +48,7 @@
#include <vm/vm_map.h>
#include <sys/user.h>
#include <vm/vm_zone.h>
+#include <sys/filedesc.h>
static MALLOC_DEFINE(M_PGRP, "pgrp", "process group header");
MALLOC_DEFINE(M_SESSION, "session", "session header");
@@ -243,6 +244,7 @@ enterpgrp(p, pgid, mksess)
LIST_INIT(&pgrp->pg_members);
LIST_INSERT_HEAD(PGRPHASH(pgid), pgrp, pg_hash);
pgrp->pg_jobc = 0;
+ SLIST_INIT(&pgrp->pg_sigiolst);
} else if (pgrp == p->p_pgrp)
return (0);
@@ -285,6 +287,12 @@ pgdelete(pgrp)
register struct pgrp *pgrp;
{
+ /*
+ * Reset any sigio structures pointing to us as a result of
+ * F_SETOWN with our pgid.
+ */
+ funsetownlst(&pgrp->pg_sigiolst);
+
if (pgrp->pg_session->s_ttyp != NULL &&
pgrp->pg_session->s_ttyp->t_pgrp == pgrp)
pgrp->pg_session->s_ttyp->t_pgrp = NULL;
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 290917a..29bacee 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_sig.c 8.7 (Berkeley) 4/18/94
- * $Id: kern_sig.c,v 1.47 1998/09/14 23:25:18 jdp Exp $
+ * $Id: kern_sig.c,v 1.48 1998/10/21 16:31:38 jdp Exp $
*/
#include "opt_compat.h"
@@ -86,6 +86,16 @@ SYSCTL_INT(_kern, KERN_LOGSIGEXIT, logsigexit, CTLFLAG_RW, &kern_logsigexit, 0,
(pc)->pc_ucred->cr_uid == (q)->p_ucred->cr_uid || \
((signum) == SIGCONT && (q)->p_session == (p)->p_session))
+/*
+ * Policy -- Can real uid ruid with ucred uc send a signal to process q?
+ */
+#define CANSIGIO(ruid, uc, q) \
+ ((uc)->cr_uid == 0 || \
+ (ruid) == (q)->p_cred->p_ruid || \
+ (uc)->cr_uid == (q)->p_cred->p_ruid || \
+ (ruid) == (q)->p_ucred->cr_uid || \
+ (uc)->cr_uid == (q)->p_ucred->cr_uid)
+
int sugid_coredump;
SYSCTL_INT(_kern, OID_AUTO, sugid_coredump, CTLFLAG_RW, &sugid_coredump, 0, "");
@@ -1344,3 +1354,30 @@ nosys(p, args)
psignal(p, SIGSYS);
return (EINVAL);
}
+
+/*
+ * Send a signal to a SIGIO or SIGURG to a process or process group using
+ * stored credentials rather than those of the current process.
+ */
+void
+pgsigio(sigio, signum, checkctty)
+ struct sigio *sigio;
+ int signum, checkctty;
+{
+ if (sigio == NULL)
+ return;
+
+ if (sigio->sio_pgid > 0) {
+ if (CANSIGIO(sigio->sio_ruid, sigio->sio_ucred,
+ sigio->sio_proc))
+ psignal(sigio->sio_proc, signum);
+ } else if (sigio->sio_pgid < 0) {
+ struct proc *p;
+
+ for (p = sigio->sio_pgrp->pg_members.lh_first; p != NULL;
+ p = p->p_pglist.le_next)
+ if (CANSIGIO(sigio->sio_ruid, sigio->sio_ucred, p) &&
+ (checkctty == 0 || (p->p_flag & P_CONTROLT)))
+ psignal(p, signum);
+ }
+}
diff --git a/sys/kern/subr_log.c b/sys/kern/subr_log.c
index 80193d4..01d8c4e 100644
--- a/sys/kern/subr_log.c
+++ b/sys/kern/subr_log.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)subr_log.c 8.1 (Berkeley) 6/10/93
- * $Id: subr_log.c,v 1.29 1998/05/28 09:30:20 phk Exp $
+ * $Id: subr_log.c,v 1.30 1998/06/07 17:11:38 dfr Exp $
*/
/*
@@ -51,6 +51,7 @@
#include <sys/signalvar.h>
#include <sys/kernel.h>
#include <sys/poll.h>
+#include <sys/filedesc.h>
#ifdef DEVFS
#include <sys/devfsext.h>
#endif /*DEVFS*/
@@ -75,7 +76,7 @@ static struct cdevsw log_cdevsw =
static struct logsoftc {
int sc_state; /* see above for possibilities */
struct selinfo sc_selp; /* process waiting on select call */
- int sc_pgid; /* process/group for async I/O */
+ struct sigio *sc_sigio; /* information for SIGIO */
} logsoftc;
int log_open; /* also used in log() */
@@ -90,7 +91,7 @@ logopen(dev, flags, mode, p)
if (log_open)
return (EBUSY);
log_open = 1;
- logsoftc.sc_pgid = p->p_pid; /* signal process only */
+ fsetown(p->p_pid, &logsoftc.sc_sigio); /* signal process only */
return (0);
}
@@ -104,6 +105,7 @@ logclose(dev, flag, mode, p)
log_open = 0;
logsoftc.sc_state = 0;
+ funsetown(logsoftc.sc_sigio);
return (0);
}
@@ -183,12 +185,8 @@ logwakeup()
if (!log_open)
return;
selwakeup(&logsoftc.sc_selp);
- if (logsoftc.sc_state & LOG_ASYNC) {
- if (logsoftc.sc_pgid < 0)
- gsignal(-logsoftc.sc_pgid, SIGIO);
- else if ((p = pfind(logsoftc.sc_pgid)))
- psignal(p, SIGIO);
- }
+ if ((logsoftc.sc_state & LOG_ASYNC) && logsoftc.sc_sigio != NULL)
+ pgsigio(logsoftc.sc_sigio, SIGIO, 0);
if (logsoftc.sc_state & LOG_RDWAIT) {
wakeup((caddr_t)msgbufp);
logsoftc.sc_state &= ~LOG_RDWAIT;
@@ -229,12 +227,20 @@ logioctl(dev, com, data, flag, p)
logsoftc.sc_state &= ~LOG_ASYNC;
break;
- case TIOCSPGRP:
- logsoftc.sc_pgid = *(int *)data;
+ case FIOSETOWN:
+ return (fsetown(*(int *)data, &logsoftc.sc_sigio));
+
+ case FIOGETOWN:
+ *(int *)data = fgetown(logsoftc.sc_sigio);
break;
+ /* This is deprecated, FIOSETOWN should be used instead. */
+ case TIOCSPGRP:
+ return (fsetown(-(*(int *)data), &logsoftc.sc_sigio));
+
+ /* This is deprecated, FIOGETOWN should be used instead */
case TIOCGPGRP:
- *(int *)data = logsoftc.sc_pgid;
+ *(int *)data = -fgetown(logsoftc.sc_sigio);
break;
default:
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index bb8f7a3..e16fed7 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)sys_generic.c 8.5 (Berkeley) 1/21/94
- * $Id: sys_generic.c,v 1.40 1998/08/24 08:39:38 dfr Exp $
+ * $Id: sys_generic.c,v 1.41 1998/09/05 14:30:11 bde Exp $
*/
#include "opt_ktrace.h"
@@ -469,37 +469,6 @@ ioctl(p, uap)
error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p);
break;
- case FIOSETOWN:
- tmp = *(int *)data;
- if (fp->f_type == DTYPE_SOCKET) {
- ((struct socket *)fp->f_data)->so_pgid = tmp;
- error = 0;
- break;
- }
- if (tmp <= 0) {
- tmp = -tmp;
- } else {
- struct proc *p1 = pfind(tmp);
- if (p1 == 0) {
- error = ESRCH;
- break;
- }
- tmp = p1->p_pgrp->pg_id;
- }
- error = (*fp->f_ops->fo_ioctl)
- (fp, (int)TIOCSPGRP, (caddr_t)&tmp, p);
- break;
-
- case FIOGETOWN:
- if (fp->f_type == DTYPE_SOCKET) {
- error = 0;
- *(int *)data = ((struct socket *)fp->f_data)->so_pgid;
- break;
- }
- error = (*fp->f_ops->fo_ioctl)(fp, (int)TIOCGPGRP, data, p);
- *(int *)data = -*(int *)data;
- break;
-
default:
error = (*fp->f_ops->fo_ioctl)(fp, com, data, p);
/*
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c
index 5f67897..b95cdd2 100644
--- a/sys/kern/sys_pipe.c
+++ b/sys/kern/sys_pipe.c
@@ -16,7 +16,7 @@
* 4. Modifications may be freely made to this file if the above conditions
* are met.
*
- * $Id: sys_pipe.c,v 1.43 1998/10/13 08:24:40 dg Exp $
+ * $Id: sys_pipe.c,v 1.44 1998/10/28 13:36:58 dg Exp $
*/
/*
@@ -256,7 +256,6 @@ pipeinit(cpipe)
cpipe->pipe_atime = cpipe->pipe_ctime;
cpipe->pipe_mtime = cpipe->pipe_ctime;
bzero(&cpipe->pipe_sel, sizeof cpipe->pipe_sel);
- cpipe->pipe_pgid = NO_PID;
#ifndef PIPE_NODIRECT
/*
@@ -315,12 +314,8 @@ pipeselwakeup(cpipe)
cpipe->pipe_state &= ~PIPE_SEL;
selwakeup(&cpipe->pipe_sel);
}
- if (cpipe->pipe_state & PIPE_ASYNC) {
- if (cpipe->pipe_pgid < 0)
- gsignal(-cpipe->pipe_pgid, SIGIO);
- else if ((p = pfind(cpipe->pipe_pgid)) != NULL)
- psignal(p, SIGIO);
- }
+ if ((cpipe->pipe_state & PIPE_ASYNC) && cpipe->pipe_sigio)
+ pgsigio(cpipe->pipe_sigio, SIGIO, 0);
}
/* ARGSUSED */
@@ -953,12 +948,20 @@ pipe_ioctl(fp, cmd, data, p)
*(int *)data = mpipe->pipe_buffer.cnt;
return (0);
- case TIOCSPGRP:
- mpipe->pipe_pgid = *(int *)data;
+ case FIOSETOWN:
+ return (fsetown(*(int *)data, &mpipe->pipe_sigio));
+
+ case FIOGETOWN:
+ *(int *)data = fgetown(mpipe->pipe_sigio);
return (0);
+ /* This is deprecated, FIOSETOWN should be used instead. */
+ case TIOCSPGRP:
+ return (fsetown(-(*(int *)data), &mpipe->pipe_sigio));
+
+ /* This is deprecated, FIOGETOWN should be used instead. */
case TIOCGPGRP:
- *(int *)data = mpipe->pipe_pgid;
+ *(int *)data = -fgetown(mpipe->pipe_sigio);
return (0);
}
@@ -1038,6 +1041,7 @@ pipe_close(fp, p)
{
struct pipe *cpipe = (struct pipe *)fp->f_data;
+ funsetown(cpipe->pipe_sigio);
pipeclose(cpipe);
fp->f_data = NULL;
return 0;
diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c
index 5b65bea..8cf30cd 100644
--- a/sys/kern/sys_socket.c
+++ b/sys/kern/sys_socket.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)sys_socket.c 8.1 (Berkeley) 6/10/93
- * $Id: sys_socket.c,v 1.17 1998/03/28 10:33:07 bde Exp $
+ * $Id: sys_socket.c,v 1.18 1998/06/07 17:11:40 dfr Exp $
*/
#include <sys/param.h>
@@ -44,6 +44,7 @@
#include <sys/sockio.h>
#include <sys/stat.h>
#include <sys/uio.h>
+#include <sys/filedesc.h>
#include <net/if.h>
#include <net/route.h>
@@ -114,12 +115,18 @@ soo_ioctl(fp, cmd, data, p)
*(int *)data = so->so_rcv.sb_cc;
return (0);
- case SIOCSPGRP:
- so->so_pgid = *(int *)data;
+ case FIOSETOWN:
+ return (fsetown(*(int *)data, &so->so_sigio));
+
+ case FIOGETOWN:
+ *(int *)data = fgetown(so->so_sigio);
return (0);
+ case SIOCSPGRP:
+ return (fsetown(-(*(int *)data), &so->so_sigio));
+
case SIOCGPGRP:
- *(int *)data = so->so_pgid;
+ *(int *)data = -fgetown(so->so_sigio);
return (0);
case SIOCATMARK:
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index 7d34873..8a043fd 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)tty.c 8.8 (Berkeley) 1/21/94
- * $Id: tty.c,v 1.105 1998/07/11 10:41:15 bde Exp $
+ * $Id: tty.c,v 1.106 1998/08/19 04:01:00 bde Exp $
*/
/*-
@@ -90,6 +90,7 @@
#include <sys/signalvar.h>
#include <sys/resourcevar.h>
#include <sys/malloc.h>
+#include <sys/filedesc.h>
#if NSNP > 0
#include <sys/snoop.h>
#endif
@@ -230,6 +231,7 @@ ttyclose(tp)
{
int s;
+ funsetown(tp->t_sigio);
s = spltty();
if (constty == tp)
constty = NULL;
@@ -756,6 +758,25 @@ ttioctl(tp, cmd, data, flag)
*(int *)data = ttnread(tp);
splx(s);
break;
+
+ case FIOSETOWN:
+ /*
+ * Policy -- Don't allow FIOSETOWN on someone else's
+ * controlling tty
+ */
+ if (tp->t_session != NULL && !isctty(p, tp))
+ return (ENOTTY);
+
+ error = fsetown(*(int *)data, &tp->t_sigio);
+ if (error)
+ return (error);
+ break;
+ case FIOGETOWN:
+ if (tp->t_session != NULL && !isctty(p, tp))
+ return (ENOTTY);
+ *(int *)data = fgetown(tp->t_sigio);
+ break;
+
case TIOCEXCL: /* set exclusive use of tty */
s = spltty();
SET(tp->t_state, TS_XCLUDE);
@@ -2082,8 +2103,8 @@ ttwakeup(tp)
if (tp->t_rsel.si_pid != 0)
selwakeup(&tp->t_rsel);
- if (ISSET(tp->t_state, TS_ASYNC))
- pgsignal(tp->t_pgrp, SIGIO, 1);
+ if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
+ pgsigio(tp->t_sigio, SIGIO, (tp->t_session != NULL));
wakeup(TSA_HUP_OR_INPUT(tp));
}
diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c
index 23c7751..6c55ca0 100644
--- a/sys/kern/uipc_sockbuf.c
+++ b/sys/kern/uipc_sockbuf.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93
- * $Id: uipc_socket2.c,v 1.39 1998/09/05 13:24:39 bde Exp $
+ * $Id: uipc_socket2.c,v 1.40 1998/11/04 20:22:11 fenner Exp $
*/
#include <sys/param.h>
@@ -213,7 +213,7 @@ sonewconn(head, connstatus)
so->so_state = head->so_state | SS_NOFDREF;
so->so_proto = head->so_proto;
so->so_timeo = head->so_timeo;
- so->so_pgid = head->so_pgid;
+ fsetown(fgetown(head->so_sigio), &so->so_sigio);
so->so_uid = head->so_uid;
(void) soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat);
@@ -321,12 +321,8 @@ sowakeup(so, sb)
sb->sb_flags &= ~SB_WAIT;
wakeup((caddr_t)&sb->sb_cc);
}
- if (so->so_state & SS_ASYNC) {
- if (so->so_pgid < 0)
- gsignal(-so->so_pgid, SIGIO);
- else if (so->so_pgid > 0 && (p = pfind(so->so_pgid)) != 0)
- psignal(p, SIGIO);
- }
+ if ((so->so_state & SS_ASYNC) && so->so_sigio != NULL)
+ pgsigio(so->so_sigio, SIGIO, 0);
if (sb->sb_flags & SB_UPCALL)
(*so->so_upcall)(so, so->so_upcallarg, M_DONTWAIT);
}
@@ -918,7 +914,7 @@ sotoxsocket(struct socket *so, struct xsocket *xso)
xso->so_qlimit = so->so_qlimit;
xso->so_timeo = so->so_timeo;
xso->so_error = so->so_error;
- xso->so_pgid = so->so_pgid;
+ xso->so_pgid = so->so_sigio ? so->so_sigio->sio_pgid : 0;
xso->so_oobmark = so->so_oobmark;
sbtoxsockbuf(&so->so_snd, &xso->so_snd);
sbtoxsockbuf(&so->so_rcv, &xso->so_rcv);
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 05d312f..275e94b 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94
- * $Id: uipc_socket.c,v 1.44 1998/08/31 15:34:55 wollman Exp $
+ * $Id: uipc_socket.c,v 1.45 1998/08/31 18:07:23 wollman Exp $
*/
#include <sys/param.h>
@@ -218,6 +218,7 @@ soclose(so)
int s = splnet(); /* conservative */
int error = 0;
+ funsetown(so->so_sigio);
if (so->so_options & SO_ACCEPTCONN) {
struct socket *sp, *sonext;
@@ -1182,10 +1183,8 @@ sohasoutofband(so)
{
struct proc *p;
- if (so->so_pgid < 0)
- gsignal(-so->so_pgid, SIGURG);
- else if (so->so_pgid > 0 && (p = pfind(so->so_pgid)) != 0)
- psignal(p, SIGURG);
+ if (so->so_sigio != NULL)
+ pgsigio(so->so_sigio, SIGURG, 0);
selwakeup(&so->so_rcv.sb_sel);
}
diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c
index 23c7751..6c55ca0 100644
--- a/sys/kern/uipc_socket2.c
+++ b/sys/kern/uipc_socket2.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93
- * $Id: uipc_socket2.c,v 1.39 1998/09/05 13:24:39 bde Exp $
+ * $Id: uipc_socket2.c,v 1.40 1998/11/04 20:22:11 fenner Exp $
*/
#include <sys/param.h>
@@ -213,7 +213,7 @@ sonewconn(head, connstatus)
so->so_state = head->so_state | SS_NOFDREF;
so->so_proto = head->so_proto;
so->so_timeo = head->so_timeo;
- so->so_pgid = head->so_pgid;
+ fsetown(fgetown(head->so_sigio), &so->so_sigio);
so->so_uid = head->so_uid;
(void) soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat);
@@ -321,12 +321,8 @@ sowakeup(so, sb)
sb->sb_flags &= ~SB_WAIT;
wakeup((caddr_t)&sb->sb_cc);
}
- if (so->so_state & SS_ASYNC) {
- if (so->so_pgid < 0)
- gsignal(-so->so_pgid, SIGIO);
- else if (so->so_pgid > 0 && (p = pfind(so->so_pgid)) != 0)
- psignal(p, SIGIO);
- }
+ if ((so->so_state & SS_ASYNC) && so->so_sigio != NULL)
+ pgsigio(so->so_sigio, SIGIO, 0);
if (sb->sb_flags & SB_UPCALL)
(*so->so_upcall)(so, so->so_upcallarg, M_DONTWAIT);
}
@@ -918,7 +914,7 @@ sotoxsocket(struct socket *so, struct xsocket *xso)
xso->so_qlimit = so->so_qlimit;
xso->so_timeo = so->so_timeo;
xso->so_error = so->so_error;
- xso->so_pgid = so->so_pgid;
+ xso->so_pgid = so->so_sigio ? so->so_sigio->sio_pgid : 0;
xso->so_oobmark = so->so_oobmark;
sbtoxsockbuf(&so->so_snd, &xso->so_snd);
sbtoxsockbuf(&so->so_rcv, &xso->so_rcv);
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index f9a217b..39d2d26 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -37,7 +37,7 @@
*
* @(#)bpf.c 8.2 (Berkeley) 3/28/94
*
- * $Id: bpf.c,v 1.43 1998/10/04 23:04:48 alex Exp $
+ * $Id: bpf.c,v 1.44 1998/10/08 00:32:08 alex Exp $
*/
#include "bpfilter.h"
@@ -61,6 +61,7 @@
#include <sys/filio.h>
#include <sys/sockio.h>
#include <sys/ttycom.h>
+#include <sys/filedesc.h>
#if defined(sparc) && BSD < 199103
#include <sys/stream.h>
@@ -379,6 +380,7 @@ bpfclose(dev, flags, fmt, p)
register struct bpf_d *d = &bpf_dtab[minor(dev)];
register int s;
+ funsetown(d->bd_sigio);
s = splimp();
if (d->bd_bif)
bpf_detachd(d);
@@ -537,11 +539,8 @@ bpf_wakeup(d)
struct proc *p;
wakeup((caddr_t)d);
- if (d->bd_async && d->bd_sig)
- if (d->bd_pgid > 0)
- gsignal (d->bd_pgid, d->bd_sig);
- else if (p = pfind (-d->bd_pgid))
- psignal (p, d->bd_sig);
+ if (d->bd_async && d->bd_sig && d->bd_sigio)
+ pgsigio(d->bd_sigio, d->bd_sig, 0);
#if BSD >= 199103
selwakeup(&d->bd_sel);
@@ -834,18 +833,22 @@ bpfioctl(dev, cmd, addr, flags, p)
d->bd_async = *(int *)addr;
break;
-/* N.B. ioctl (FIOSETOWN) and fcntl (F_SETOWN) both end up doing the
- equivalent of a TIOCSPGRP and hence end up here. *However* TIOCSPGRP's arg
- is a process group if it's positive and a process id if it's negative. This
- is exactly the opposite of what the other two functions want! Therefore
- there is code in ioctl and fcntl to negate the arg before calling here. */
+ case FIOSETOWN:
+ error = fsetown(*(int *)addr, &d->bd_sigio);
+ break;
+
+ case FIOGETOWN:
+ *(int *)addr = fgetown(d->bd_sigio);
+ break;
- case TIOCSPGRP: /* Process or group to send signals to */
- d->bd_pgid = *(int *)addr;
+ /* This is deprecated, FIOSETOWN should be used instead. */
+ case TIOCSPGRP:
+ error = fsetown(-(*(int *)addr), &d->bd_sigio);
break;
+ /* This is deprecated, FIOGETOWN should be used instead. */
case TIOCGPGRP:
- *(int *)addr = d->bd_pgid;
+ *(int *)addr = -fgetown(d->bd_sigio);
break;
case BIOCSRSIG: /* Set receive signal */
diff --git a/sys/net/bpfdesc.h b/sys/net/bpfdesc.h
index aa7f462..03d0def 100644
--- a/sys/net/bpfdesc.h
+++ b/sys/net/bpfdesc.h
@@ -37,7 +37,7 @@
*
* @(#)bpfdesc.h 8.1 (Berkeley) 6/10/93
*
- * $Id$
+ * $Id: bpfdesc.h,v 1.10 1997/02/22 09:40:57 peter Exp $
*/
#ifndef _NET_BPFDESC_H_
@@ -78,7 +78,7 @@ struct bpf_d {
u_char bd_immediate; /* true to return on packet arrival */
int bd_async; /* non-zero if packet reception should generate signal */
int bd_sig; /* signal to send upon packet reception */
- pid_t bd_pgid; /* process or group id for signal */
+ struct sigio * bd_sigio; /* information for SIGIO */
#if BSD < 199103
u_char bd_selcoll; /* true if selects collide */
int bd_timedout;
diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c
index e00ce0c..d62488f 100644
--- a/sys/net/if_tun.c
+++ b/sys/net/if_tun.c
@@ -30,6 +30,7 @@
#include <sys/ttycom.h>
#include <sys/poll.h>
#include <sys/signalvar.h>
+#include <sys/filedesc.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
#ifdef DEVFS
@@ -215,7 +216,7 @@ tunclose(dev, foo, bar, p)
}
splx(s);
}
- tp->tun_pgrp = 0;
+ funsetown(tp->tun_sigio);
selwakeup(&tp->tun_rsel);
TUNDEBUG ("%s%d: closed\n", ifp->if_name, ifp->if_unit);
@@ -372,12 +373,8 @@ tunoutput(ifp, m0, dst, rt)
tp->tun_flags &= ~TUN_RWAIT;
wakeup((caddr_t)tp);
}
- if (tp->tun_flags & TUN_ASYNC && tp->tun_pgrp) {
- if (tp->tun_pgrp > 0)
- gsignal(tp->tun_pgrp, SIGIO);
- else if ((p = pfind(-tp->tun_pgrp)) != 0)
- psignal(p, SIGIO);
- }
+ if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio)
+ pgsigio(tp->tun_sigio, SIGIO, 0);
selwakeup(&tp->tun_rsel);
return 0;
}
@@ -434,12 +431,22 @@ tunioctl(dev, cmd, data, flag, p)
*(int *)data = 0;
splx(s);
break;
+ case FIOSETOWN:
+ return (fsetown(*(int *)data, &tp->tun_sigio));
+
+ case FIOGETOWN:
+ *(int *)data = fgetown(tp->tun_sigio);
+ return (0);
+
+ /* This is deprecated, FIOSETOWN should be used instead. */
case TIOCSPGRP:
- tp->tun_pgrp = *(int *)data;
- break;
+ return (fsetown(-(*(int *)data), &tp->tun_sigio));
+
+ /* This is deprecated, FIOGETOWN should be used instead. */
case TIOCGPGRP:
- *(int *)data = tp->tun_pgrp;
- break;
+ *(int *)data = -fgetown(tp->tun_sigio);
+ return (0);
+
default:
return (ENOTTY);
}
diff --git a/sys/net/if_tunvar.h b/sys/net/if_tunvar.h
index c44911b..d0ef510 100644
--- a/sys/net/if_tunvar.h
+++ b/sys/net/if_tunvar.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id:$
+ * $Id: if_tunvar.h,v 1.1 1998/01/11 17:52:33 brian Exp $
*/
#ifndef _NET_IF_TUNVAR_H_
@@ -42,7 +42,7 @@ struct tun_softc {
#define TUN_READY (TUN_OPEN | TUN_INITED)
struct ifnet tun_if; /* the interface */
- int tun_pgrp; /* the process group - if any */
+ struct sigio *tun_sigio; /* information for SIGIO */
struct selinfo tun_rsel; /* read select */
struct selinfo tun_wsel; /* write select (not used) */
};
diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h
index 444c3ef..6d3fb26 100644
--- a/sys/sys/filedesc.h
+++ b/sys/sys/filedesc.h
@@ -31,12 +31,14 @@
* SUCH DAMAGE.
*
* @(#)filedesc.h 8.1 (Berkeley) 6/2/93
- * $Id: filedesc.h,v 1.12 1997/10/12 20:25:57 phk Exp $
+ * $Id: filedesc.h,v 1.13 1997/12/05 18:58:10 bde Exp $
*/
#ifndef _SYS_FILEDESC_H_
#define _SYS_FILEDESC_H_
+#include <sys/queue.h>
+
/*
* This structure is used for the management of descriptors. It may be
* shared by multiple processes.
@@ -91,6 +93,30 @@ struct filedesc0 {
*/
#define OFILESIZE (sizeof(struct file *) + sizeof(char))
+/*
+ * This structure that holds the information needed to send a SIGIO or
+ * a SIGURG signal to a process or process group when new data arrives
+ * on a device or socket. The structure is placed on an SLIST belonging
+ * to the proc or pgrp so that the entire list may be revoked when the
+ * process exits or the process group disappears.
+ */
+struct sigio {
+ union {
+ struct proc *siu_proc; /* Process to receive SIGIO/SIGURG */
+ struct pgrp *siu_pgrp; /* Process group to receive ... */
+ } sio_u;
+ SLIST_ENTRY(sigio) sio_pgsigio; /* sigio's for process or group */
+ struct sigio **sio_myref; /* location of the pointer that holds
+ * the reference to this structure */
+ struct ucred *sio_ucred; /* Current credentials */
+ uid_t sio_ruid; /* Real user id */
+ pid_t sio_pgid; /* pgid for signals */
+};
+#define sio_proc sio_u.siu_proc
+#define sio_pgrp sio_u.siu_pgrp
+
+SLIST_HEAD(sigiolst, sigio);
+
#ifdef KERNEL
/*
* Kernel global variables and routines.
@@ -109,6 +135,10 @@ void fdcloseexec __P((struct proc *p));
int getvnode __P((struct filedesc *fdp, int fd, struct file **fpp));
int fdissequential __P((struct file *));
void fdsequential __P((struct file *, int));
+pid_t fgetown __P((struct sigio *));
+int fsetown __P((pid_t, struct sigio **));
+void funsetown __P((struct sigio *));
+void funsetownlst __P((struct sigiolst *));
#endif
#endif
diff --git a/sys/sys/pipe.h b/sys/sys/pipe.h
index 7454cdf..064334d 100644
--- a/sys/sys/pipe.h
+++ b/sys/sys/pipe.h
@@ -18,7 +18,7 @@
* 5. Modifications may be freely made to this file if the above conditions
* are met.
*
- * $Id: pipe.h,v 1.9 1997/04/09 16:53:45 bde Exp $
+ * $Id: pipe.h,v 1.10 1998/03/26 20:53:26 phk Exp $
*/
#ifndef _SYS_PIPE_H_
@@ -102,7 +102,7 @@ struct pipe {
struct timespec pipe_atime; /* time of last access */
struct timespec pipe_mtime; /* time of last modify */
struct timespec pipe_ctime; /* time of status change */
- int pipe_pgid; /* process/group for async I/O */
+ struct sigio *pipe_sigio; /* information for SIGIO */
struct pipe *pipe_peer; /* link with other direction */
u_int pipe_state; /* pipe status info */
int pipe_busy; /* busy flag, mostly to handle rundown sanely */
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 6358322..82cc217 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)proc.h 8.15 (Berkeley) 5/19/95
- * $Id: proc.h,v 1.58 1998/05/28 09:30:26 phk Exp $
+ * $Id: proc.h,v 1.59 1998/11/09 15:08:04 truckman Exp $
*/
#ifndef _SYS_PROC_H_
@@ -52,6 +52,7 @@
#endif
#include <sys/ucred.h>
#include <sys/queue.h>
+#include <sys/filedesc.h> /* For struct sigiolst */
/*
* One structure allocated per session.
@@ -72,6 +73,7 @@ struct pgrp {
LIST_ENTRY(pgrp) pg_hash; /* Hash chain. */
LIST_HEAD(, proc) pg_members; /* Pointer to pgrp members. */
struct session *pg_session; /* Pointer to session. */
+ struct sigiolst pg_sigiolst; /* List of sigio sources */
pid_t pg_id; /* Pgrp id. */
int pg_jobc; /* # procs qualifying pgrp for job control */
};
@@ -161,6 +163,7 @@ struct proc {
unsigned char p_pfsflags; /* procfs flags */
char p_pad3[2]; /* padding for alignment */
register_t p_retval[2]; /* syscall aux returns */
+ struct sigiolst p_sigiolst; /* List of sigio sources */
/* End area that is zeroed on creation. */
#define p_endzero p_startcopy
diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h
index 3976a4f..1ca6bed 100644
--- a/sys/sys/signalvar.h
+++ b/sys/sys/signalvar.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)signalvar.h 8.6 (Berkeley) 2/19/95
- * $Id: signalvar.h,v 1.18 1998/03/28 10:33:23 bde Exp $
+ * $Id: signalvar.h,v 1.19 1998/09/14 05:36:51 jdp Exp $
*/
#ifndef _SYS_SIGNALVAR_H_ /* tmp for user.h */
@@ -152,6 +152,7 @@ static int sigprop[NSIG + 1] = {
#ifdef KERNEL
struct pgrp;
struct proc;
+struct sigio;
extern int sugid_coredump; /* Sysctl variable kern.sugid_coredump */
@@ -163,6 +164,7 @@ char *expand_name __P((const char*, int, int));
void gsignal __P((int pgid, int sig));
int issignal __P((struct proc *p));
void killproc __P((struct proc *p, char *why));
+void pgsigio __P((struct sigio *, int signum, int checkctty));
void pgsignal __P((struct pgrp *pgrp, int sig, int checkctty));
void postsig __P((int sig));
void psignal __P((struct proc *p, int sig));
diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h
index 3a53ca7..05cd696 100644
--- a/sys/sys/socketvar.h
+++ b/sys/sys/socketvar.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)socketvar.h 8.3 (Berkeley) 2/19/95
- * $Id: socketvar.h,v 1.29 1998/08/23 03:07:17 wollman Exp $
+ * $Id: socketvar.h,v 1.30 1998/11/05 14:28:25 dg Exp $
*/
#ifndef _SYS_SOCKETVAR_H_
@@ -77,7 +77,7 @@ struct socket {
short so_qlimit; /* max number queued connections */
short so_timeo; /* connection timeout */
u_short so_error; /* error affecting connection */
- pid_t so_pgid; /* pgid for signals */
+ struct sigio *so_sigio; /* information for SIGIO/SIGURG */
u_long so_oobmark; /* chars to oob mark */
/*
* Variables for socket buffering.
diff --git a/sys/sys/tty.h b/sys/sys/tty.h
index d3dd4df..3caca7e 100644
--- a/sys/sys/tty.h
+++ b/sys/sys/tty.h
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)tty.h 8.6 (Berkeley) 1/21/94
- * $Id: tty.h,v 1.41 1998/03/07 15:36:25 bde Exp $
+ * $Id: tty.h,v 1.42 1998/06/07 17:13:04 dfr Exp $
*/
#ifndef _SYS_TTY_H_
@@ -79,6 +79,7 @@ struct tty {
int t_timeout; /* Timeout for ttywait() */
struct pgrp *t_pgrp; /* Foreground process group. */
struct session *t_session; /* Enclosing session. */
+ struct sigio *t_sigio; /* information for SIGIO */
struct selinfo t_rsel; /* Tty read/oob select. */
struct selinfo t_wsel; /* Tty write select. */
struct termios t_termios; /* Termios state. */
OpenPOWER on IntegriCloud