--- //depot/vendor/freebsd/src/sys/kern/kern_mac.c	2003/11/16 15:35:29
+++ //depot/user/rwatson/pipe/sys/kern/kern_mac.c	2004/01/31 15:47:02
@@ -745,7 +745,7 @@
 		pipe = fp->f_data;
 		intlabel = mac_pipe_label_alloc();
 		PIPE_LOCK(pipe);
-		mac_copy_pipe_label(pipe->pipe_label, intlabel);
+		mac_copy_pipe_label(pipe->pipe_pair->pp_label, intlabel);
 		PIPE_UNLOCK(pipe);
 		error = mac_externalize_pipe_label(intlabel, elements,
 		    buffer, mac.m_buflen);
@@ -953,8 +953,8 @@
 		if (error == 0) {
 			pipe = fp->f_data;
 			PIPE_LOCK(pipe);
-			error = mac_pipe_label_set(td->td_ucred, pipe,
-			    intlabel);
+			error = mac_pipe_label_set(td->td_ucred,
+			    pipe->pipe_pair, intlabel);
 			PIPE_UNLOCK(pipe);
 		}
 		mac_pipe_label_free(intlabel);
--- //depot/vendor/freebsd/src/sys/kern/sys_pipe.c	2004/01/31 15:05:28
+++ //depot/user/rwatson/pipe/sys/kern/sys_pipe.c	2004/01/31 18:51:43
@@ -179,7 +179,7 @@
 static void pipeinit(void *dummy __unused);
 static void pipeclose(struct pipe *cpipe);
 static void pipe_free_kmem(struct pipe *cpipe);
-static int pipe_create(struct pipe **cpipep);
+static int pipe_create(struct pipe *pipe);
 static __inline int pipelock(struct pipe *cpipe, int catch);
 static __inline void pipeunlock(struct pipe *cpipe);
 static __inline void pipeselwakeup(struct pipe *cpipe);
@@ -191,6 +191,11 @@
 #endif
 static int pipespace(struct pipe *cpipe, int size);
 
+static void	pipe_zone_ctor(void *mem, int size, void *arg);
+static void	pipe_zone_dtor(void *mem, int size, void *arg);
+static void	pipe_zone_init(void *mem, int size);
+static void	pipe_zone_fini(void *mem, int size);
+
 static uma_zone_t pipe_zone;
 
 SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_ANY, pipeinit, NULL);
@@ -199,13 +204,96 @@
 pipeinit(void *dummy __unused)
 {
 
-	pipe_zone = uma_zcreate("PIPE", sizeof(struct pipe), NULL,
-	    NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
+	pipe_zone = uma_zcreate("PIPE", sizeof(struct pipepair),
+	    pipe_zone_ctor, pipe_zone_dtor, pipe_zone_init, pipe_zone_fini,
+	    UMA_ALIGN_PTR, 0);
 	KASSERT(pipe_zone != NULL, ("pipe_zone not initialized"));
 }
 
+static void
+pipe_zone_ctor(void *mem, int size, void *arg)
+{
+	struct pipepair *pp;
+	struct pipe *rpipe, *wpipe;
+
+	KASSERT(size == sizeof(*pp), ("pipe_zone_ctor: wrong size"));
+
+	pp = (struct pipepair *)mem;
+
+	/*
+	 * We zero both pipe endpoints to make sure all the kmem pointers
+	 * are NULL, flag fields are zero'd, etc.  We timestamp both
+	 * endpoints with the same time.
+	 */
+	rpipe = &pp->pp_rpipe;
+	bzero(rpipe, sizeof(*rpipe));
+	vfs_timestamp(&rpipe->pipe_ctime);
+	rpipe->pipe_atime = rpipe->pipe_mtime = rpipe->pipe_ctime;
+
+	wpipe = &pp->pp_wpipe;
+	bzero(wpipe, sizeof(*wpipe));
+	wpipe->pipe_ctime = rpipe->pipe_ctime;
+	wpipe->pipe_atime = wpipe->pipe_mtime = rpipe->pipe_ctime;
+
+	rpipe->pipe_peer = wpipe;
+	rpipe->pipe_pair = pp;
+	wpipe->pipe_peer = rpipe;
+	wpipe->pipe_pair = pp;
+
+	/*
+	 * Mark both endpoints as present; they will later get free'd
+	 * one at a time.  When both are free'd, then the whole pair
+	 * is released.
+	 */
+	rpipe->pipe_present = 1;
+	wpipe->pipe_present = 1;
+
+	/*
+	 * Eventually, the MAC Framework may initialize the label
+	 * in ctor or init, but for now we do it elswhere to avoid
+	 * blocking in ctor or init.
+	 */
+	pp->pp_label = NULL;
+
+}
+
+static void
+pipe_zone_dtor(void *mem, int size, void *arg)
+{
+	struct pipepair *pp;
+
+	KASSERT(size == sizeof(*pp), ("pipe_zone_dtor: wrong size"));
+
+	pp = (struct pipepair *)mem;
+}
+
+static void
+pipe_zone_init(void *mem, int size)
+{
+	struct pipepair *pp;
+
+	KASSERT(size == sizeof(*pp), ("pipe_zone_init: wrong size"));
+
+	pp = (struct pipepair *)mem;
+
+	mtx_init(&pp->pp_mtx, "pipe mutex", NULL, MTX_DEF | MTX_RECURSE);
+}
+
+static void
+pipe_zone_fini(void *mem, int size)
+{
+	struct pipepair *pp;
+
+	KASSERT(size == sizeof(*pp), ("pipe_zone_fini: wrong size"));
+
+	pp = (struct pipepair *)mem;
+
+	mtx_destroy(&pp->pp_mtx);
+}
+
 /*
- * The pipe system call for the DTYPE_PIPE type of pipes
+ * The pipe system call for the DTYPE_PIPE type of pipes.  If we fail,
+ * let the zone pick up the pieces via pipeclose().
  */
 
 /* ARGSUSED */
@@ -218,12 +306,25 @@
 {
 	struct filedesc *fdp = td->td_proc->p_fd;
 	struct file *rf, *wf;
+	struct pipepair *pp;
 	struct pipe *rpipe, *wpipe;
-	struct mtx *pmtx;
 	int fd, error;
 
-	rpipe = wpipe = NULL;
-	if (pipe_create(&rpipe) || pipe_create(&wpipe)) {
+	pp = uma_zalloc(pipe_zone, M_WAITOK);
+#ifdef MAC
+	/*
+	 * struct pipe represents a pipe endpoint.  The MAC label is shared
+	 * between the connected endpoints.  As a result mac_init_pipe() and
+	 * mac_create_pipe() should only be called on one of the endpoints
+	 * after they have been connected.
+	 */
+	mac_init_pipe(pp);
+	mac_create_pipe(td->td_ucred, pp);
+#endif
+	rpipe = &pp->pp_rpipe;
+	wpipe = &pp->pp_wpipe;
+
+	if (pipe_create(rpipe) || pipe_create(wpipe)) {
 		pipeclose(rpipe);
 		pipeclose(wpipe);
 		return (ENFILE);
@@ -278,21 +379,6 @@
 	FILE_UNLOCK(wf);
 	fdrop(wf, td);
 	td->td_retval[1] = fd;
-	rpipe->pipe_peer = wpipe;
-	wpipe->pipe_peer = rpipe;
-#ifdef MAC
-	/*
-	 * struct pipe represents a pipe endpoint.  The MAC label is shared
-	 * between the connected endpoints.  As a result mac_init_pipe() and
-	 * mac_create_pipe() should only be called on one of the endpoints
-	 * after they have been connected.
-	 */
-	mac_init_pipe(rpipe);
-	mac_create_pipe(td->td_ucred, rpipe);
-#endif
-	pmtx = malloc(sizeof(*pmtx), M_TEMP, M_WAITOK | M_ZERO);
-	mtx_init(pmtx, "pipe mutex", NULL, MTX_DEF | MTX_RECURSE);
-	rpipe->pipe_mtxp = wpipe->pipe_mtxp = pmtx;
 	fdrop(rf, td);
 
 	return (0);
@@ -314,8 +400,7 @@
 	static int curfail = 0;
 	static struct timeval lastfail;
 
-	KASSERT(cpipe->pipe_mtxp == NULL || !mtx_owned(PIPE_MTX(cpipe)),
-	       ("pipespace: pipe mutex locked"));
+	KASSERT(!mtx_owned(PIPE_MTX(cpipe)), ("pipespace: pipe mutex locked"));
 
 	size = round_page(size);
 	/*
@@ -349,60 +434,28 @@
 }
 
 /*
- * initialize and allocate VM and memory for pipe
+ * Initialize and allocate VM and memory for pipe.  The structure
+ * will start out zero'd from the ctor, so we just manage the kmem.
  */
 static int
-pipe_create(cpipep)
-	struct pipe **cpipep;
+pipe_create(pipe)
+	struct pipe *pipe;
 {
-	struct pipe *cpipe;
 	int error;
 
-	*cpipep = uma_zalloc(pipe_zone, M_WAITOK);
-	if (*cpipep == NULL)
-		return (ENOMEM);
-
-	cpipe = *cpipep;
-
-	/*
-	 * protect so pipeclose() doesn't follow a junk pointer
-	 * if pipespace() fails.
-	 */
-	bzero(&cpipe->pipe_sel, sizeof(cpipe->pipe_sel));
-	cpipe->pipe_state = 0;
-	cpipe->pipe_peer = NULL;
-	cpipe->pipe_busy = 0;
-
-#ifndef PIPE_NODIRECT
-	/*
-	 * pipe data structure initializations to support direct pipe I/O
-	 */
-	cpipe->pipe_map.cnt = 0;
-	cpipe->pipe_map.kva = 0;
-	cpipe->pipe_map.pos = 0;
-	cpipe->pipe_map.npages = 0;
-	/* cpipe->pipe_map.ms[] = invalid */
-#endif
-
-	cpipe->pipe_mtxp = NULL;	/* avoid pipespace assertion */
 	/*
 	 * Reduce to 1/4th pipe size if we're over our global max.
 	 */
 	if (amountpipekva > maxpipekva / 2)
-		error = pipespace(cpipe, SMALL_PIPE_SIZE);
+		error = pipespace(pipe, SMALL_PIPE_SIZE);
 	else
-		error = pipespace(cpipe, PIPE_SIZE);
+		error = pipespace(pipe, PIPE_SIZE);
 	if (error)
 		return (error);
 
-	vfs_timestamp(&cpipe->pipe_ctime);
-	cpipe->pipe_atime = cpipe->pipe_ctime;
-	cpipe->pipe_mtime = cpipe->pipe_ctime;
-
 	return (0);
 }
 
-
 /*
  * lock a pipe for I/O, blocking other access
  */
@@ -477,7 +530,7 @@
 		goto unlocked_error;
 
 #ifdef MAC
-	error = mac_check_pipe_read(active_cred, rpipe);
+	error = mac_check_pipe_read(active_cred, rpipe->pipe_pair);
 	if (error)
 		goto locked_error;
 #endif
@@ -890,7 +943,7 @@
 		return (EPIPE);
 	}
 #ifdef MAC
-	error = mac_check_pipe_write(active_cred, wpipe);
+	error = mac_check_pipe_write(active_cred, wpipe->pipe_pair);
 	if (error) {
 		PIPE_UNLOCK(rpipe);
 		return (error);
@@ -1180,7 +1233,7 @@
 	PIPE_LOCK(mpipe);
 
 #ifdef MAC
-	error = mac_check_pipe_ioctl(active_cred, mpipe, cmd, data);
+	error = mac_check_pipe_ioctl(active_cred, mpipe->pipe_pair, cmd, data);
 	if (error) {
 		PIPE_UNLOCK(mpipe);
 		return (error);
@@ -1252,7 +1305,7 @@
 	wpipe = rpipe->pipe_peer;
 	PIPE_LOCK(rpipe);
 #ifdef MAC
-	error = mac_check_pipe_poll(active_cred, rpipe);
+	error = mac_check_pipe_poll(active_cred, rpipe->pipe_pair);
 	if (error)
 		goto locked_error;
 #endif
@@ -1308,7 +1361,7 @@
 	int error;
 
 	PIPE_LOCK(pipe);
-	error = mac_check_pipe_stat(active_cred, pipe);
+	error = mac_check_pipe_stat(active_cred, pipe->pipe_pair);
 	PIPE_UNLOCK(pipe);
 	if (error)
 		return (error);
@@ -1350,8 +1403,8 @@
 	struct pipe *cpipe;
 {
 
-	KASSERT(cpipe->pipe_mtxp == NULL || !mtx_owned(PIPE_MTX(cpipe)),
-	       ("pipe_free_kmem: pipe mutex locked"));
+	KASSERT(!mtx_owned(PIPE_MTX(cpipe)),
+	    ("pipe_free_kmem: pipe mutex locked"));
 
 	if (cpipe->pipe_buffer.buffer != NULL) {
 		if (cpipe->pipe_buffer.size > PIPE_SIZE)
@@ -1385,17 +1438,15 @@
 pipeclose(cpipe)
 	struct pipe *cpipe;
 {
+	struct pipepair *pp;
 	struct pipe *ppipe;
 	int hadpeer;
 
-	if (cpipe == NULL)
-		return;
+	KASSERT(cpipe != NULL, ("pipeclose: cpipe == NULL"));
 
 	hadpeer = 0;
-
-	/* partially created pipes won't have a valid mutex. */
-	if (PIPE_MTX(cpipe) != NULL)
-		PIPE_LOCK(cpipe);
+	PIPE_LOCK(cpipe);
+	pp = cpipe->pipe_pair;
 
 	pipeselwakeup(cpipe);
 
@@ -1409,35 +1460,43 @@
 		msleep(cpipe, PIPE_MTX(cpipe), PRIBIO, "pipecl", 0);
 	}
 
-#ifdef MAC
-	if (cpipe->pipe_label != NULL && cpipe->pipe_peer == NULL)
-		mac_destroy_pipe(cpipe);
-#endif
 
 	/*
-	 * Disconnect from peer
+	 * Disconnect from peer, if any.
 	 */
-	if ((ppipe = cpipe->pipe_peer) != NULL) {
+	ppipe = cpipe->pipe_peer;
+	if (ppipe->pipe_present != 0) {
 		hadpeer++;
 		pipeselwakeup(ppipe);
 
 		ppipe->pipe_state |= PIPE_EOF;
 		wakeup(ppipe);
 		KNOTE(&ppipe->pipe_sel.si_note, 0);
-		ppipe->pipe_peer = NULL;
 	}
+
 	/*
-	 * free resources
+	 * Mark this endpoint as free.  Release kmem resources.  We
+	 * don't mark this endpoint as unused until we've finished
+	 * doing that, or the pipe might disappear out from under
+	 * us.
+	 */
+	PIPE_UNLOCK(cpipe);
+	pipe_free_kmem(cpipe);
+	PIPE_LOCK(cpipe);
+	cpipe->pipe_present = 0;
+
+	/*
+	 * If both endpoints are now closed, release the memory for the
+	 * pipe pair.  If not, unlock.
 	 */
-	if (PIPE_MTX(cpipe) != NULL) {
+	if (ppipe->pipe_present == 0) {
+		PIPE_UNLOCK(cpipe);
+#ifdef MAC
+		mac_destroy_pipe(pp);
+#endif
+		uma_zfree(pipe_zone, cpipe->pipe_pair);
+	} else
 		PIPE_UNLOCK(cpipe);
-		if (!hadpeer) {
-			mtx_destroy(PIPE_MTX(cpipe));
-			free(PIPE_MTX(cpipe), M_TEMP);
-		}
-	}
-	pipe_free_kmem(cpipe);
-	uma_zfree(pipe_zone, cpipe);
 }
 
 /*ARGSUSED*/
--- //depot/vendor/freebsd/src/sys/security/mac/mac_pipe.c	2003/11/11 19:15:41
+++ //depot/user/rwatson/pipe/sys/security/mac/mac_pipe.c	2004/01/31 15:47:02
@@ -73,11 +73,10 @@
 }
 
 void
-mac_init_pipe(struct pipe *pipe)
+mac_init_pipe(struct pipepair *pp)
 {
 
-	pipe->pipe_label = pipe->pipe_peer->pipe_label =
-	    mac_pipe_label_alloc();
+	pp->pp_label = mac_pipe_label_alloc();
 }
 
 void
@@ -90,11 +89,11 @@
 }
 
 void
-mac_destroy_pipe(struct pipe *pipe)
+mac_destroy_pipe(struct pipepair *pp)
 {
 
-	mac_pipe_label_free(pipe->pipe_label);
-	pipe->pipe_label = NULL;
+	mac_pipe_label_free(pp->pp_label);
+	pp->pp_label = NULL;
 }
 
 void
@@ -126,123 +125,125 @@
 }
 
 void
-mac_create_pipe(struct ucred *cred, struct pipe *pipe)
+mac_create_pipe(struct ucred *cred, struct pipepair *pp)
 {
 
-	MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label);
+	MAC_PERFORM(create_pipe, cred, pp, pp->pp_label);
 }
 
 static void
-mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel)
+mac_relabel_pipe(struct ucred *cred, struct pipepair *pp,
+    struct label *newlabel)
 {
 
-	MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel);
+	MAC_PERFORM(relabel_pipe, cred, pp, pp->pp_label, newlabel);
 }
 
 int
-mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd,
-    void *data)
+mac_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
+    unsigned long cmd, void *data)
 {
 	int error;
 
-	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
+	mtx_assert(&pp->pp_mtx, MA_OWNED);
 
 	if (!mac_enforce_pipe)
 		return (0);
 
-	MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data);
+	MAC_CHECK(check_pipe_ioctl, cred, pp, pp->pp_label, cmd, data);
 
 	return (error);
 }
 
 int
-mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe)
+mac_check_pipe_poll(struct ucred *cred, struct pipepair *pp)
 {
 	int error;
 
-	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
+	mtx_assert(&pp->pp_mtx, MA_OWNED);
 
 	if (!mac_enforce_pipe)
 		return (0);
 
-	MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label);
+	MAC_CHECK(check_pipe_poll, cred, pp, pp->pp_label);
 
 	return (error);
 }
 
 int
-mac_check_pipe_read(struct ucred *cred, struct pipe *pipe)
+mac_check_pipe_read(struct ucred *cred, struct pipepair *pp)
 {
 	int error;
 
-	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
+	mtx_assert(&pp->pp_mtx, MA_OWNED);
 
 	if (!mac_enforce_pipe)
 		return (0);
 
-	MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label);
+	MAC_CHECK(check_pipe_read, cred, pp, pp->pp_label);
 
 	return (error);
 }
 
 static int
-mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
+mac_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
     struct label *newlabel)
 {
 	int error;
 
-	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
+	mtx_assert(&pp->pp_mtx, MA_OWNED);
 
 	if (!mac_enforce_pipe)
 		return (0);
 
-	MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel);
+	MAC_CHECK(check_pipe_relabel, cred, pp, pp->pp_label, newlabel);
 
 	return (error);
 }
 
 int
-mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe)
+mac_check_pipe_stat(struct ucred *cred, struct pipepair *pp)
 {
 	int error;
 
-	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
+	mtx_assert(&pp->pp_mtx, MA_OWNED);
 
 	if (!mac_enforce_pipe)
 		return (0);
 
-	MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label);
+	MAC_CHECK(check_pipe_stat, cred, pp, pp->pp_label);
 
 	return (error);
 }
 
 int
-mac_check_pipe_write(struct ucred *cred, struct pipe *pipe)
+mac_check_pipe_write(struct ucred *cred, struct pipepair *pp)
 {
 	int error;
 
-	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
+	mtx_assert(&pp->pp_mtx, MA_OWNED);
 
 	if (!mac_enforce_pipe)
 		return (0);
 
-	MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label);
+	MAC_CHECK(check_pipe_write, cred, pp, pp->pp_label);
 
 	return (error);
 }
 
 int
-mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label)
+mac_pipe_label_set(struct ucred *cred, struct pipepair *pp,
+    struct label *label)
 {
 	int error;
 
-	PIPE_LOCK_ASSERT(pipe, MA_OWNED);
+	mtx_assert(&pp->pp_mtx, MA_OWNED);
 
-	error = mac_check_pipe_relabel(cred, pipe, label);
+	error = mac_check_pipe_relabel(cred, pp, label);
 	if (error)
 		return (error);
 
-	mac_relabel_pipe(cred, pipe, label);
+	mac_relabel_pipe(cred, pp, label);
 
 	return (0);
 }
--- //depot/vendor/freebsd/src/sys/security/mac_biba/mac_biba.c	2003/12/17 06:55:44
+++ //depot/user/rwatson/pipe/sys/security/mac_biba/mac_biba.c	2004/01/31 15:47:02
@@ -1017,7 +1017,7 @@
 }
 
 static void
-mac_biba_create_pipe(struct ucred *cred, struct pipe *pipe,
+mac_biba_create_pipe(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel)
 {
 	struct mac_biba *source, *dest;
@@ -1054,7 +1054,7 @@
 }
 
 static void
-mac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe,
+mac_biba_relabel_pipe(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel, struct label *newlabel)
 {
 	struct mac_biba *source, *dest;
@@ -1588,7 +1588,7 @@
 }
 
 static int
-mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
+mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
 {
 
@@ -1601,7 +1601,7 @@
 }
 
 static int
-mac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
+mac_biba_check_pipe_poll(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel)
 {
 	struct mac_biba *subj, *obj;
@@ -1619,7 +1619,7 @@
 }
 
 static int
-mac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe,
+mac_biba_check_pipe_read(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel)
 {
 	struct mac_biba *subj, *obj;
@@ -1637,7 +1637,7 @@
 }
 
 static int
-mac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
+mac_biba_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel, struct label *newlabel)
 {
 	struct mac_biba *subj, *obj, *new;
@@ -1688,7 +1688,7 @@
 }
 
 static int
-mac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
+mac_biba_check_pipe_stat(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel)
 {
 	struct mac_biba *subj, *obj;
@@ -1706,7 +1706,7 @@
 }
 
 static int
-mac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe,
+mac_biba_check_pipe_write(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel)
 {
 	struct mac_biba *subj, *obj;
--- //depot/vendor/freebsd/src/sys/security/mac_lomac/mac_lomac.c	2003/12/17 06:55:44
+++ //depot/user/rwatson/pipe/sys/security/mac_lomac/mac_lomac.c	2004/01/31 15:47:02
@@ -1156,7 +1156,7 @@
 }
 
 static void
-mac_lomac_create_pipe(struct ucred *cred, struct pipe *pipe,
+mac_lomac_create_pipe(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel)
 {
 	struct mac_lomac *source, *dest;
@@ -1193,7 +1193,7 @@
 }
 
 static void
-mac_lomac_relabel_pipe(struct ucred *cred, struct pipe *pipe,
+mac_lomac_relabel_pipe(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel, struct label *newlabel)
 {
 	struct mac_lomac *source, *dest;
@@ -1798,7 +1798,7 @@
 }
 
 static int
-mac_lomac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
+mac_lomac_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
 {
 
@@ -1811,7 +1811,7 @@
 }
 
 static int
-mac_lomac_check_pipe_read(struct ucred *cred, struct pipe *pipe,
+mac_lomac_check_pipe_read(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel)
 {
 	struct mac_lomac *subj, *obj;
@@ -1829,7 +1829,7 @@
 }
 
 static int
-mac_lomac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
+mac_lomac_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel, struct label *newlabel)
 {
 	struct mac_lomac *subj, *obj, *new;
@@ -1880,7 +1880,7 @@
 }
 
 static int
-mac_lomac_check_pipe_write(struct ucred *cred, struct pipe *pipe,
+mac_lomac_check_pipe_write(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel)
 {
 	struct mac_lomac *subj, *obj;
--- //depot/vendor/freebsd/src/sys/security/mac_mls/mac_mls.c	2003/12/17 06:55:44
+++ //depot/user/rwatson/pipe/sys/security/mac_mls/mac_mls.c	2004/01/31 15:47:02
@@ -987,7 +987,7 @@
 }
 
 static void
-mac_mls_create_pipe(struct ucred *cred, struct pipe *pipe,
+mac_mls_create_pipe(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel)
 {
 	struct mac_mls *source, *dest;
@@ -1024,7 +1024,7 @@
 }
 
 static void
-mac_mls_relabel_pipe(struct ucred *cred, struct pipe *pipe,
+mac_mls_relabel_pipe(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel, struct label *newlabel)
 {
 	struct mac_mls *source, *dest;
@@ -1479,7 +1479,7 @@
 }
 
 static int
-mac_mls_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
+mac_mls_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
 {
 
@@ -1492,7 +1492,7 @@
 }
 
 static int
-mac_mls_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
+mac_mls_check_pipe_poll(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel)
 {
 	struct mac_mls *subj, *obj;
@@ -1510,7 +1510,7 @@
 }
 
 static int
-mac_mls_check_pipe_read(struct ucred *cred, struct pipe *pipe,
+mac_mls_check_pipe_read(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel)
 {
 	struct mac_mls *subj, *obj;
@@ -1528,7 +1528,7 @@
 }
 
 static int
-mac_mls_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
+mac_mls_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel, struct label *newlabel)
 {
 	struct mac_mls *subj, *obj, *new;
@@ -1579,7 +1579,7 @@
 }
 
 static int
-mac_mls_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
+mac_mls_check_pipe_stat(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel)
 {
 	struct mac_mls *subj, *obj;
@@ -1597,7 +1597,7 @@
 }
 
 static int
-mac_mls_check_pipe_write(struct ucred *cred, struct pipe *pipe,
+mac_mls_check_pipe_write(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel)
 {
 	struct mac_mls *subj, *obj;
--- //depot/vendor/freebsd/src/sys/security/mac_test/mac_test.c	2003/12/17 06:55:44
+++ //depot/user/rwatson/pipe/sys/security/mac_test/mac_test.c	2004/01/31 15:47:02
@@ -803,7 +803,7 @@
 }
 
 static void
-mac_test_create_pipe(struct ucred *cred, struct pipe *pipe,
+mac_test_create_pipe(struct ucred *cred, struct pipepair *pp,
    struct label *pipelabel)
 {
 
@@ -831,7 +831,7 @@
 }
 
 static void
-mac_test_relabel_pipe(struct ucred *cred, struct pipe *pipe,
+mac_test_relabel_pipe(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel, struct label *newlabel)
 {
 
@@ -1247,7 +1247,7 @@
 }
 
 static int
-mac_test_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
+mac_test_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data)
 {
 
@@ -1258,7 +1258,7 @@
 }
 
 static int
-mac_test_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
+mac_test_check_pipe_poll(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel)
 {
 
@@ -1269,7 +1269,7 @@
 }
 
 static int
-mac_test_check_pipe_read(struct ucred *cred, struct pipe *pipe,
+mac_test_check_pipe_read(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel)
 {
 
@@ -1280,7 +1280,7 @@
 }
 
 static int
-mac_test_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
+mac_test_check_pipe_relabel(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel, struct label *newlabel)
 {
 
@@ -1292,7 +1292,7 @@
 }
 
 static int
-mac_test_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
+mac_test_check_pipe_stat(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel)
 {
 
@@ -1303,7 +1303,7 @@
 }
 
 static int
-mac_test_check_pipe_write(struct ucred *cred, struct pipe *pipe,
+mac_test_check_pipe_write(struct ucred *cred, struct pipepair *pp,
     struct label *pipelabel)
 {
 
--- //depot/vendor/freebsd/src/sys/sys/mac.h	2003/12/17 06:55:44
+++ //depot/user/rwatson/pipe/sys/sys/mac.h	2004/01/31 15:47:02
@@ -120,7 +120,7 @@
 struct proc;
 struct sockaddr;
 struct socket;
-struct pipe;
+struct pipepair;
 struct thread;
 struct timespec;
 struct ucred;
@@ -142,7 +142,7 @@
 int	mac_init_inpcb(struct inpcb *, int flag);
 int	mac_init_ipq(struct ipq *, int flag);
 int	mac_init_socket(struct socket *, int flag);
-void	mac_init_pipe(struct pipe *);
+void	mac_init_pipe(struct pipepair *);
 int	mac_init_mbuf(struct mbuf *mbuf, int flag);
 int	mac_init_mbuf_tag(struct m_tag *, int flag);
 void	mac_init_mount(struct mount *);
@@ -157,7 +157,7 @@
 void	mac_destroy_inpcb(struct inpcb *);
 void	mac_destroy_ipq(struct ipq *);
 void	mac_destroy_socket(struct socket *);
-void	mac_destroy_pipe(struct pipe *);
+void	mac_destroy_pipe(struct pipepair *);
 void	mac_destroy_proc(struct proc *);
 void	mac_destroy_mbuf_tag(struct m_tag *);
 void	mac_destroy_mount(struct mount *);
@@ -202,7 +202,7 @@
 	    struct socket *socket);
 void	mac_set_socket_peer_from_socket(struct socket *oldsocket,
 	    struct socket *newsocket);
-void	mac_create_pipe(struct ucred *cred, struct pipe *pipe);
+void	mac_create_pipe(struct ucred *cred, struct pipepair *pp);
 
 /*
  * Labeling event operations: network objects.
@@ -255,12 +255,12 @@
 int	mac_check_kld_stat(struct ucred *cred);
 int	mac_check_kld_unload(struct ucred *cred);
 int	mac_check_mount_stat(struct ucred *cred, struct mount *mp);
-int	mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
+int	mac_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp,
 	    unsigned long cmd, void *data);
-int	mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe);
-int	mac_check_pipe_read(struct ucred *cred, struct pipe *pipe);
-int	mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe);
-int	mac_check_pipe_write(struct ucred *cred, struct pipe *pipe);
+int	mac_check_pipe_poll(struct ucred *cred, struct pipepair *pp);
+int	mac_check_pipe_read(struct ucred *cred, struct pipepair *pp);
+int	mac_check_pipe_stat(struct ucred *cred, struct pipepair *pp);
+int	mac_check_pipe_write(struct ucred *cred, struct pipepair *pp);
 int	mac_check_proc_debug(struct ucred *cred, struct proc *proc);
 int	mac_check_proc_sched(struct ucred *cred, struct proc *proc);
 int	mac_check_proc_signal(struct ucred *cred, struct proc *proc,
@@ -351,7 +351,7 @@
 	    struct ifnet *ifnet);
 int	mac_setsockopt_label(struct ucred *cred, struct socket *so,
 	    struct mac *extmac);
-int	mac_pipe_label_set(struct ucred *cred, struct pipe *pipe,
+int	mac_pipe_label_set(struct ucred *cred, struct pipepair *pp,
 	    struct label *label);
 void	mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred);
 
--- //depot/vendor/freebsd/src/sys/sys/mac_policy.h	2003/12/17 06:55:44
+++ //depot/user/rwatson/pipe/sys/sys/mac_policy.h	2004/01/31 15:47:02
@@ -60,7 +60,7 @@
 struct mac_policy_conf;
 struct mbuf;
 struct mount;
-struct pipe;
+struct pipepair;
 struct sbuf;
 struct socket;
 struct ucred;
@@ -199,7 +199,7 @@
 		    struct label *newsocketlabel);
 	void	(*mpo_relabel_socket)(struct ucred *cred, struct socket *so,
 		    struct label *oldlabel, struct label *newlabel);
-	void	(*mpo_relabel_pipe)(struct ucred *cred, struct pipe *pipe,
+	void	(*mpo_relabel_pipe)(struct ucred *cred, struct pipepair *pp,
 		    struct label *oldlabel, struct label *newlabel);
 	void	(*mpo_set_socket_peer_from_mbuf)(struct mbuf *mbuf,
 		    struct label *mbuflabel, struct socket *so,
@@ -207,7 +207,7 @@
 	void	(*mpo_set_socket_peer_from_socket)(struct socket *oldsocket,
 		    struct label *oldsocketlabel, struct socket *newsocket,
 		    struct label *newsocketpeerlabel);
-	void	(*mpo_create_pipe)(struct ucred *cred, struct pipe *pipe,
+	void	(*mpo_create_pipe)(struct ucred *cred, struct pipepair *pp,
 		    struct label *pipelabel);
 
 	/*
@@ -312,19 +312,20 @@
 	int	(*mpo_check_kld_unload)(struct ucred *cred);
 	int	(*mpo_check_mount_stat)(struct ucred *cred, struct mount *mp,
 		    struct label *mntlabel);
-	int	(*mpo_check_pipe_ioctl)(struct ucred *cred, struct pipe *pipe,
-		    struct label *pipelabel, unsigned long cmd, void *data); 
-	int	(*mpo_check_pipe_poll)(struct ucred *cred, struct pipe *pipe,
-		    struct label *pipelabel);
-	int	(*mpo_check_pipe_read)(struct ucred *cred, struct pipe *pipe,
-		    struct label *pipelabel);
+	int	(*mpo_check_pipe_ioctl)(struct ucred *cred,
+		    struct pipepair *pp, struct label *pipelabel,
+		    unsigned long cmd, void *data); 
+	int	(*mpo_check_pipe_poll)(struct ucred *cred,
+		    struct pipepair *pp, struct label *pipelabel);
+	int	(*mpo_check_pipe_read)(struct ucred *cred,
+		    struct pipepair *pp, struct label *pipelabel);
 	int	(*mpo_check_pipe_relabel)(struct ucred *cred,
-		    struct pipe *pipe, struct label *pipelabel,
+		    struct pipepair *pp, struct label *pipelabel,
 		    struct label *newlabel);
-	int	(*mpo_check_pipe_stat)(struct ucred *cred, struct pipe *pipe,
-		    struct label *pipelabel);
-	int	(*mpo_check_pipe_write)(struct ucred *cred, struct pipe *pipe,
-		    struct label *pipelabel);
+	int	(*mpo_check_pipe_stat)(struct ucred *cred,
+		    struct pipepair *pp, struct label *pipelabel);
+	int	(*mpo_check_pipe_write)(struct ucred *cred,
+		    struct pipepair *pp, struct label *pipelabel);
 	int	(*mpo_check_proc_debug)(struct ucred *cred,
 		    struct proc *proc);
 	int	(*mpo_check_proc_sched)(struct ucred *cred,
--- //depot/vendor/freebsd/src/sys/sys/pipe.h	2003/11/11 19:15:41
+++ //depot/user/rwatson/pipe/sys/sys/pipe.h	2004/01/31 18:12:16
@@ -113,13 +113,24 @@
 	struct	timespec pipe_ctime;	/* time of status change */
 	struct	sigio *pipe_sigio;	/* information for async I/O */
 	struct	pipe *pipe_peer;	/* link with other direction */
+	struct	pipepair *pipe_pair;	/* container structure pointer */
 	u_int	pipe_state;		/* pipe status info */
 	int	pipe_busy;		/* busy flag, mostly to handle rundown sanely */
-	struct	label *pipe_label;	/* pipe MAC label - shared */
-	struct	mtx *pipe_mtxp;		/* shared mutex between both pipes */
+	int	pipe_present;		/* still present? */
+};
+
+/*
+ * Container structure to hold the two pipe endpoints, mutex, and label
+ * pointer.
+ */
+struct pipepair {
+	struct pipe	pp_rpipe;
+	struct pipe	pp_wpipe;
+	struct mtx	pp_mtx;
+	struct label	*pp_label;
 };
 
-#define PIPE_MTX(pipe)		(pipe)->pipe_mtxp
+#define PIPE_MTX(pipe)		(&(pipe)->pipe_pair->pp_mtx)
 #define PIPE_LOCK(pipe)		mtx_lock(PIPE_MTX(pipe))
 #define PIPE_UNLOCK(pipe)	mtx_unlock(PIPE_MTX(pipe))
 #define PIPE_LOCK_ASSERT(pipe, type)  mtx_assert(PIPE_MTX(pipe), (type))
