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
This commit is contained in:
truckman 1998-11-11 10:04:13 +00:00
parent 225b2f2541
commit de184682fa
22 changed files with 343 additions and 146 deletions

View File

@ -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;
@ -365,6 +349,124 @@ finishdup(fdp, old, new, retval)
return (0);
}
/*
* 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.
*/

View File

@ -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"
@ -186,6 +186,12 @@ exit1(p, rv)
if (timevalisset(&p->p_realtimer.it_value))
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!

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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:

View File

@ -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);
/*

View File

@ -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;

View File

@ -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:

View File

@ -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));
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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 TIOCSPGRP: /* Process or group to send signals to */
d->bd_pgid = *(int *)addr;
case FIOSETOWN:
error = fsetown(*(int *)addr, &d->bd_sigio);
break;
case FIOGETOWN:
*(int *)addr = fgetown(d->bd_sigio);
break;
/* 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 */

View File

@ -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;

View File

@ -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);
}

View File

@ -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) */
};

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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));

View File

@ -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.

View File

@ -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. */