--- //depot/projects/trustedbsd/mac/sys/kern/kern_mac.c	2003/06/07 22:05:57
+++ //depot/user/hdandeka/rishi_SystemVIPC/sys/kern/kern_mac.c	2003/06/13 16:12:32
@@ -68,6 +68,10 @@
 #include <sys/pipe.h>
 #include <sys/socketvar.h>
 #include <sys/sysctl.h>
+#include <sys/msg.h>
+#include <sys/msg_msg.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
 
 #include <vm/vm.h>
 #include <vm/pmap.h>
@@ -171,6 +175,11 @@
     &mac_enforce_system, 0, "Enforce MAC policy on system operations");
 TUNABLE_INT("security.mac.enforce_system", &mac_enforce_system);
 
+static int	mac_enforce_sysv = 1;
+SYSCTL_INT(_security_mac, OID_AUTO, enforce_sysv, CTLFLAG_RW,
+    &mac_enforce_sysv, 0, "Enforce MAC policy on SystemV ipc  system objects");
+TUNABLE_INT("security.mac.enforce_sysv", &mac_enforce_sysv);
+
 static int	mac_enforce_vm = 1;
 SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
     &mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
@@ -833,6 +842,36 @@
 	mac_init_ifnet_label(&ifp->if_label);
 }
 
+void 
+mac_init_ipc_msgmsg(struct msg *msgptr)
+{
+				mac_init_label(&msgptr->label);
+				MAC_PERFORM(init_ipc_msgmsg_label, &msgptr->label);
+}
+
+void 
+mac_init_ipc_msgqueue(struct msqid_kernel *msqkptr)
+{
+				mac_init_label(&msqkptr->label);
+				MAC_PERFORM(init_ipc_msgqueue_label, &msqkptr->label);
+}
+
+void  
+mac_init_ipc_sema(struct semid_kernel *semakptr)
+{
+
+				mac_init_label(&semakptr->label);
+				MAC_PERFORM(init_ipc_sema_label, &semakptr->label);
+}
+
+void 
+mac_init_ipc_shm(struct shmid_kernel *shmsegptr)
+{
+
+				mac_init_label(&shmsegptr->label);
+				MAC_PERFORM(init_ipc_shm_label, &shmsegptr->label);
+}
+
 int
 mac_init_ipq(struct ipq *ipq, int flag)
 {
@@ -1080,6 +1119,38 @@
 }
 
 void
+mac_destroy_ipc_msgmsg(struct msg *msgptr)
+{
+
+	MAC_PERFORM(destroy_ipc_msgmsg_label, &msgptr->label);
+	mac_destroy_label(&msgptr->label);
+}
+
+void
+mac_destroy_ipc_msgqueue(struct msqid_kernel *msqkptr)
+{
+
+	MAC_PERFORM(destroy_ipc_msgqueue_label, &msqkptr->label);
+	mac_destroy_label(&msqkptr->label);
+}
+
+void
+mac_destroy_ipc_sema(struct semid_kernel *semakptr)
+{
+
+	MAC_PERFORM(destroy_ipc_sema_label, &semakptr->label);
+	mac_destroy_label(&semakptr->label);
+}
+
+void
+mac_destroy_ipc_shm(struct shmid_kernel *shmsegptr)
+{
+
+  MAC_PERFORM(destroy_ipc_shm_label, &shmsegptr->label);
+  mac_destroy_label(&shmsegptr->label);
+}
+
+void
 mac_destroy_ipq(struct ipq *ipq)
 {
 
@@ -2238,6 +2309,34 @@
 	MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label);
 }
 
+void 
+mac_create_ipc_msgmsg(struct ucred *cred, struct msg *msgptr)
+{
+				
+	MAC_PERFORM(create_ipc_msgmsg, cred, msgptr, &msgptr->label);
+}
+
+void 
+mac_create_ipc_msgqueue(struct ucred *cred, struct msqid_kernel *msqkptr)
+{
+				
+	MAC_PERFORM(create_ipc_msgqueue, cred, msqkptr, &msqkptr->label);
+}
+
+void 
+mac_create_ipc_sema(struct ucred *cred, struct semid_kernel *semakptr)
+{
+
+	MAC_PERFORM(create_ipc_sema, cred, semakptr, &semakptr->label);
+}
+
+void 
+mac_create_ipc_shm(struct ucred *cred, struct shmid_kernel *shmsegptr)
+{
+
+	MAC_PERFORM(create_ipc_shm, cred, shmsegptr, &shmsegptr->label);
+}
+
 void
 mac_create_socket(struct ucred *cred, struct socket *socket)
 {
@@ -2489,6 +2588,33 @@
 	    &mp->mnt_fslabel);
 }
 
+void
+mac_cleanup_ipc_msgmsg(struct msg *msgptr)
+{
+	MAC_PERFORM(cleanup_ipc_msgmsg, &msgptr->label);
+}
+
+void 
+mac_cleanup_ipc_msgqueue(struct msqid_kernel *msqkptr)
+{
+				
+	MAC_PERFORM(cleanup_ipc_msgqueue, &msqkptr->label);
+}
+
+void 
+mac_cleanup_ipc_sema(struct semid_kernel *semakptr)
+{
+
+	MAC_PERFORM(cleanup_ipc_sema, &semakptr->label);
+}
+
+void 
+mac_cleanup_ipc_shm(struct shmid_kernel *shmsegptr)
+{
+
+	MAC_PERFORM(cleanup_ipc_shm, &shmsegptr->label);
+}
+
 int
 mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet)
 {
@@ -2546,6 +2672,213 @@
 }
 
 int
+mac_check_ipc_msgmsq(struct ucred *cred, struct msg *msgptr, 
+	struct msqid_kernel *msqkptr)
+{
+				int error;
+
+				if (!mac_enforce_sysv)
+			    return (0);
+
+				//XXX: Should we also pass &msqkptr->label ??
+				MAC_CHECK(check_ipc_msgmsq, cred,  msgptr, msqkptr);
+
+
+				return(error);
+}
+
+int
+mac_check_ipc_msgrcv(struct ucred *cred, struct msg *msgptr)
+{
+				int error;
+
+				if (!mac_enforce_sysv)
+			    return (0);
+
+				//XXX: Should we also pass &msqkptr->label ??
+				MAC_CHECK(check_ipc_msgrcv, cred,  msgptr);
+
+
+				return(error);
+}
+
+int
+mac_check_ipc_msgrmid(struct ucred *cred, struct msg *msgptr)
+{
+				int error;
+
+				if (!mac_enforce_sysv)
+			    return (0);
+
+				//XXX: Should we also pass &msqkptr->label ??
+				MAC_CHECK(check_ipc_msgrmid, cred,  msgptr);
+
+
+				return(error);
+}
+
+int
+mac_check_ipc_msqget(struct ucred *cred, struct msqid_kernel *msqkptr)
+{
+				int error;
+
+				if (!mac_enforce_sysv)
+			    return (0);
+
+				//XXX: Should we also pass &msqkptr->label ??
+				MAC_CHECK(check_ipc_msqget, cred, msqkptr);
+
+
+				return(error);
+}
+
+int
+mac_check_ipc_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr)
+{
+				int error;
+
+				if (!mac_enforce_sysv)
+			    return (0);
+
+				//XXX: Should we also pass &msqkptr->label ??
+				MAC_CHECK(check_ipc_msqsnd, cred, msqkptr);
+
+				return(error);
+}
+
+int
+mac_check_ipc_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr)
+{
+				int error;
+
+				if (!mac_enforce_sysv)
+			    return (0);
+
+				//XXX: Should we also pass &msqkptr->label ??
+				MAC_CHECK(check_ipc_msqrcv, cred, msqkptr);
+
+				return(error);
+}
+
+int
+mac_check_ipc_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,                  int cmd)
+{
+				int error;
+
+				if (!mac_enforce_sysv)
+			    return (0);
+
+				//XXX: Should we also pass &msqkptr->label ??
+				MAC_CHECK(check_ipc_msqctl, cred, msqkptr, cmd);
+
+				return(error);
+}
+
+int
+mac_check_ipc_semctl(struct ucred *cred, struct semid_kernel *semakptr, int cmd)
+{
+				int error;
+
+				if (!mac_enforce_sysv)
+			    return (0);
+
+				//XXX: Should we also pass &semakptr->label ??
+				MAC_CHECK(check_ipc_semctl, cred, semakptr, cmd);
+
+
+				return(error);
+}
+
+int
+mac_check_ipc_semget(struct ucred *cred, struct semid_kernel *semakptr)
+{
+				int error;
+
+				if (!mac_enforce_sysv)
+			    return (0);
+
+				//XXX: Should we also pass &semakptr->label ??
+				MAC_CHECK(check_ipc_semget, cred, semakptr);
+
+				return(error);
+}
+
+int
+mac_check_ipc_semop(struct ucred *cred, struct semid_kernel *semakptr, 
+								        size_t accesstype)
+{
+				int error;
+
+				if (!mac_enforce_sysv)
+			    return (0);
+
+				//XXX: Should we also pass &semakptr->label ??
+				MAC_CHECK(check_ipc_semop, cred, semakptr, accesstype);
+
+				return(error);
+}
+
+int 
+mac_check_ipc_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
+								        int shmflg)
+{
+				int error;
+
+				if (!mac_enforce_sysv)
+			    return (0);
+
+				//XXX: Should we also pass &shmsegptr->label ??
+				MAC_CHECK(check_ipc_shmat, cred, shmsegptr, shmflg);
+
+				return(error);
+}
+
+int
+mac_check_ipc_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
+                        int cmd)
+{
+				int error;
+
+				if (!mac_enforce_sysv)
+			    return (0);
+
+				//XXX: Should we also pass &shmsegptr->label ??
+				MAC_CHECK(check_ipc_shmctl, cred, shmsegptr, cmd);
+
+				return(error);
+}
+
+int 
+mac_check_ipc_shmdt(struct ucred *cred, struct shmid_kernel *shmsegptr)
+{
+				int error;
+
+				if (!mac_enforce_sysv)
+			    return (0);
+
+				//XXX: Should we also pass &shmsegptr->label ??
+				MAC_CHECK(check_ipc_shmdt, cred, shmsegptr);
+
+				return(error);
+}
+
+int 
+mac_check_ipc_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
+								        int shmflg)
+{
+				int error;
+
+				if (!mac_enforce_sysv)
+			    return (0);
+
+				//XXX: Should we also pass &shmsegptr->label ??
+				MAC_CHECK(check_ipc_shmget, cred, shmsegptr, shmflg);
+
+				return(error);
+}
+
+
+int
 mac_check_kenv_dump(struct ucred *cred)
 {
 	int error;
--- //depot/projects/trustedbsd/mac/sys/kern/sysv_ipc.c	2003/05/31 18:09:30
+++ //depot/user/hdandeka/rishi_SystemVIPC/sys/kern/sysv_ipc.c	2003/06/11 17:17:58
@@ -69,6 +69,13 @@
  * Check for ipc permission
  */
 
+
+/*
+ * Note: The MAC Framework doesnt add any hook to the ipcperm function as 
+ * fine-grained hooks are inserted throughout the ipc primitives. These hooks
+ * compliment the ipcperm check. 
+ */
+
 int
 ipcperm(td, perm, mode)
 	struct thread *td;
--- //depot/projects/trustedbsd/mac/sys/kern/sysv_msg.c	2003/02/21 10:04:40
+++ //depot/user/hdandeka/rishi_SystemVIPC/sys/kern/sysv_msg.c	2003/06/20 08:44:14
@@ -20,6 +20,7 @@
  */
 
 #include "opt_sysvipc.h"
+#include "opt_mac.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -34,6 +35,11 @@
 #include <sys/sysctl.h>
 #include <sys/malloc.h>
 #include <sys/jail.h>
+#ifdef MAC
+#include <sys/msg_msg.h>
+#include <sys/_label.h>
+#include <sys/mac.h>
+#endif
 
 static MALLOC_DEFINE(M_MSG, "msg", "SVID compatible message queues");
 
@@ -55,6 +61,8 @@
 	(sy_call_t *)msgsnd, (sy_call_t *)msgrcv
 };
 
+#ifndef MAC
+/* For the MAC framework, struct moved to the header file sys/msg_msg.h */
 struct msg {
 	struct	msg *msg_next;	/* next msg in the chain */
 	long	msg_type;	/* type of this message */
@@ -63,6 +71,7 @@
 	u_short	msg_ts;		/* size of this message */
 	short	msg_spot;	/* location of start of msg in buffer */
 };
+#endif
 
 
 #ifndef MSGSSZ
@@ -128,8 +137,10 @@
 static char *msgpool;		/* MSGMAX byte long msg buffer pool */
 static struct msgmap *msgmaps;	/* MSGSEG msgmap structures */
 static struct msg *msghdrs;	/* MSGTQL msg headers */
-static struct msqid_ds *msqids;	/* MSGMNI msqid_ds struct's */
+static struct msqid_kernel *msqids;	/* MSGMNI msqid_kernel struct's */
 static struct mtx msq_mtx;	/* global mutex for message queues. */
+static int refcount; /* to ensure consistency during and after msgunload */
+static struct mtx refcnt_mtx;	/* global mutex for refcount. */
 
 static void
 msginit()
@@ -150,7 +161,7 @@
 	msghdrs = malloc(sizeof(struct msg) * msginfo.msgtql, M_MSG, M_WAITOK);
 	if (msghdrs == NULL)
 		panic("msghdrs is NULL");
-	msqids = malloc(sizeof(struct msqid_ds) * msginfo.msgmni, M_MSG, M_WAITOK);
+	msqids = malloc(sizeof(struct msqid_kernel) * msginfo.msgmni, M_MSG, M_WAITOK);
 	if (msqids == NULL)
 		panic("msqids is NULL");
 
@@ -193,6 +204,9 @@
 		if (i > 0)
 			msghdrs[i-1].msg_next = &msghdrs[i];
 		msghdrs[i].msg_next = NULL;
+#ifdef MAC
+		mac_init_ipc_msgmsg(&msghdrs[i]);
+#endif
     	}
 	free_msghdrs = &msghdrs[0];
 
@@ -200,19 +214,44 @@
 		panic("msqids is NULL");
 
 	for (i = 0; i < msginfo.msgmni; i++) {
-		msqids[i].msg_qbytes = 0;	/* implies entry is available */
-		msqids[i].msg_perm.seq = 0;	/* reset to a known value */
-		msqids[i].msg_perm.mode = 0;
+		msqids[i].u.msg_qbytes = 0;	/* implies entry is available */
+		msqids[i].u.msg_perm.seq = 0;	/* reset to a known value */
+		msqids[i].u.msg_perm.mode = 0;
+#ifdef MAC
+		mac_init_ipc_msgqueue(&msqids[i]);
+#endif
 	}
 	mtx_init(&msq_mtx, "msq", NULL, MTX_DEF);
+	refcount = 0;
+	/* 
+	 * It is not permissible to pass the same mutex to mtx_init() multiple 
+	 * times without intervening calls to mtx_destroy().
+	 * Since we cannot destroy the refcnt_mtx during msgunload, we check if the 
+	 * mtx_init has ever been called. If so, we dont need to do mtx_init as the 
+	 * mutex is already initialized.
+	 */
+	if ( mtx_initialized(&refcnt_mtx) == 0 )
+		mtx_init(&refcnt_mtx, "msgrefcnt", NULL, MTX_DEF);
 }
 
 static int
 msgunload()
 {
-	struct msqid_ds *msqptr;
+	struct msqid_kernel *msqkptr;
 	int msqid;
 
+	/* 
+	 * Make sure that the msgunload maintains the consistency of the msqids
+	 * and msghdrs data structures. This assures that the unload doesn't take
+	 * place if any thread is in any of the code-paths (tinkering with the
+	 * data structures), and also that no thread can enter the code-paths once
+	 * the module is unloaded. 
+	 */
+	mtx_lock(&refcnt_mtx);
+	if (refcount > 0) {
+		mtx_unlock(&refcnt_mtx);
+		return (EBUSY);
+	}
 	for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
 		/*
 		 * Look for an unallocated and unlocked msqid_ds.
@@ -220,19 +259,38 @@
 		 * they are copying the message in/out.  We can't
 		 * re-use the entry until they release it.
 		 */
-		msqptr = &msqids[msqid];
-		if (msqptr->msg_qbytes != 0 ||
-		    (msqptr->msg_perm.mode & MSG_LOCKED) != 0)
+		msqkptr = &msqids[msqid];
+		if (msqkptr->u.msg_qbytes != 0 ||
+		    (msqkptr->u.msg_perm.mode & MSG_LOCKED) != 0)
 			break;
 	}
-	if (msqid != msginfo.msgmni)
+	if (msqid != msginfo.msgmni) {
+		mtx_unlock(&refcnt_mtx);
 		return (EBUSY);
+	}
+
+	refcount= -1; /* Mark the module as being unloaded */
+	mtx_unlock(&refcnt_mtx);
 
+#ifdef MAC
+	int i;
+	/* Clean up the MAC label associated with the msg objects. */
+	for (i = 0; i < msginfo.msgtql; i++) 
+		mac_destroy_ipc_msgmsg(&msghdrs[i]);
+	/* Clean up the MAC label associated with the msq objects. */
+	for (msqid = 0; msqid < msginfo.msgmni; msqid++) 
+		mac_destroy_ipc_msgqueue(&msqids[msqid]);
+#endif 
 	free(msgpool, M_MSG);
 	free(msgmaps, M_MSG);
 	free(msghdrs, M_MSG);
 	free(msqids, M_MSG);
 	mtx_destroy(&msq_mtx);
+	/* 
+	 * NOTE: We cannot destroy the refcnt_mtx as it is possible that some thread
+	 * might (attempt to) hold the mutex.
+	 */
+/* 	mtx_destroy(&refcnt_mtx); */
 	return (0);
 }
 
@@ -324,6 +382,10 @@
 		panic("msghdr->msg_spot != -1");
 	msghdr->msg_next = free_msghdrs;
 	free_msghdrs = msghdr;
+#ifdef MAC
+	/* XXX: Reset the MAC label */
+	mac_cleanup_ipc_msgmsg(msghdr);
+#endif
 }
 
 #ifndef _SYS_SYSPROTO_H_
@@ -347,76 +409,116 @@
 	struct msqid_ds *user_msqptr = uap->buf;
 	int rval, error;
 	struct msqid_ds msqbuf;
-	register struct msqid_ds *msqptr;
+	register struct msqid_kernel *msqkptr;
 
 	DPRINTF(("call to msgctl(%d, %d, 0x%x)\n", msqid, cmd, user_msqptr));
 	if (!jail_sysvipc_allowed && jailed(td->td_ucred))
 		return (ENOSYS);
 
+	/* Prevent thread from going any further if module is (being) unloaded */
+	mtx_lock(&refcnt_mtx);
+	if (refcount < 0 ) {
+		mtx_unlock(&refcnt_mtx);
+		return (ENOSYS);
+	}
+	refcount++; /* Indicate that thread is active in the code-path */
+	mtx_unlock(&refcnt_mtx);
+
 	msqid = IPCID_TO_IX(msqid);
 
 	if (msqid < 0 || msqid >= msginfo.msgmni) {
 		DPRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
 		    msginfo.msgmni));
-		return (EINVAL);
+		error = EINVAL;
+		goto done3;
 	}
 	if (cmd == IPC_SET &&
-	    (error = copyin(user_msqptr, &msqbuf, sizeof(msqbuf))) != 0)
-		return (error);
+	    (error = copyin(user_msqptr, &msqbuf, sizeof(msqbuf))) != 0) 
+		goto done3;
 
-	msqptr = &msqids[msqid];
+	msqkptr = &msqids[msqid];
 
 	mtx_lock(&msq_mtx);
-	if (msqptr->msg_qbytes == 0) {
+	if (msqkptr->u.msg_qbytes == 0) {
 		DPRINTF(("no such msqid\n"));
 		error = EINVAL;
 		goto done2;
 	}
-	if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
+	if (msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
 		DPRINTF(("wrong sequence number\n"));
 		error = EINVAL;
 		goto done2;
 	}
+#ifdef MAC
+	if ((error = mac_check_ipc_msqctl(td->td_ucred,msqkptr,cmd)))
+		goto done2;
+#endif
 
 	error = 0;
 	rval = 0;
 
+
 	switch (cmd) {
 
 	case IPC_RMID:
 	{
 		struct msg *msghdr;
-		if ((error = ipcperm(td, &msqptr->msg_perm, IPC_M)))
+		if ((error = ipcperm(td, &msqkptr->u.msg_perm, IPC_M)))
 			goto done2;
+
+#ifdef MAC
+		/* 
+		 * Check that the thread has MAC access permissions to individual msghdrs.
+		 * Note: We need to do this in a separate loop because the actual loop 
+		 * alters the msq/msghdr info as it progresses, and there is no going back 
+		 * if half the way through we discover that the thread cannot free a 
+		 * certain msghdr. The msq will get into an inconsistent state.
+		 */
+		msghdr = msqkptr->u.msg_first;
+		while (msghdr != NULL) {
+			if((error=	mac_check_ipc_msgrmid(td->td_ucred,msghdr))) {
+				DPRINTF(("MAC Framework: mac_check_ipc_msgrmid permission denied\n"));
+				/* XXX wakeup(msqkptr); ??? */
+				goto done2;
+			}
+			msghdr = msghdr->msg_next;
+		}
+#endif
+
 		/* Free the message headers */
-		msghdr = msqptr->msg_first;
+		msghdr = msqkptr->u.msg_first;
 		while (msghdr != NULL) {
 			struct msg *msghdr_tmp;
 
 			/* Free the segments of each message */
-			msqptr->msg_cbytes -= msghdr->msg_ts;
-			msqptr->msg_qnum--;
+			msqkptr->u.msg_cbytes -= msghdr->msg_ts;
+			msqkptr->u.msg_qnum--;
 			msghdr_tmp = msghdr;
 			msghdr = msghdr->msg_next;
 			msg_freehdr(msghdr_tmp);
 		}
 
-		if (msqptr->msg_cbytes != 0)
+		if (msqkptr->u.msg_cbytes != 0)
 			panic("msg_cbytes is screwed up");
-		if (msqptr->msg_qnum != 0)
+		if (msqkptr->u.msg_qnum != 0)
 			panic("msg_qnum is screwed up");
 
-		msqptr->msg_qbytes = 0;	/* Mark it as free */
+		msqkptr->u.msg_qbytes = 0;	/* Mark it as free */
+
+#ifdef MAC
+		/* XXX: Reset the MAC label */
+		mac_cleanup_ipc_msgqueue(msqkptr);
+#endif
 
-		wakeup(msqptr);
+		wakeup(msqkptr);
 	}
 
 		break;
 
 	case IPC_SET:
-		if ((error = ipcperm(td, &msqptr->msg_perm, IPC_M)))
+		if ((error = ipcperm(td, &msqkptr->u.msg_perm, IPC_M)))
 			goto done2;
-		if (msqbuf.msg_qbytes > msqptr->msg_qbytes) {
+		if (msqbuf.msg_qbytes > msqkptr->u.msg_qbytes) {
 			error = suser(td);
 			if (error)
 				goto done2;
@@ -431,16 +533,16 @@
 			error = EINVAL;		/* non-standard errno! */
 			goto done2;
 		}
-		msqptr->msg_perm.uid = msqbuf.msg_perm.uid;	/* change the owner */
-		msqptr->msg_perm.gid = msqbuf.msg_perm.gid;	/* change the owner */
-		msqptr->msg_perm.mode = (msqptr->msg_perm.mode & ~0777) |
+		msqkptr->u.msg_perm.uid = msqbuf.msg_perm.uid;	/* change the owner */
+		msqkptr->u.msg_perm.gid = msqbuf.msg_perm.gid;	/* change the owner */
+		msqkptr->u.msg_perm.mode = (msqkptr->u.msg_perm.mode & ~0777) |
 		    (msqbuf.msg_perm.mode & 0777);
-		msqptr->msg_qbytes = msqbuf.msg_qbytes;
-		msqptr->msg_ctime = time_second;
+		msqkptr->u.msg_qbytes = msqbuf.msg_qbytes;
+		msqkptr->u.msg_ctime = time_second;
 		break;
 
 	case IPC_STAT:
-		if ((error = ipcperm(td, &msqptr->msg_perm, IPC_R))) {
+		if ((error = ipcperm(td, &msqkptr->u.msg_perm, IPC_R))) {
 			DPRINTF(("requester doesn't have read access\n"));
 			goto done2;
 		}
@@ -457,7 +559,11 @@
 done2:
 	mtx_unlock(&msq_mtx);
 	if (cmd == IPC_STAT && error == 0)
-		error = copyout(msqptr, user_msqptr, sizeof(struct msqid_ds));
+		error = copyout(&(msqkptr->u), user_msqptr, sizeof(struct msqid_ds));
+done3:
+	mtx_lock(&refcnt_mtx);
+	refcount--; /* Indicate that thread no longer active in the code-path */
+	mtx_unlock(&refcnt_mtx);
 	return(error);
 }
 
@@ -480,19 +586,28 @@
 	int key = uap->key;
 	int msgflg = uap->msgflg;
 	struct ucred *cred = td->td_ucred;
-	register struct msqid_ds *msqptr = NULL;
+	register struct msqid_kernel *msqkptr = NULL;
 
 	DPRINTF(("msgget(0x%x, 0%o)\n", key, msgflg));
 
 	if (!jail_sysvipc_allowed && jailed(td->td_ucred))
 		return (ENOSYS);
 
+	/* Prevent thread from going any further if module is (being) unloaded */
+	mtx_lock(&refcnt_mtx);
+	if (refcount < 0 ) {
+		mtx_unlock(&refcnt_mtx);
+		return (ENOSYS);
+	}
+	refcount++;	/* Indicate that thread is active in the code-path */
+	mtx_unlock(&refcnt_mtx);
+
 	mtx_lock(&msq_mtx);
 	if (key != IPC_PRIVATE) {
 		for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
-			msqptr = &msqids[msqid];
-			if (msqptr->msg_qbytes != 0 &&
-			    msqptr->msg_perm.key == key)
+			msqkptr = &msqids[msqid];
+			if (msqkptr->u.msg_qbytes != 0 &&
+			    msqkptr->u.msg_perm.key == key)
 				break;
 		}
 		if (msqid < msginfo.msgmni) {
@@ -502,11 +617,17 @@
 				error = EEXIST;
 				goto done2;
 			}
-			if ((error = ipcperm(td, &msqptr->msg_perm, msgflg & 0700 ))) {
+			if ((error = ipcperm(td, &msqkptr->u.msg_perm, msgflg & 0700 ))) {
 				DPRINTF(("requester doesn't have 0%o access\n",
 				    msgflg & 0700));
 				goto done2;
 			}
+#ifdef MAC
+			if(( error = mac_check_ipc_msqget(cred, msqkptr) )) {
+				DPRINTF(("MAC Framework:  mac_check_ipc_msqget access denied\n"));
+				goto done2;
+			}
+#endif
 			goto found;
 		}
 	}
@@ -520,9 +641,9 @@
 			 * they are copying the message in/out.  We can't
 			 * re-use the entry until they release it.
 			 */
-			msqptr = &msqids[msqid];
-			if (msqptr->msg_qbytes == 0 &&
-			    (msqptr->msg_perm.mode & MSG_LOCKED) == 0)
+			msqkptr = &msqids[msqid];
+			if (msqkptr->u.msg_qbytes == 0 &&
+			    (msqkptr->u.msg_perm.mode & MSG_LOCKED) == 0)
 				break;
 		}
 		if (msqid == msginfo.msgmni) {
@@ -531,24 +652,27 @@
 			goto done2;
 		}
 		DPRINTF(("msqid %d is available\n", msqid));
-		msqptr->msg_perm.key = key;
-		msqptr->msg_perm.cuid = cred->cr_uid;
-		msqptr->msg_perm.uid = cred->cr_uid;
-		msqptr->msg_perm.cgid = cred->cr_gid;
-		msqptr->msg_perm.gid = cred->cr_gid;
-		msqptr->msg_perm.mode = (msgflg & 0777);
+		msqkptr->u.msg_perm.key = key;
+		msqkptr->u.msg_perm.cuid = cred->cr_uid;
+		msqkptr->u.msg_perm.uid = cred->cr_uid;
+		msqkptr->u.msg_perm.cgid = cred->cr_gid;
+		msqkptr->u.msg_perm.gid = cred->cr_gid;
+		msqkptr->u.msg_perm.mode = (msgflg & 0777);
 		/* Make sure that the returned msqid is unique */
-		msqptr->msg_perm.seq = (msqptr->msg_perm.seq + 1) & 0x7fff;
-		msqptr->msg_first = NULL;
-		msqptr->msg_last = NULL;
-		msqptr->msg_cbytes = 0;
-		msqptr->msg_qnum = 0;
-		msqptr->msg_qbytes = msginfo.msgmnb;
-		msqptr->msg_lspid = 0;
-		msqptr->msg_lrpid = 0;
-		msqptr->msg_stime = 0;
-		msqptr->msg_rtime = 0;
-		msqptr->msg_ctime = time_second;
+		msqkptr->u.msg_perm.seq = (msqkptr->u.msg_perm.seq + 1) & 0x7fff;
+		msqkptr->u.msg_first = NULL;
+		msqkptr->u.msg_last = NULL;
+		msqkptr->u.msg_cbytes = 0;
+		msqkptr->u.msg_qnum = 0;
+		msqkptr->u.msg_qbytes = msginfo.msgmnb;
+		msqkptr->u.msg_lspid = 0;
+		msqkptr->u.msg_lrpid = 0;
+		msqkptr->u.msg_stime = 0;
+		msqkptr->u.msg_rtime = 0;
+		msqkptr->u.msg_ctime = time_second;
+#ifdef MAC
+		mac_create_ipc_msgqueue(cred, msqkptr);
+#endif
 	} else {
 		DPRINTF(("didn't find it and wasn't asked to create it\n"));
 		error = ENOENT;
@@ -557,9 +681,12 @@
 
 found:
 	/* Construct the unique msqid */
-	td->td_retval[0] = IXSEQ_TO_IPCID(msqid, msqptr->msg_perm);
+	td->td_retval[0] = IXSEQ_TO_IPCID(msqid, msqkptr->u.msg_perm);
 done2:
 	mtx_unlock(&msq_mtx);
+	mtx_lock(&refcnt_mtx);
+	refcount--; /* Indicate that thread no longer active in the code-path */
+	mtx_unlock(&refcnt_mtx);
 	return (error);
 }
 
@@ -585,7 +712,7 @@
 	size_t msgsz = uap->msgsz;
 	int msgflg = uap->msgflg;
 	int segs_needed, error = 0;
-	register struct msqid_ds *msqptr;
+	register struct msqid_kernel *msqkptr;
 	register struct msg *msghdr;
 	short next;
 
@@ -594,6 +721,15 @@
 	if (!jail_sysvipc_allowed && jailed(td->td_ucred))
 		return (ENOSYS);
 
+	/* Prevent thread from going any further if module is (being) unloaded */
+	mtx_lock(&refcnt_mtx);
+	if (refcount < 0 ) {
+		mtx_unlock(&refcnt_mtx);
+		return (ENOSYS);
+	}
+	refcount++;	/* Indicate that thread is active in the code-path */
+	mtx_unlock(&refcnt_mtx);
+
 	mtx_lock(&msq_mtx);
 	msqid = IPCID_TO_IX(msqid);
 
@@ -604,23 +740,31 @@
 		goto done2;
 	}
 
-	msqptr = &msqids[msqid];
-	if (msqptr->msg_qbytes == 0) {
+	msqkptr = &msqids[msqid];
+	if (msqkptr->u.msg_qbytes == 0) {
 		DPRINTF(("no such message queue id\n"));
 		error = EINVAL;
 		goto done2;
 	}
-	if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
+	if (msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
 		DPRINTF(("wrong sequence number\n"));
 		error = EINVAL;
 		goto done2;
 	}
 
-	if ((error = ipcperm(td, &msqptr->msg_perm, IPC_W))) {
+	if ((error = ipcperm(td, &msqkptr->u.msg_perm, IPC_W))) {
 		DPRINTF(("requester doesn't have write access\n"));
 		goto done2;
 	}
 
+#ifdef MAC 
+	/* Make sure that the thread has  access rights to the message queue */
+	if ((error = mac_check_ipc_msqsnd(td->td_ucred, msqkptr))) {
+		DPRINTF(("MAC Framework: mac_check_ipc_msqsnd permission denied\n"));
+		goto done2;
+	}
+#endif
+
 	segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz;
 	DPRINTF(("msgsz=%d, msgssz=%d, segs_needed=%d\n", msgsz, msginfo.msgssz,
 	    segs_needed));
@@ -632,17 +776,17 @@
 		 * (inside this loop in case msg_qbytes changes while we sleep)
 		 */
 
-		if (msgsz > msqptr->msg_qbytes) {
-			DPRINTF(("msgsz > msqptr->msg_qbytes\n"));
+		if (msgsz > msqkptr->u.msg_qbytes) {
+			DPRINTF(("msgsz > msqkptr->u.msg_qbytes\n"));
 			error = EINVAL;
 			goto done2;
 		}
 
-		if (msqptr->msg_perm.mode & MSG_LOCKED) {
+		if (msqkptr->u.msg_perm.mode & MSG_LOCKED) {
 			DPRINTF(("msqid is locked\n"));
 			need_more_resources = 1;
 		}
-		if (msgsz + msqptr->msg_cbytes > msqptr->msg_qbytes) {
+		if (msgsz + msqkptr->u.msg_cbytes > msqkptr->u.msg_qbytes) {
 			DPRINTF(("msgsz + msg_cbytes > msg_qbytes\n"));
 			need_more_resources = 1;
 		}
@@ -665,22 +809,22 @@
 				goto done2;
 			}
 
-			if ((msqptr->msg_perm.mode & MSG_LOCKED) != 0) {
+			if ((msqkptr->u.msg_perm.mode & MSG_LOCKED) != 0) {
 				DPRINTF(("we don't own the msqid_ds\n"));
 				we_own_it = 0;
 			} else {
 				/* Force later arrivals to wait for our
 				   request */
 				DPRINTF(("we own the msqid_ds\n"));
-				msqptr->msg_perm.mode |= MSG_LOCKED;
+				msqkptr->u.msg_perm.mode |= MSG_LOCKED;
 				we_own_it = 1;
 			}
 			DPRINTF(("goodnight\n"));
-			error = msleep(msqptr, &msq_mtx, (PZERO - 4) | PCATCH,
+			error = msleep(msqkptr, &msq_mtx, (PZERO - 4) | PCATCH,
 			    "msgwait", 0);
 			DPRINTF(("good morning, error=%d\n", error));
 			if (we_own_it)
-				msqptr->msg_perm.mode &= ~MSG_LOCKED;
+				msqkptr->u.msg_perm.mode &= ~MSG_LOCKED;
 			if (error != 0) {
 				DPRINTF(("msgsnd:  interrupted system call\n"));
 				error = EINTR;
@@ -691,7 +835,7 @@
 			 * Make sure that the msq queue still exists
 			 */
 
-			if (msqptr->msg_qbytes == 0) {
+			if (msqkptr->u.msg_qbytes == 0) {
 				DPRINTF(("msqid deleted\n"));
 				error = EIDRM;
 				goto done2;
@@ -708,11 +852,11 @@
 	 * Make sure!
 	 */
 
-	if (msqptr->msg_perm.mode & MSG_LOCKED)
+	if (msqkptr->u.msg_perm.mode & MSG_LOCKED)
 		panic("msg_perm.mode & MSG_LOCKED");
 	if (segs_needed > nfree_msgmaps)
 		panic("segs_needed > nfree_msgmaps");
-	if (msgsz + msqptr->msg_cbytes > msqptr->msg_qbytes)
+	if (msgsz + msqkptr->u.msg_cbytes > msqkptr->u.msg_qbytes)
 		panic("msgsz + msg_cbytes > msg_qbytes");
 	if (free_msghdrs == NULL)
 		panic("no more msghdrs");
@@ -722,9 +866,9 @@
 	 * message
 	 */
 
-	if ((msqptr->msg_perm.mode & MSG_LOCKED) != 0)
+	if ((msqkptr->u.msg_perm.mode & MSG_LOCKED) != 0)
 		panic("msqid_ds is already locked");
-	msqptr->msg_perm.mode |= MSG_LOCKED;
+	msqkptr->u.msg_perm.mode |= MSG_LOCKED;
 
 	/*
 	 * Allocate a message header
@@ -734,6 +878,15 @@
 	free_msghdrs = msghdr->msg_next;
 	msghdr->msg_spot = -1;
 	msghdr->msg_ts = msgsz;
+#ifdef MAC
+	mac_create_ipc_msgmsg(td->td_ucred,msghdr);
+	/* 
+	 * XXX: Should the mac_check_ipc_msgmsq check follow here immediately ? 
+	 * Or, should it be checked just before the msg is enqueued in the msgq 
+	 * (as it is done now) ?
+	 */
+
+#endif
 
 	/*
 	 * Allocate space for the message
@@ -767,8 +920,8 @@
 		mtx_lock(&msq_mtx);
 		DPRINTF(("error %d copying the message type\n", error));
 		msg_freehdr(msghdr);
-		msqptr->msg_perm.mode &= ~MSG_LOCKED;
-		wakeup(msqptr);
+		msqkptr->u.msg_perm.mode &= ~MSG_LOCKED;
+		wakeup(msqkptr);
 		goto done2;
 	}
 	mtx_lock(&msq_mtx);
@@ -780,8 +933,8 @@
 
 	if (msghdr->msg_type < 1) {
 		msg_freehdr(msghdr);
-		msqptr->msg_perm.mode &= ~MSG_LOCKED;
-		wakeup(msqptr);
+		msqkptr->u.msg_perm.mode &= ~MSG_LOCKED;
+		wakeup(msqkptr);
 		DPRINTF(("mtype (%d) < 1\n", msghdr->msg_type));
 		error = EINVAL;
 		goto done2;
@@ -809,8 +962,8 @@
 			DPRINTF(("error %d copying in message segment\n",
 			    error));
 			msg_freehdr(msghdr);
-			msqptr->msg_perm.mode &= ~MSG_LOCKED;
-			wakeup(msqptr);
+			msqkptr->u.msg_perm.mode &= ~MSG_LOCKED;
+			wakeup(msqkptr);
 			goto done2;
 		}
 		mtx_lock(&msq_mtx);
@@ -825,15 +978,15 @@
 	 * We've got the message.  Unlock the msqid_ds.
 	 */
 
-	msqptr->msg_perm.mode &= ~MSG_LOCKED;
+	msqkptr->u.msg_perm.mode &= ~MSG_LOCKED;
 
 	/*
 	 * Make sure that the msqid_ds is still allocated.
 	 */
 
-	if (msqptr->msg_qbytes == 0) {
+	if (msqkptr->u.msg_qbytes == 0) {
 		msg_freehdr(msghdr);
-		wakeup(msqptr);
+		wakeup(msqkptr);
 		error = EIDRM;
 		goto done2;
 	}
@@ -842,24 +995,45 @@
 	 * Put the message into the queue
 	 */
 
-	if (msqptr->msg_first == NULL) {
-		msqptr->msg_first = msghdr;
-		msqptr->msg_last = msghdr;
+#ifdef MAC
+	/*
+	 * Note: Since the task/thread allocates the msghdr and usually primes it with
+	 * its own MAC label,for a majority of policies, it won't be necessary to 
+	 * check whether the msghdr has access permissions to the msgq 
+	 * The mac_check_ipc_msqsnd check would suffice in that case. However, this 
+	 * hook may be required where individual policies derive a non-identical label
+	 * for the msghdr from the current thread label and may want to check the 
+	 * msghdr enqueue permissions, along with read/write permissions to the msgq.
+	 */
+	if((error=	mac_check_ipc_msgmsq(td->td_ucred,msghdr,msqkptr))) {
+		DPRINTF(("MAC Framework: mac_check_ipc_msqmsq permission denied\n"));
+		msg_freehdr(msghdr);
+		wakeup(msqkptr);
+		goto done2;
+	}
+#endif
+
+	if (msqkptr->u.msg_first == NULL) {
+		msqkptr->u.msg_first = msghdr;
+		msqkptr->u.msg_last = msghdr;
 	} else {
-		msqptr->msg_last->msg_next = msghdr;
-		msqptr->msg_last = msghdr;
+		msqkptr->u.msg_last->msg_next = msghdr;
+		msqkptr->u.msg_last = msghdr;
 	}
-	msqptr->msg_last->msg_next = NULL;
+	msqkptr->u.msg_last->msg_next = NULL;
 
-	msqptr->msg_cbytes += msghdr->msg_ts;
-	msqptr->msg_qnum++;
-	msqptr->msg_lspid = td->td_proc->p_pid;
-	msqptr->msg_stime = time_second;
+	msqkptr->u.msg_cbytes += msghdr->msg_ts;
+	msqkptr->u.msg_qnum++;
+	msqkptr->u.msg_lspid = td->td_proc->p_pid;
+	msqkptr->u.msg_stime = time_second;
 
-	wakeup(msqptr);
+	wakeup(msqkptr);
 	td->td_retval[0] = 0;
 done2:
 	mtx_unlock(&msq_mtx);
+	mtx_lock(&refcnt_mtx);
+	refcount--; /* Indicate that thread no longer active in the code-path */
+	mtx_unlock(&refcnt_mtx);
 	return (error);
 }
 
@@ -887,7 +1061,7 @@
 	long msgtyp = uap->msgtyp;
 	int msgflg = uap->msgflg;
 	size_t len;
-	register struct msqid_ds *msqptr;
+	register struct msqid_kernel *msqkptr;
 	register struct msg *msghdr;
 	int error = 0;
 	short next;
@@ -898,36 +1072,54 @@
 	if (!jail_sysvipc_allowed && jailed(td->td_ucred))
 		return (ENOSYS);
 
+	/* Prevent thread from going any further if module is (being) unloaded */
+	mtx_lock(&refcnt_mtx);
+	if (refcount < 0 ) {
+		mtx_unlock(&refcnt_mtx);
+		return (ENOSYS);
+	}
+	refcount++;	/* Indicate that thread is active in the code-path */
+	mtx_unlock(&refcnt_mtx);
+
 	msqid = IPCID_TO_IX(msqid);
 
 	if (msqid < 0 || msqid >= msginfo.msgmni) {
 		DPRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
 		    msginfo.msgmni));
-		return (EINVAL);
+		error = EINVAL;
+		goto done3;
 	}
 
-	msqptr = &msqids[msqid];
+	msqkptr = &msqids[msqid];
 	mtx_lock(&msq_mtx);
-	if (msqptr->msg_qbytes == 0) {
+	if (msqkptr->u.msg_qbytes == 0) {
 		DPRINTF(("no such message queue id\n"));
 		error = EINVAL;
 		goto done2;
 	}
-	if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
+	if (msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
 		DPRINTF(("wrong sequence number\n"));
 		error = EINVAL;
 		goto done2;
 	}
 
-	if ((error = ipcperm(td, &msqptr->msg_perm, IPC_R))) {
+	if ((error = ipcperm(td, &msqkptr->u.msg_perm, IPC_R))) {
 		DPRINTF(("requester doesn't have read access\n"));
 		goto done2;
 	}
 
+#ifdef MAC 
+	/* Make sure that the thread has access rights to the message queue */
+	if ((error = mac_check_ipc_msqrcv(td->td_ucred, msqkptr))) {
+		DPRINTF(("MAC Framework: mac_check_ipc_msqrcv permission denied\n"));
+		goto done2;
+	}
+#endif
+
 	msghdr = NULL;
 	while (msghdr == NULL) {
 		if (msgtyp == 0) {
-			msghdr = msqptr->msg_first;
+			msghdr = msqkptr->u.msg_first;
 			if (msghdr != NULL) {
 				if (msgsz < msghdr->msg_ts &&
 				    (msgflg & MSG_NOERROR) == 0) {
@@ -937,12 +1129,19 @@
 					error = E2BIG;
 					goto done2;
 				}
-				if (msqptr->msg_first == msqptr->msg_last) {
-					msqptr->msg_first = NULL;
-					msqptr->msg_last = NULL;
+#ifdef MAC
+	/* Make sure that the thread has access rights to the message header */
+				if ((error = mac_check_ipc_msgrcv(td->td_ucred, msghdr))) {
+					DPRINTF(("MAC Framework: mac_check_ipc_msgrcv permission denied\n"));
+					goto done2;
+				}
+#endif
+				if (msqkptr->u.msg_first == msqkptr->u.msg_last) {
+					msqkptr->u.msg_first = NULL;
+					msqkptr->u.msg_last = NULL;
 				} else {
-					msqptr->msg_first = msghdr->msg_next;
-					if (msqptr->msg_first == NULL)
+					msqkptr->u.msg_first = msghdr->msg_next;
+					if (msqkptr->u.msg_first == NULL)
 						panic("msg_first/last screwed up #1");
 				}
 			}
@@ -951,7 +1150,7 @@
 			struct msg **prev;
 
 			previous = NULL;
-			prev = &(msqptr->msg_first);
+			prev = &(msqkptr->u.msg_first);
 			while ((msghdr = *prev) != NULL) {
 				/*
 				 * Is this message's type an exact match or is
@@ -976,21 +1175,28 @@
 						error = E2BIG;
 						goto done2;
 					}
+#ifdef MAC
+				/* Make sure that the thread has access rights to the message header */
+					if ((error = mac_check_ipc_msgrcv(td->td_ucred, msghdr))) {
+						DPRINTF(("MAC Framework: mac_check_ipc_msgrcv permission denied\n"));
+						goto done2;
+					}
+#endif
 					*prev = msghdr->msg_next;
-					if (msghdr == msqptr->msg_last) {
+					if (msghdr == msqkptr->u.msg_last) {
 						if (previous == NULL) {
 							if (prev !=
-							    &msqptr->msg_first)
+							    &msqkptr->u.msg_first)
 								panic("msg_first/last screwed up #2");
-							msqptr->msg_first =
+							msqkptr->u.msg_first =
 							    NULL;
-							msqptr->msg_last =
+							msqkptr->u.msg_last =
 							    NULL;
 						} else {
 							if (prev ==
-							    &msqptr->msg_first)
+							    &msqkptr->u.msg_first)
 								panic("msg_first/last screwed up #3");
-							msqptr->msg_last =
+							msqkptr->u.msg_last =
 							    previous;
 						}
 					}
@@ -1027,7 +1233,7 @@
 		 */
 
 		DPRINTF(("msgrcv:  goodnight\n"));
-		error = msleep(msqptr, &msq_mtx, (PZERO - 4) | PCATCH,
+		error = msleep(msqkptr, &msq_mtx, (PZERO - 4) | PCATCH,
 		    "msgwait", 0);
 		DPRINTF(("msgrcv:  good morning (error=%d)\n", error));
 
@@ -1041,8 +1247,8 @@
 		 * Make sure that the msq queue still exists
 		 */
 
-		if (msqptr->msg_qbytes == 0 ||
-		    msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
+		if (msqkptr->u.msg_qbytes == 0 ||
+		    msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
 			DPRINTF(("msqid deleted\n"));
 			error = EIDRM;
 			goto done2;
@@ -1055,10 +1261,10 @@
 	 * First, do the bookkeeping (before we risk being interrupted).
 	 */
 
-	msqptr->msg_cbytes -= msghdr->msg_ts;
-	msqptr->msg_qnum--;
-	msqptr->msg_lrpid = td->td_proc->p_pid;
-	msqptr->msg_rtime = time_second;
+	msqkptr->u.msg_cbytes -= msghdr->msg_ts;
+	msqkptr->u.msg_qnum--;
+	msqkptr->u.msg_lrpid = td->td_proc->p_pid;
+	msqkptr->u.msg_rtime = time_second;
 
 	/*
 	 * Make msgsz the actual amount that we'll be returning.
@@ -1082,7 +1288,7 @@
 	if (error != 0) {
 		DPRINTF(("error (%d) copying out message type\n", error));
 		msg_freehdr(msghdr);
-		wakeup(msqptr);
+		wakeup(msqkptr);
 		goto done2;
 	}
 	user_msgp = (char *)user_msgp + sizeof(msghdr->msg_type);
@@ -1111,7 +1317,7 @@
 			DPRINTF(("error (%d) copying out message segment\n",
 			    error));
 			msg_freehdr(msghdr);
-			wakeup(msqptr);
+			wakeup(msqkptr);
 			goto done2;
 		}
 		user_msgp = (char *)user_msgp + tlen;
@@ -1123,10 +1329,14 @@
 	 */
 
 	msg_freehdr(msghdr);
-	wakeup(msqptr);
+	wakeup(msqkptr);
 	td->td_retval[0] = msgsz;
 done2:
 	mtx_unlock(&msq_mtx);
+done3:
+	mtx_lock(&refcnt_mtx);
+	refcount--; /* Indicate that thread no longer active in the code-path */
+	mtx_unlock(&refcnt_mtx);
 	return (error);
 }
 
--- //depot/projects/trustedbsd/mac/sys/kern/sysv_sem.c	2003/03/24 20:14:00
+++ //depot/user/hdandeka/rishi_SystemVIPC/sys/kern/sysv_sem.c	2003/06/20 08:44:14
@@ -9,6 +9,7 @@
  */
 
 #include "opt_sysvipc.h"
+#include "opt_mac.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -24,6 +25,10 @@
 #include <sys/sysctl.h>
 #include <sys/malloc.h>
 #include <sys/jail.h>
+#ifdef MAC
+#include <sys/_label.h>
+#include <sys/mac.h>
+#endif
 
 static MALLOC_DEFINE(M_SEM, "sem", "SVID compatible semaphores");
 
@@ -38,7 +43,7 @@
 static int semunload(void);
 static void semexit_myhook(void *arg, struct proc *p);
 static int sysctl_sema(SYSCTL_HANDLER_ARGS);
-static int semvalid(int semid, struct semid_ds *semaptr);
+static int semvalid(int semid, struct semid_kernel  *semakptr);
 
 #ifndef _SYS_SYSPROTO_H_
 struct __semctl_args;
@@ -62,12 +67,14 @@
 
 static struct mtx	sem_mtx;	/* semaphore global lock */
 static int	semtot = 0;
-static struct semid_ds *sema;	/* semaphore id pool */
+static struct semid_kernel  *sema;	/* semaphore id pool */
 static struct mtx *sema_mtx;	/* semaphore id pool mutexes*/
 static struct sem *sem;		/* semaphore pool */
 SLIST_HEAD(, sem_undo) semu_list;	/* list of active undo structures */
 static int	*semu;		/* undo structure pool */
 static eventhandler_tag semexit_tag;
+static int refcount; /* to ensure consistency during and after semunload */
+static struct mtx refcnt_mtx;	/* global mutex for refcount. */
 
 #define SEMUNDO_MTX		sem_mtx
 #define SEMUNDO_LOCK()		mtx_lock(&SEMUNDO_MTX);
@@ -188,15 +195,18 @@
 	TUNABLE_INT_FETCH("kern.ipc.semaem", &seminfo.semaem);
 
 	sem = malloc(sizeof(struct sem) * seminfo.semmns, M_SEM, M_WAITOK);
-	sema = malloc(sizeof(struct semid_ds) * seminfo.semmni, M_SEM,
+	sema = malloc(sizeof(struct semid_kernel ) * seminfo.semmni, M_SEM,
 	    M_WAITOK);
 	sema_mtx = malloc(sizeof(struct mtx) * seminfo.semmni, M_SEM,
 	    M_WAITOK | M_ZERO);
 	semu = malloc(seminfo.semmnu * seminfo.semusz, M_SEM, M_WAITOK);
 
 	for (i = 0; i < seminfo.semmni; i++) {
-		sema[i].sem_base = 0;
-		sema[i].sem_perm.mode = 0;
+		sema[i].u.sem_base = 0;
+		sema[i].u.sem_perm.mode = 0;
+#ifdef MAC
+		mac_init_ipc_sema(&sema[i]);
+#endif
 	}
 	for (i = 0; i < seminfo.semmni; i++)
 		mtx_init(&sema_mtx[i], "semid", NULL, MTX_DEF);
@@ -206,6 +216,16 @@
 	}
 	SLIST_INIT(&semu_list);
 	mtx_init(&sem_mtx, "sem", NULL, MTX_DEF);
+	refcount =0;
+	/* 
+	 * It is not permissible to pass the same mutex to mtx_init() multiple 
+	 * times without intervening calls to mtx_destroy().
+	 * Since we cannot destroy the refcnt_mtx during semunload, we check if the 
+	 * mtx_init has ever been called. If so, we dont need to do mtx_init as the 
+	 * mutex is already initialized.
+	 */
+	if ( mtx_initialized(&refcnt_mtx) == 0 )
+		mtx_init(&refcnt_mtx, "semrefcnt", NULL, MTX_DEF);
 	semexit_tag = EVENTHANDLER_REGISTER(process_exit, semexit_myhook, NULL,
 	    EVENTHANDLER_PRI_ANY);
 }
@@ -215,16 +235,37 @@
 {
 	int i;
 
-	if (semtot != 0)
+	/* 
+	 * Make sure that the semunload maintains the consistency of the sem and 
+	 * sema data structures. This assures that the unload doesn't take
+	 * place if any thread is in any of the code-paths (tinkering with the
+	 * data structures), and also that no thread can enter the code-paths once
+	 * the module is unloaded. 
+	 */
+	mtx_lock(&refcnt_mtx);
+	if ((refcount > 0) || (semtot != 0)) {
+		mtx_unlock(&refcnt_mtx);
 		return (EBUSY);
+	}
+	refcount= -1; /* Mark the module as being unloaded */
+	mtx_unlock(&refcnt_mtx);
 
 	EVENTHANDLER_DEREGISTER(process_exit, semexit_tag);
+#ifdef MAC
+	for (i = 0; i < seminfo.semmni; i++) 
+		mac_destroy_ipc_sema(&sema[i]);
+#endif 
 	free(sem, M_SEM);
 	free(sema, M_SEM);
 	free(semu, M_SEM);
 	for (i = 0; i < seminfo.semmni; i++)
 		mtx_destroy(&sema_mtx[i]);
 	mtx_destroy(&sem_mtx);
+	/* 
+	 * NOTE: We cannot destroy the refcnt_mtx as it is possible that some thread
+	 * might (attempt to) hold the mutex.
+	 */
+/* 	mtx_destroy(&refcnt_mtx); */
 	return (0);
 }
 
@@ -467,13 +508,13 @@
 }
 
 static int
-semvalid(semid, semaptr)
+semvalid(semid, semakptr)
 	int semid;
-	struct semid_ds *semaptr;
+	struct semid_kernel  *semakptr;
 {
 
-	return ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 ||
-	    semaptr->sem_perm.seq != IPCID_TO_SEQ(semid) ? EINVAL : 0);
+	return ((semakptr->u.sem_perm.mode & SEM_ALLOC) == 0 ||
+	    semakptr->u.sem_perm.seq != IPCID_TO_SEQ(semid) ? EINVAL : 0);
 }
 
 /*
@@ -505,7 +546,7 @@
 	struct ucred *cred = td->td_ucred;
 	int i, rval, error;
 	struct semid_ds sbuf;
-	struct semid_ds *semaptr;
+	struct semid_kernel  *semakptr;
 	struct mtx *sema_mtxp;
 	u_short usval, count;
 
@@ -514,37 +555,68 @@
 	if (!jail_sysvipc_allowed && jailed(td->td_ucred))
 		return (ENOSYS);
 
+	/* Prevent thread from going any further if module is (being) unloaded */
+	mtx_lock(&refcnt_mtx);
+	if (refcount < 0 ) {
+		mtx_unlock(&refcnt_mtx);
+		return (ENOSYS);
+	}
+	refcount++; /* Indicate that thread is active in the code-path */
+	mtx_unlock(&refcnt_mtx);
+
 	array = NULL;
 
 	switch(cmd) {
 	case SEM_STAT:
-		if (semid < 0 || semid >= seminfo.semmni)
-			return (EINVAL);
+		if (semid < 0 || semid >= seminfo.semmni) {
+			error =  EINVAL;
+			goto done3;
+		}
 		if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
-			return (error);
-		semaptr = &sema[semid];
+			goto done3;
+		semakptr = &sema[semid];
 		sema_mtxp = &sema_mtx[semid];
 		mtx_lock(sema_mtxp);
-		if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 ) {
+		if ((semakptr->u.sem_perm.mode & SEM_ALLOC) == 0 ) {
 			error = EINVAL;
 			goto done2;
 		}
-		if ((error = ipcperm(td, &semaptr->sem_perm, IPC_R)))
+		if ((error = ipcperm(td, &semakptr->u.sem_perm, IPC_R)))
 			goto done2;
+#ifdef MAC
+  	if(( error = mac_check_ipc_semctl(cred,semakptr,cmd) )) {
+  		DPRINTF(("MAC Framework:  mac_check_ipc_semctl access denied\n"));
+	  	goto done2;
+		}
+#endif
 		mtx_unlock(sema_mtxp);
-		error = copyout(semaptr, real_arg.buf, sizeof(struct semid_ds));
-		rval = IXSEQ_TO_IPCID(semid,semaptr->sem_perm);
+		error = copyout(&semakptr->u, real_arg.buf, sizeof(struct semid_ds));
+		rval = IXSEQ_TO_IPCID(semid,semakptr->u.sem_perm);
 		if (error == 0)
 			td->td_retval[0] = rval;
-		return (error);
+		goto done3;
 	}
 
 	semid = IPCID_TO_IX(semid);
-	if (semid < 0 || semid >= seminfo.semmni)
-		return (EINVAL);
+	if (semid < 0 || semid >= seminfo.semmni) {
+		error = EINVAL;
+		goto done3;
+	}
 
-	semaptr = &sema[semid];
+	semakptr = &sema[semid];
 	sema_mtxp = &sema_mtx[semid];
+#ifdef MAC
+  mtx_lock(sema_mtxp);
+	/* 
+	 * The MAC framework lets the policies decide what type of access
+	 * is permitted, based on the cmd.
+	 */
+  if(( error = mac_check_ipc_semctl(cred,semakptr,cmd) )) {
+  	DPRINTF(("MAC Framework:  mac_check_ipc_semctl access denied\n"));
+	  goto done2;
+	}
+	mtx_unlock(sema_mtxp);
+#endif
 		
 	error = 0;
 	rval = 0;
@@ -552,25 +624,29 @@
 	switch (cmd) {
 	case IPC_RMID:
 		mtx_lock(sema_mtxp);
-		if ((error = semvalid(uap->semid, semaptr)) != 0)
+		if ((error = semvalid(uap->semid, semakptr)) != 0)
 			goto done2;
-		if ((error = ipcperm(td, &semaptr->sem_perm, IPC_M)))
+		if ((error = ipcperm(td, &semakptr->u.sem_perm, IPC_M)))
 			goto done2;
-		semaptr->sem_perm.cuid = cred->cr_uid;
-		semaptr->sem_perm.uid = cred->cr_uid;
-		semtot -= semaptr->sem_nsems;
-		for (i = semaptr->sem_base - sem; i < semtot; i++)
-			sem[i] = sem[i + semaptr->sem_nsems];
+		semakptr->u.sem_perm.cuid = cred->cr_uid;
+		semakptr->u.sem_perm.uid = cred->cr_uid;
+		semtot -= semakptr->u.sem_nsems;
+		for (i = semakptr->u.sem_base - sem; i < semtot; i++)
+			sem[i] = sem[i + semakptr->u.sem_nsems];
 		for (i = 0; i < seminfo.semmni; i++) {
-			if ((sema[i].sem_perm.mode & SEM_ALLOC) &&
-			    sema[i].sem_base > semaptr->sem_base)
-				sema[i].sem_base -= semaptr->sem_nsems;
+			if ((sema[i].u.sem_perm.mode & SEM_ALLOC) &&
+			    sema[i].u.sem_base > semakptr->u.sem_base)
+				sema[i].u.sem_base -= semakptr->u.sem_nsems;
 		}
-		semaptr->sem_perm.mode = 0;
+		semakptr->u.sem_perm.mode = 0;
+#ifdef MAC
+		/* XXX: Reset the MAC label */
+		mac_cleanup_ipc_sema(semakptr);
+#endif
 		SEMUNDO_LOCK();
 		semundo_clear(semid, -1);
 		SEMUNDO_UNLOCK();
-		wakeup(semaptr);
+		wakeup(semakptr);
 		break;
 
 	case IPC_SET:
@@ -579,82 +655,82 @@
 		if ((error = copyin(real_arg.buf, &sbuf, sizeof(sbuf))) != 0)
 			goto done2;
 		mtx_lock(sema_mtxp);
-		if ((error = semvalid(uap->semid, semaptr)) != 0)
+		if ((error = semvalid(uap->semid, semakptr)) != 0)
 			goto done2;
-		if ((error = ipcperm(td, &semaptr->sem_perm, IPC_M)))
+		if ((error = ipcperm(td, &semakptr->u.sem_perm, IPC_M)))
 			goto done2;
-		semaptr->sem_perm.uid = sbuf.sem_perm.uid;
-		semaptr->sem_perm.gid = sbuf.sem_perm.gid;
-		semaptr->sem_perm.mode = (semaptr->sem_perm.mode & ~0777) |
+		semakptr->u.sem_perm.uid = sbuf.sem_perm.uid;
+		semakptr->u.sem_perm.gid = sbuf.sem_perm.gid;
+		semakptr->u.sem_perm.mode = (semakptr->u.sem_perm.mode & ~0777) |
 		    (sbuf.sem_perm.mode & 0777);
-		semaptr->sem_ctime = time_second;
+		semakptr->u.sem_ctime = time_second;
 		break;
 
 	case IPC_STAT:
 		if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
 			goto done2;
 		mtx_lock(sema_mtxp);
-		if ((error = semvalid(uap->semid, semaptr)) != 0)
+		if ((error = semvalid(uap->semid, semakptr)) != 0)
 			goto done2;
-		if ((error = ipcperm(td, &semaptr->sem_perm, IPC_R)))
+		if ((error = ipcperm(td, &semakptr->u.sem_perm, IPC_R)))
 			goto done2;
-		sbuf = *semaptr;
+		sbuf = semakptr->u;
 		mtx_unlock(sema_mtxp);
-		error = copyout(semaptr, real_arg.buf,
+		error = copyout(&semakptr->u, real_arg.buf,
 				sizeof(struct semid_ds));
 		break;
 
 	case GETNCNT:
 		mtx_lock(sema_mtxp);
-		if ((error = semvalid(uap->semid, semaptr)) != 0)
+		if ((error = semvalid(uap->semid, semakptr)) != 0)
 			goto done2;
-		if ((error = ipcperm(td, &semaptr->sem_perm, IPC_R)))
+		if ((error = ipcperm(td, &semakptr->u.sem_perm, IPC_R)))
 			goto done2;
-		if (semnum < 0 || semnum >= semaptr->sem_nsems) {
+		if (semnum < 0 || semnum >= semakptr->u.sem_nsems) {
 			error = EINVAL;
 			goto done2;
 		}
-		rval = semaptr->sem_base[semnum].semncnt;
+		rval = semakptr->u.sem_base[semnum].semncnt;
 		break;
 
 	case GETPID:
 		mtx_lock(sema_mtxp);
-		if ((error = semvalid(uap->semid, semaptr)) != 0)
+		if ((error = semvalid(uap->semid, semakptr)) != 0)
 			goto done2;
-		if ((error = ipcperm(td, &semaptr->sem_perm, IPC_R)))
+		if ((error = ipcperm(td, &semakptr->u.sem_perm, IPC_R)))
 			goto done2;
-		if (semnum < 0 || semnum >= semaptr->sem_nsems) {
+		if (semnum < 0 || semnum >= semakptr->u.sem_nsems) {
 			error = EINVAL;
 			goto done2;
 		}
-		rval = semaptr->sem_base[semnum].sempid;
+		rval = semakptr->u.sem_base[semnum].sempid;
 		break;
 
 	case GETVAL:
 		mtx_lock(sema_mtxp);
-		if ((error = semvalid(uap->semid, semaptr)) != 0)
+		if ((error = semvalid(uap->semid, semakptr)) != 0)
 			goto done2;
-		if ((error = ipcperm(td, &semaptr->sem_perm, IPC_R)))
+		if ((error = ipcperm(td, &semakptr->u.sem_perm, IPC_R)))
 			goto done2;
-		if (semnum < 0 || semnum >= semaptr->sem_nsems) {
+		if (semnum < 0 || semnum >= semakptr->u.sem_nsems) {
 			error = EINVAL;
 			goto done2;
 		}
-		rval = semaptr->sem_base[semnum].semval;
+		rval = semakptr->u.sem_base[semnum].semval;
 		break;
 
 	case GETALL:
 		if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
 			goto done2;
-		array = malloc(sizeof(*array) * semaptr->sem_nsems, M_TEMP,
+		array = malloc(sizeof(*array) * semakptr->u.sem_nsems, M_TEMP,
 		    M_WAITOK);
 		mtx_lock(sema_mtxp);
-		if ((error = semvalid(uap->semid, semaptr)) != 0)
+		if ((error = semvalid(uap->semid, semakptr)) != 0)
 			goto done2;
-		if ((error = ipcperm(td, &semaptr->sem_perm, IPC_R)))
+		if ((error = ipcperm(td, &semakptr->u.sem_perm, IPC_R)))
 			goto done2;
-		for (i = 0; i < semaptr->sem_nsems; i++)
-			array[i] = semaptr->sem_base[i].semval;
+		for (i = 0; i < semakptr->u.sem_nsems; i++)
+			array[i] = semakptr->u.sem_base[i].semval;
 		mtx_unlock(sema_mtxp);
 		error = copyout(array, real_arg.array,
 		    i * sizeof(real_arg.array[0]));
@@ -662,26 +738,26 @@
 
 	case GETZCNT:
 		mtx_lock(sema_mtxp);
-		if ((error = semvalid(uap->semid, semaptr)) != 0)
+		if ((error = semvalid(uap->semid, semakptr)) != 0)
 			goto done2;
-		if ((error = ipcperm(td, &semaptr->sem_perm, IPC_R)))
+		if ((error = ipcperm(td, &semakptr->u.sem_perm, IPC_R)))
 			goto done2;
-		if (semnum < 0 || semnum >= semaptr->sem_nsems) {
+		if (semnum < 0 || semnum >= semakptr->u.sem_nsems) {
 			error = EINVAL;
 			goto done2;
 		}
-		rval = semaptr->sem_base[semnum].semzcnt;
+		rval = semakptr->u.sem_base[semnum].semzcnt;
 		break;
 
 	case SETVAL:
 		if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
 			goto done2;
 		mtx_lock(sema_mtxp);
-		if ((error = semvalid(uap->semid, semaptr)) != 0)
+		if ((error = semvalid(uap->semid, semakptr)) != 0)
 			goto done2;
-		if ((error = ipcperm(td, &semaptr->sem_perm, IPC_W)))
+		if ((error = ipcperm(td, &semakptr->u.sem_perm, IPC_W)))
 			goto done2;
-		if (semnum < 0 || semnum >= semaptr->sem_nsems) {
+		if (semnum < 0 || semnum >= semakptr->u.sem_nsems) {
 			error = EINVAL;
 			goto done2;
 		}
@@ -689,19 +765,19 @@
 			error = ERANGE;
 			goto done2;
 		}
-		semaptr->sem_base[semnum].semval = real_arg.val;
+		semakptr->u.sem_base[semnum].semval = real_arg.val;
 		SEMUNDO_LOCK();
 		semundo_clear(semid, semnum);
 		SEMUNDO_UNLOCK();
-		wakeup(semaptr);
+		wakeup(semakptr);
 		break;
 
 	case SETALL:
 		mtx_lock(sema_mtxp);
 raced:
-		if ((error = semvalid(uap->semid, semaptr)) != 0)
+		if ((error = semvalid(uap->semid, semakptr)) != 0)
 			goto done2;
-		count = semaptr->sem_nsems;
+		count = semakptr->u.sem_nsems;
 		mtx_unlock(sema_mtxp);
 		if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
 			goto done2;
@@ -710,28 +786,28 @@
 		if (error)
 			break;
 		mtx_lock(sema_mtxp);
-		if ((error = semvalid(uap->semid, semaptr)) != 0)
+		if ((error = semvalid(uap->semid, semakptr)) != 0)
 			goto done2;
 		/* we could have raced? */
-		if (count != semaptr->sem_nsems) {
+		if (count != semakptr->u.sem_nsems) {
 			free(array, M_TEMP);
 			array = NULL;
 			goto raced;
 		}
-		if ((error = ipcperm(td, &semaptr->sem_perm, IPC_W)))
+		if ((error = ipcperm(td, &semakptr->u.sem_perm, IPC_W)))
 			goto done2;
-		for (i = 0; i < semaptr->sem_nsems; i++) {
+		for (i = 0; i < semakptr->u.sem_nsems; i++) {
 			usval = array[i];
 			if (usval > seminfo.semvmx) {
 				error = ERANGE;
 				break;
 			}
-			semaptr->sem_base[i].semval = usval;
+			semakptr->u.sem_base[i].semval = usval;
 		}
 		SEMUNDO_LOCK();
 		semundo_clear(semid, -1);
 		SEMUNDO_UNLOCK();
-		wakeup(semaptr);
+		wakeup(semakptr);
 		break;
 
 	default:
@@ -746,6 +822,10 @@
 		mtx_unlock(sema_mtxp);
 	if (array != NULL)
 		free(array, M_TEMP);
+done3:
+	mtx_lock(&refcnt_mtx);
+	refcount--; /* Indicate that thread no longer active in the code-path */
+	mtx_unlock(&refcnt_mtx);
 	return(error);
 }
 
@@ -775,20 +855,29 @@
 	if (!jail_sysvipc_allowed && jailed(td->td_ucred))
 		return (ENOSYS);
 
+	/* Prevent thread from going any further if module is (being) unloaded */
+	mtx_lock(&refcnt_mtx);
+	if (refcount < 0 ) {
+		mtx_unlock(&refcnt_mtx);
+		return (ENOSYS);
+	}
+	refcount++; /* Indicate that thread is active in the code-path */
+	mtx_unlock(&refcnt_mtx);
+
 	mtx_lock(&Giant);
 	if (key != IPC_PRIVATE) {
 		for (semid = 0; semid < seminfo.semmni; semid++) {
-			if ((sema[semid].sem_perm.mode & SEM_ALLOC) &&
-			    sema[semid].sem_perm.key == key)
+			if ((sema[semid].u.sem_perm.mode & SEM_ALLOC) &&
+			    sema[semid].u.sem_perm.key == key)
 				break;
 		}
 		if (semid < seminfo.semmni) {
 			DPRINTF(("found public key\n"));
-			if ((error = ipcperm(td, &sema[semid].sem_perm,
+			if ((error = ipcperm(td, &sema[semid].u.sem_perm,
 			    semflg & 0700))) {
 				goto done2;
 			}
-			if (nsems > 0 && sema[semid].sem_nsems < nsems) {
+			if (nsems > 0 && sema[semid].u.sem_nsems < nsems) {
 				DPRINTF(("too small\n"));
 				error = EINVAL;
 				goto done2;
@@ -798,11 +887,17 @@
 				error = EEXIST;
 				goto done2;
 			}
+#ifdef MAC 
+		  if(( error = mac_check_ipc_semget(cred,&sema[semid]) )) {
+		  	DPRINTF(("MAC Framework:  mac_check_ipc_semget access denied\n"));
+			  goto done2;
+			}
+#endif
 			goto found;
 		}
 	}
 
-	DPRINTF(("need to allocate the semid_ds\n"));
+	DPRINTF(("need to allocate the semid_kernel \n"));
 	if (key == IPC_PRIVATE || (semflg & IPC_CREAT)) {
 		if (nsems <= 0 || nsems > seminfo.semmsl) {
 			DPRINTF(("nsems out of range (0<%d<=%d)\n", nsems,
@@ -818,31 +913,34 @@
 			goto done2;
 		}
 		for (semid = 0; semid < seminfo.semmni; semid++) {
-			if ((sema[semid].sem_perm.mode & SEM_ALLOC) == 0)
+			if ((sema[semid].u.sem_perm.mode & SEM_ALLOC) == 0)
 				break;
 		}
 		if (semid == seminfo.semmni) {
-			DPRINTF(("no more semid_ds's available\n"));
+			DPRINTF(("no more semid_kernel 's available\n"));
 			error = ENOSPC;
 			goto done2;
 		}
 		DPRINTF(("semid %d is available\n", semid));
-		sema[semid].sem_perm.key = key;
-		sema[semid].sem_perm.cuid = cred->cr_uid;
-		sema[semid].sem_perm.uid = cred->cr_uid;
-		sema[semid].sem_perm.cgid = cred->cr_gid;
-		sema[semid].sem_perm.gid = cred->cr_gid;
-		sema[semid].sem_perm.mode = (semflg & 0777) | SEM_ALLOC;
-		sema[semid].sem_perm.seq =
-		    (sema[semid].sem_perm.seq + 1) & 0x7fff;
-		sema[semid].sem_nsems = nsems;
-		sema[semid].sem_otime = 0;
-		sema[semid].sem_ctime = time_second;
-		sema[semid].sem_base = &sem[semtot];
+		sema[semid].u.sem_perm.key = key;
+		sema[semid].u.sem_perm.cuid = cred->cr_uid;
+		sema[semid].u.sem_perm.uid = cred->cr_uid;
+		sema[semid].u.sem_perm.cgid = cred->cr_gid;
+		sema[semid].u.sem_perm.gid = cred->cr_gid;
+		sema[semid].u.sem_perm.mode = (semflg & 0777) | SEM_ALLOC;
+		sema[semid].u.sem_perm.seq =
+		    (sema[semid].u.sem_perm.seq + 1) & 0x7fff;
+		sema[semid].u.sem_nsems = nsems;
+		sema[semid].u.sem_otime = 0;
+		sema[semid].u.sem_ctime = time_second;
+		sema[semid].u.sem_base = &sem[semtot];
 		semtot += nsems;
-		bzero(sema[semid].sem_base,
-		    sizeof(sema[semid].sem_base[0])*nsems);
-		DPRINTF(("sembase = 0x%x, next = 0x%x\n", sema[semid].sem_base,
+		bzero(sema[semid].u.sem_base,
+		    sizeof(sema[semid].u.sem_base[0])*nsems);
+#ifdef MAC
+		mac_create_ipc_sema(cred, &sema[semid]);
+#endif
+		DPRINTF(("sembase = 0x%x, next = 0x%x\n", sema[semid].u.sem_base,
 		    &sem[semtot]));
 	} else {
 		DPRINTF(("didn't find it and wasn't asked to create it\n"));
@@ -851,9 +949,12 @@
 	}
 
 found:
-	td->td_retval[0] = IXSEQ_TO_IPCID(semid, sema[semid].sem_perm);
+	td->td_retval[0] = IXSEQ_TO_IPCID(semid, sema[semid].u.sem_perm);
 done2:
 	mtx_unlock(&Giant);
+	mtx_lock(&refcnt_mtx);
+	refcount--; /* Indicate that thread no longer active in the code-path */
+	mtx_unlock(&refcnt_mtx);
 	return (error);
 }
 
@@ -876,7 +977,7 @@
 	int semid = uap->semid;
 	size_t nsops = uap->nsops;
 	struct sembuf *sops;
-	struct semid_ds *semaptr;
+	struct semid_kernel  *semakptr;
 	struct sembuf *sopptr = 0;
 	struct sem *semptr = 0;
 	struct sem_undo *suptr;
@@ -890,33 +991,45 @@
 	if (!jail_sysvipc_allowed && jailed(td->td_ucred))
 		return (ENOSYS);
 
+	/* Prevent thread from going any further if module is (being) unloaded */
+	mtx_lock(&refcnt_mtx);
+	if (refcount < 0 ) {
+		mtx_unlock(&refcnt_mtx);
+		return (ENOSYS);
+	}
+	refcount++; /* Indicate that thread is active in the code-path */
+	mtx_unlock(&refcnt_mtx);
+
 	semid = IPCID_TO_IX(semid);	/* Convert back to zero origin */
 
-	if (semid < 0 || semid >= seminfo.semmni)
-		return (EINVAL);
+	if (semid < 0 || semid >= seminfo.semmni) {
+		error = EINVAL;
+		goto done3;
+	}
 
 	/* Allocate memory for sem_ops */
 	if (nsops > seminfo.semopm) {
 		DPRINTF(("too many sops (max=%d, nsops=%d)\n", seminfo.semopm,
 		    nsops));
-		return (E2BIG);
+		error = E2BIG;
+		goto done3;
 	}
 	sops = malloc(nsops * sizeof(sops[0]), M_SEM, M_WAITOK);
 	if ((error = copyin(uap->sops, sops, nsops * sizeof(sops[0]))) != 0) {
 		DPRINTF(("error = %d from copyin(%08x, %08x, %d)\n", error,
 		    uap->sops, sops, nsops * sizeof(sops[0])));
 		free(sops, M_SEM);
-		return (error);
+		goto done3;
 	}
 
-	semaptr = &sema[semid];
+	semakptr = &sema[semid];
 	sema_mtxp = &sema_mtx[semid];
 	mtx_lock(sema_mtxp);
-	if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0) {
+	if ((semakptr->u.sem_perm.mode & SEM_ALLOC) == 0) {
 		error = EINVAL;
 		goto done2;
 	}
-	if (semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) {
+	if (semakptr->u.sem_perm.seq != IPCID_TO_SEQ(uap->semid)) {
 		error = EINVAL;
 		goto done2;
 	}
@@ -929,7 +1042,7 @@
 	do_undos = 0;
 	for (i = 0; i < nsops; i++) {
 		sopptr = &sops[i];
-		if (sopptr->sem_num >= semaptr->sem_nsems) {
+		if (sopptr->sem_num >= semakptr->u.sem_nsems) {
 			error = EFBIG;
 			goto done2;
 		}
@@ -938,10 +1051,20 @@
 		j |= (sopptr->sem_op == 0) ? SEM_R : SEM_A;
 	}
 
-	if ((error = ipcperm(td, &semaptr->sem_perm, j))) {
+	if ((error = ipcperm(td, &semakptr->u.sem_perm, j))) {
 		DPRINTF(("error = %d from ipaccess\n", error));
 		goto done2;
 	}
+#ifdef MAC
+	/* 
+	 * The MAC hook checks whether the thread has read ( and possibly write)
+	 * permissions to the semaphore array based on the sopptr->sem_op value.
+	 */
+	if ((error = mac_check_ipc_semop(td->td_ucred, semakptr, j))) {
+		DPRINTF(("MAC Framework:  mac_check_ipc_semop access denied\n"));
+		goto done2;
+	}
+#endif
 
 	/*
 	 * Loop trying to satisfy the vector of requests.
@@ -958,12 +1081,12 @@
 
 		for (i = 0; i < nsops; i++) {
 			sopptr = &sops[i];
-			semptr = &semaptr->sem_base[sopptr->sem_num];
+			semptr = &semakptr->u.sem_base[sopptr->sem_num];
 
 			DPRINTF((
-			    "semop:  semaptr=%x, sem_base=%x, "
+			    "semop:  semakptr=%x, sem_base=%x, "
 			    "semptr=%x, sem[%d]=%d : op=%d, flag=%s\n",
-			    semaptr, semaptr->sem_base, semptr,
+			    semakptr, semakptr->u.sem_base, semptr,
 			    sopptr->sem_num, semptr->semval, sopptr->sem_op,
 			    (sopptr->sem_flg & IPC_NOWAIT) ?
 			    "nowait" : "wait"));
@@ -1005,7 +1128,7 @@
 		 */
 		DPRINTF(("semop:  rollback 0 through %d\n", i-1));
 		for (j = 0; j < i; j++)
-			semaptr->sem_base[sops[j].sem_num].semval -=
+			semakptr->u.sem_base[sops[j].sem_num].semval -=
 			    sops[j].sem_op;
 
 		/* If we detected an error, return it */
@@ -1027,7 +1150,7 @@
 			semptr->semncnt++;
 
 		DPRINTF(("semop:  good night!\n"));
-		error = msleep(semaptr, sema_mtxp, (PZERO - 4) | PCATCH,
+		error = msleep(semakptr, sema_mtxp, (PZERO - 4) | PCATCH,
 		    "semwait", 0);
 		DPRINTF(("semop:  good morning (error=%d)!\n", error));
 
@@ -1040,8 +1163,8 @@
 		/*
 		 * Make sure that the semaphore still exists
 		 */
-		if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 ||
-		    semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) {
+		if ((semakptr->u.sem_perm.mode & SEM_ALLOC) == 0 ||
+		    semakptr->u.sem_perm.seq != IPCID_TO_SEQ(uap->semid)) {
 			error = EIDRM;
 			goto done2;
 		}
@@ -1102,7 +1225,7 @@
 			}
 
 			for (j = 0; j < nsops; j++)
-				semaptr->sem_base[sops[j].sem_num].semval -=
+				semakptr->u.sem_base[sops[j].sem_num].semval -=
 				    sops[j].sem_op;
 
 			DPRINTF(("error = %d from semundo_adjust\n", error));
@@ -1115,10 +1238,10 @@
 	/* We're definitely done - set the sempid's and time */
 	for (i = 0; i < nsops; i++) {
 		sopptr = &sops[i];
-		semptr = &semaptr->sem_base[sopptr->sem_num];
+		semptr = &semakptr->u.sem_base[sopptr->sem_num];
 		semptr->sempid = td->td_proc->p_pid;
 	}
-	semaptr->sem_otime = time_second;
+	semakptr->u.sem_otime = time_second;
 
 	/*
 	 * Do a wakeup if any semaphore was up'd whilst something was
@@ -1126,7 +1249,7 @@
 	 */
 	if (do_wakeup) {
 		DPRINTF(("semop:  doing wakeup\n"));
-		wakeup(semaptr);
+		wakeup(semakptr);
 		DPRINTF(("semop:  back from wakeup\n"));
 	}
 	DPRINTF(("semop:  done\n"));
@@ -1134,6 +1257,10 @@
 done2:
 	mtx_unlock(sema_mtxp);
 	free(sops, M_SEM);
+done3:
+	mtx_lock(&refcnt_mtx);
+	refcount--; /* Indicate that thread no longer active in the code-path */
+	mtx_unlock(&refcnt_mtx);
 	return (error);
 }
 
@@ -1176,16 +1303,16 @@
 			int semid = suptr->un_ent[ix].un_id;
 			int semnum = suptr->un_ent[ix].un_num;
 			int adjval = suptr->un_ent[ix].un_adjval;
-			struct semid_ds *semaptr;
+			struct semid_kernel  *semakptr;
 			struct mtx *sema_mtxp;
 
-			semaptr = &sema[semid];
+			semakptr = &sema[semid];
 			sema_mtxp = &sema_mtx[semid];
 			mtx_lock(sema_mtxp);
 			SEMUNDO_LOCK();
-			if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0)
+			if ((semakptr->u.sem_perm.mode & SEM_ALLOC) == 0)
 				panic("semexit - semid not allocated");
-			if (semnum >= semaptr->sem_nsems)
+			if (semnum >= semakptr->u.sem_nsems)
 				panic("semexit - semnum out of range");
 
 			DPRINTF((
@@ -1193,18 +1320,18 @@
 			    suptr->un_proc, suptr->un_ent[ix].un_id,
 			    suptr->un_ent[ix].un_num,
 			    suptr->un_ent[ix].un_adjval,
-			    semaptr->sem_base[semnum].semval));
+			    semakptr->u.sem_base[semnum].semval));
 
 			if (adjval < 0) {
-				if (semaptr->sem_base[semnum].semval < -adjval)
-					semaptr->sem_base[semnum].semval = 0;
+				if (semakptr->u.sem_base[semnum].semval < -adjval)
+					semakptr->u.sem_base[semnum].semval = 0;
 				else
-					semaptr->sem_base[semnum].semval +=
+					semakptr->u.sem_base[semnum].semval +=
 					    adjval;
 			} else
-				semaptr->sem_base[semnum].semval += adjval;
+				semakptr->u.sem_base[semnum].semval += adjval;
 
-			wakeup(semaptr);
+			wakeup(semakptr);
 			DPRINTF(("semexit:  back from wakeup\n"));
 			mtx_unlock(sema_mtxp);
 			SEMUNDO_UNLOCK();
--- //depot/projects/trustedbsd/mac/sys/kern/sysv_shm.c	2003/05/05 17:13:02
+++ //depot/user/hdandeka/rishi_SystemVIPC/sys/kern/sysv_shm.c	2003/06/20 08:44:14
@@ -33,6 +33,7 @@
 
 #include "opt_compat.h"
 #include "opt_sysvipc.h"
+#include "opt_mac.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -50,6 +51,10 @@
 #include <sys/sysent.h>
 #include <sys/sysproto.h>
 #include <sys/jail.h>
+#ifdef MAC
+#include <sys/_label.h>
+#include <sys/mac.h>
+#endif
 
 #include <vm/vm.h>
 #include <vm/vm_param.h>
@@ -82,7 +87,9 @@
 #define	SHMSEG_WANTED		0x1000
 
 static int shm_last_free, shm_nused, shm_committed, shmalloced;
-static struct shmid_ds	*shmsegs;
+static struct shmid_kernel	*shmsegs;
+static int refcount; /* to ensure consistency during and after shmunload */
+static struct mtx refcnt_mtx;	/* global mutex for refcount. */
 
 struct shm_handle {
 	/* vm_offset_t kva; */
@@ -94,15 +101,16 @@
 	int shmid;
 };
 
-static void shm_deallocate_segment(struct shmid_ds *);
+static void shm_deallocate_segment(struct shmid_kernel *);
 static int shm_find_segment_by_key(key_t);
-static struct shmid_ds *shm_find_segment_by_shmid(int, int);
-static struct shmid_ds *shm_find_segment_by_shmidx(int, int);
+static struct shmid_kernel *shm_find_segment_by_shmid(int, int);
+static struct shmid_kernel *shm_find_segment_by_shmidx(int, int);
 static int shm_delete_mapping(struct vmspace *vm, struct shmmap_state *);
 static void shmrealloc(void);
 static void shminit(void);
 static int sysvshm_modload(struct module *, int, void *);
 static int shmunload(void);
+/* TODO: Look at the following functions w.r.t. the MAC framework */
 static void shmexit_myhook(struct vmspace *vm);
 static void shmfork_myhook(struct proc *p1, struct proc *p2);
 static int sysctl_shmsegs(SYSCTL_HANDLER_ARGS);
@@ -157,66 +165,70 @@
 	int i;
 
 	for (i = 0; i < shmalloced; i++)
-		if ((shmsegs[i].shm_perm.mode & SHMSEG_ALLOCATED) &&
-		    shmsegs[i].shm_perm.key == key)
+		if ((shmsegs[i].u.shm_perm.mode & SHMSEG_ALLOCATED) &&
+		    shmsegs[i].u.shm_perm.key == key)
 			return (i);
 	return (-1);
 }
 
-static struct shmid_ds *
+static struct shmid_kernel *
 shm_find_segment_by_shmid(int shmid, int wantrem)
 {
 	int segnum;
-	struct shmid_ds *shmseg;
+	struct shmid_kernel *shmseg;
 
 	segnum = IPCID_TO_IX(shmid);
 	if (segnum < 0 || segnum >= shmalloced)
 		return (NULL);
 	shmseg = &shmsegs[segnum];
-	if (!((shmseg->shm_perm.mode & SHMSEG_ALLOCATED) ||
-  	    (wantrem && !(shmseg->shm_perm.mode & SHMSEG_REMOVED))) ||
-	    shmseg->shm_perm.seq != IPCID_TO_SEQ(shmid))
+	if (!((shmseg->u.shm_perm.mode & SHMSEG_ALLOCATED) ||
+  	    (wantrem && !(shmseg->u.shm_perm.mode & SHMSEG_REMOVED))) ||
+	    shmseg->u.shm_perm.seq != IPCID_TO_SEQ(shmid))
 		return (NULL);
 	return (shmseg);
 }
 
-static struct shmid_ds *
+static struct shmid_kernel *
 shm_find_segment_by_shmidx(int segnum, int wantrem)
 {
-	struct shmid_ds *shmseg;
+	struct shmid_kernel *shmseg;
 
 	if (segnum < 0 || segnum >= shmalloced)
 		return (NULL);
 	shmseg = &shmsegs[segnum];
-	if (!((shmseg->shm_perm.mode & SHMSEG_ALLOCATED) ||
-  	    (wantrem && !(shmseg->shm_perm.mode & SHMSEG_REMOVED))))
+	if (!((shmseg->u.shm_perm.mode & SHMSEG_ALLOCATED) ||
+  	    (wantrem && !(shmseg->u.shm_perm.mode & SHMSEG_REMOVED))))
 		return (NULL);
 	return (shmseg);
 }
 
 static void
 shm_deallocate_segment(shmseg)
-	struct shmid_ds *shmseg;
+	struct shmid_kernel *shmseg;
 {
 	struct shm_handle *shm_handle;
 	size_t size;
 
 	GIANT_REQUIRED;
 
-	shm_handle = shmseg->shm_internal;
+	shm_handle = shmseg->u.shm_internal;
 	vm_object_deallocate(shm_handle->shm_object);
 	free(shm_handle, M_SHM);
-	shmseg->shm_internal = NULL;
-	size = round_page(shmseg->shm_segsz);
+	shmseg->u.shm_internal = NULL;
+	size = round_page(shmseg->u.shm_segsz);
 	shm_committed -= btoc(size);
 	shm_nused--;
-	shmseg->shm_perm.mode = SHMSEG_FREE;
+	shmseg->u.shm_perm.mode = SHMSEG_FREE;
+#ifdef MAC
+	/* XXX: Reset the MAC label */
+	mac_cleanup_ipc_shm(shmseg);
+#endif
 }
 
 static int
 shm_delete_mapping(struct vmspace *vm, struct shmmap_state *shmmap_s)
 {
-	struct shmid_ds *shmseg;
+	struct shmid_kernel *shmseg;
 	int segnum, result;
 	size_t size;
 
@@ -224,14 +236,14 @@
 
 	segnum = IPCID_TO_IX(shmmap_s->shmid);
 	shmseg = &shmsegs[segnum];
-	size = round_page(shmseg->shm_segsz);
+	size = round_page(shmseg->u.shm_segsz);
 	result = vm_map_remove(&vm->vm_map, shmmap_s->va, shmmap_s->va + size);
 	if (result != KERN_SUCCESS)
 		return (EINVAL);
 	shmmap_s->shmid = -1;
-	shmseg->shm_dtime = time_second;
-	if ((--shmseg->shm_nattch <= 0) &&
-	    (shmseg->shm_perm.mode & SHMSEG_REMOVED)) {
+	shmseg->u.shm_dtime = time_second;
+	if ((--shmseg->u.shm_nattch <= 0) &&
+	    (shmseg->u.shm_perm.mode & SHMSEG_REMOVED)) {
 		shm_deallocate_segment(shmseg);
 		shm_last_free = segnum;
 	}
@@ -259,6 +271,16 @@
 
 	if (!jail_sysvipc_allowed && jailed(td->td_ucred))
 		return (ENOSYS);
+
+	/* Prevent thread from going any further if module is (being) unloaded */
+	mtx_lock(&refcnt_mtx);
+	if (refcount < 0 ) {
+		mtx_unlock(&refcnt_mtx);
+		return (ENOSYS);
+	}
+	refcount++; /* Indicate that thread is active in the code-path */
+	mtx_unlock(&refcnt_mtx);
+
 	mtx_lock(&Giant);
 	shmmap_s = p->p_vmspace->vm_shm;
  	if (shmmap_s == NULL) {
@@ -275,9 +297,21 @@
 		error = EINVAL;
 		goto done2;
 	}
+#ifdef MAC
+	/* XXX It might be useful to move this into the shm_delete_mapping function */
+	struct shmid_kernel *shmsegptr;
+	shmsegptr = &shmsegs[IPCID_TO_IX(shmmap_s->shmid)];
+  if(( error = mac_check_ipc_shmdt(td->td_ucred, shmsegptr) )) { 
+    printf(("MAC Framework:  mac_check_ipc_shmdt access denied\n"));
+    goto done2;
+  }
+#endif
 	error = shm_delete_mapping(p->p_vmspace, shmmap_s);
 done2:
 	mtx_unlock(&Giant);
+	mtx_lock(&refcnt_mtx);
+	refcount--; /* Indicate that thread no longer active in the code-path */
+	mtx_unlock(&refcnt_mtx);
 	return (error);
 }
 
@@ -302,7 +336,7 @@
 {
 	struct proc *p = td->td_proc;
 	int i, flags;
-	struct shmid_ds *shmseg;
+	struct shmid_kernel *shmseg;
 	struct shmmap_state *shmmap_s = NULL;
 	struct shm_handle *shm_handle;
 	vm_offset_t attach_va;
@@ -313,6 +347,16 @@
 
 	if (!jail_sysvipc_allowed && jailed(td->td_ucred))
 		return (ENOSYS);
+
+	/* Prevent thread from going any further if module is (being) unloaded */
+	mtx_lock(&refcnt_mtx);
+	if (refcount < 0 ) {
+		mtx_unlock(&refcnt_mtx);
+		return (ENOSYS);
+	}
+	refcount++; /* Indicate that thread is active in the code-path */
+	mtx_unlock(&refcnt_mtx);
+
 	mtx_lock(&Giant);
 	shmmap_s = p->p_vmspace->vm_shm;
 	if (shmmap_s == NULL) {
@@ -327,10 +371,16 @@
 		error = EINVAL;
 		goto done2;
 	}
-	error = ipcperm(td, &shmseg->shm_perm,
+	error = ipcperm(td, &shmseg->u.shm_perm,
 	    (shmflg & SHM_RDONLY) ? IPC_R : IPC_R|IPC_W);
 	if (error)
 		goto done2;
+#ifdef MAC
+  if(( error = mac_check_ipc_shmat(td->td_ucred, shmseg, shmflg) )) { 
+    printf(("MAC Framework:  mac_check_ipc_shmat access denied\n"));
+    goto done2;
+  }
+#endif
 	for (i = 0; i < shminfo.shmseg; i++) {
 		if (shmmap_s->shmid == -1)
 			break;
@@ -340,7 +390,7 @@
 		error = EMFILE;
 		goto done2;
 	}
-	size = round_page(shmseg->shm_segsz);
+	size = round_page(shmseg->u.shm_segsz);
 #ifdef VM_PROT_READ_IS_EXEC
 	prot = VM_PROT_READ | VM_PROT_EXECUTE;
 #else
@@ -368,7 +418,7 @@
 		    + maxtsiz + maxdsiz);
 	}
 
-	shm_handle = shmseg->shm_internal;
+	shm_handle = shmseg->u.shm_internal;
 	vm_object_reference(shm_handle->shm_object);
 	rv = vm_map_find(&p->p_vmspace->vm_map, shm_handle->shm_object,
 		0, &attach_va, size, (flags & MAP_FIXED)?0:1, prot, prot, 0);
@@ -381,12 +431,15 @@
 
 	shmmap_s->va = attach_va;
 	shmmap_s->shmid = shmid;
-	shmseg->shm_lpid = p->p_pid;
-	shmseg->shm_atime = time_second;
-	shmseg->shm_nattch++;
+	shmseg->u.shm_lpid = p->p_pid;
+	shmseg->u.shm_atime = time_second;
+	shmseg->u.shm_nattch++;
 	td->td_retval[0] = attach_va;
 done2:
 	mtx_unlock(&Giant);
+	mtx_lock(&refcnt_mtx);
+	refcount--; /* Indicate that thread no longer active in the code-path */
+	mtx_unlock(&refcnt_mtx);
 	return (error);
 }
 
@@ -426,11 +479,21 @@
 {
 #ifdef COMPAT_43
 	int error = 0;
-	struct shmid_ds *shmseg;
+	struct shmid_kernel *shmseg;
 	struct oshmid_ds outbuf;
 
 	if (!jail_sysvipc_allowed && jailed(td->td_ucred))
 		return (ENOSYS);
+
+	/* Prevent thread from going any further if module is (being) unloaded */
+	mtx_lock(&refcnt_mtx);
+	if (refcount < 0 ) {
+		mtx_unlock(&refcnt_mtx);
+		return (ENOSYS);
+	}
+	refcount++; /* Indicate that thread is active in the code-path */
+	mtx_unlock(&refcnt_mtx);
+
 	mtx_lock(&Giant);
 	shmseg = shm_find_segment_by_shmid(uap->shmid, 0);
 	if (shmseg == NULL) {
@@ -439,18 +502,24 @@
 	}
 	switch (uap->cmd) {
 	case IPC_STAT:
-		error = ipcperm(td, &shmseg->shm_perm, IPC_R);
+		error = ipcperm(td, &shmseg->u.shm_perm, IPC_R);
 		if (error)
 			goto done2;
-		outbuf.shm_perm = shmseg->shm_perm;
-		outbuf.shm_segsz = shmseg->shm_segsz;
-		outbuf.shm_cpid = shmseg->shm_cpid;
-		outbuf.shm_lpid = shmseg->shm_lpid;
-		outbuf.shm_nattch = shmseg->shm_nattch;
-		outbuf.shm_atime = shmseg->shm_atime;
-		outbuf.shm_dtime = shmseg->shm_dtime;
-		outbuf.shm_ctime = shmseg->shm_ctime;
-		outbuf.shm_handle = shmseg->shm_internal;
+#ifdef MAC
+  	if(( error = mac_check_ipc_shmctl(td->td_ucred, shmseg, uap->cmd) )) {
+    	printf(("MAC Framework:  mac_check_ipc_shmctl access denied\n"));
+    	goto done2;
+  	}
+#endif
+		outbuf.shm_perm = shmseg->u.shm_perm;
+		outbuf.shm_segsz = shmseg->u.shm_segsz;
+		outbuf.shm_cpid = shmseg->u.shm_cpid;
+		outbuf.shm_lpid = shmseg->u.shm_lpid;
+		outbuf.shm_nattch = shmseg->u.shm_nattch;
+		outbuf.shm_atime = shmseg->u.shm_atime;
+		outbuf.shm_dtime = shmseg->u.shm_dtime;
+		outbuf.shm_ctime = shmseg->u.shm_ctime;
+		outbuf.shm_handle = shmseg->u.shm_internal;
 		error = copyout(&outbuf, uap->ubuf, sizeof(outbuf));
 		if (error)
 			goto done2;
@@ -462,6 +531,9 @@
 	}
 done2:
 	mtx_unlock(&Giant);
+	mtx_lock(&refcnt_mtx);
+	refcount--; /* Indicate that thread no longer active in the code-path */
+	mtx_unlock(&refcnt_mtx);
 	return (error);
 #else
 	return (EINVAL);
@@ -489,11 +561,20 @@
 	int wantrem;
 {
 	int error = 0;
-	struct shmid_ds *shmseg;
+	struct shmid_kernel *shmseg;
 
 	if (!jail_sysvipc_allowed && jailed(td->td_ucred))
 		return (ENOSYS);
 
+	/* Prevent thread from going any further if module is (being) unloaded */
+	mtx_lock(&refcnt_mtx);
+	if (refcount < 0 ) {
+		mtx_unlock(&refcnt_mtx);
+		return (ENOSYS);
+	}
+	refcount++; /* Indicate that thread is active in the code-path */
+	mtx_unlock(&refcnt_mtx);
+
 	mtx_lock(&Giant);
 	switch (cmd) {
 	case IPC_INFO:
@@ -525,40 +606,46 @@
 		error = EINVAL;
 		goto done2;
 	}
+#ifdef MAC
+  if(( error = mac_check_ipc_shmctl(td->td_ucred, shmseg, cmd) )) {
+  	printf(("MAC Framework:  mac_check_ipc_shmctl access denied\n"));
+  	goto done2;
+  }
+#endif
 	switch (cmd) {
 	case SHM_STAT:
 	case IPC_STAT:
-		error = ipcperm(td, &shmseg->shm_perm, IPC_R);
+		error = ipcperm(td, &shmseg->u.shm_perm, IPC_R);
 		if (error)
 			goto done2;
-		memcpy(buf, shmseg, sizeof(struct shmid_ds));
+		memcpy(buf, &shmseg->u, sizeof(struct shmid_ds));
 		if (bufsz)
 			*bufsz = sizeof(struct shmid_ds);
 		if (cmd == SHM_STAT)
-			td->td_retval[0] = IXSEQ_TO_IPCID(shmid, shmseg->shm_perm);
+			td->td_retval[0] = IXSEQ_TO_IPCID(shmid, shmseg->u.shm_perm);
 		break;
 	case IPC_SET: {
 		struct shmid_ds *shmid;
 
 		shmid = (struct shmid_ds *)buf;
-		error = ipcperm(td, &shmseg->shm_perm, IPC_M);
+		error = ipcperm(td, &shmseg->u.shm_perm, IPC_M);
 		if (error)
 			goto done2;
-		shmseg->shm_perm.uid = shmid->shm_perm.uid;
-		shmseg->shm_perm.gid = shmid->shm_perm.gid;
-		shmseg->shm_perm.mode =
-		    (shmseg->shm_perm.mode & ~ACCESSPERMS) |
+		shmseg->u.shm_perm.uid = shmid->shm_perm.uid;
+		shmseg->u.shm_perm.gid = shmid->shm_perm.gid;
+		shmseg->u.shm_perm.mode =
+		    (shmseg->u.shm_perm.mode & ~ACCESSPERMS) |
 		    (shmid->shm_perm.mode & ACCESSPERMS);
-		shmseg->shm_ctime = time_second;
+		shmseg->u.shm_ctime = time_second;
 		break;
 	}
 	case IPC_RMID:
-		error = ipcperm(td, &shmseg->shm_perm, IPC_M);
+		error = ipcperm(td, &shmseg->u.shm_perm, IPC_M);
 		if (error)
 			goto done2;
-		shmseg->shm_perm.key = IPC_PRIVATE;
-		shmseg->shm_perm.mode |= SHMSEG_REMOVED;
-		if (shmseg->shm_nattch <= 0) {
+		shmseg->u.shm_perm.key = IPC_PRIVATE;
+		shmseg->u.shm_perm.mode |= SHMSEG_REMOVED;
+		if (shmseg->u.shm_nattch <= 0) {
 			shm_deallocate_segment(shmseg);
 			shm_last_free = IPCID_TO_IX(shmid);
 		}
@@ -573,6 +660,9 @@
 	}
 done2:
 	mtx_unlock(&Giant);
+	mtx_lock(&refcnt_mtx);
+	refcount--; /* Indicate that thread no longer active in the code-path */
+	mtx_unlock(&refcnt_mtx);
 	return (error);
 }
 
@@ -629,17 +719,17 @@
 	int mode;
 	int segnum;
 {
-	struct shmid_ds *shmseg;
+	struct shmid_kernel *shmseg;
 	int error;
 
 	shmseg = &shmsegs[segnum];
-	if (shmseg->shm_perm.mode & SHMSEG_REMOVED) {
+	if (shmseg->u.shm_perm.mode & SHMSEG_REMOVED) {
 		/*
 		 * This segment is in the process of being allocated.  Wait
 		 * until it's done, and look the key up again (in case the
 		 * allocation failed or it was freed).
 		 */
-		shmseg->shm_perm.mode |= SHMSEG_WANTED;
+		shmseg->u.shm_perm.mode |= SHMSEG_WANTED;
 		error = tsleep(shmseg, PLOCK | PCATCH, "shmget", 0);
 		if (error)
 			return (error);
@@ -647,12 +737,17 @@
 	}
 	if ((uap->shmflg & (IPC_CREAT | IPC_EXCL)) == (IPC_CREAT | IPC_EXCL))
 		return (EEXIST);
-	error = ipcperm(td, &shmseg->shm_perm, mode);
+	error = ipcperm(td, &shmseg->u.shm_perm, mode);
+#ifdef MAC
+	if(( error = mac_check_ipc_shmget(td->td_ucred,shmseg,uap->shmflg) )) {
+		printf(("MAC Framework:  mac_check_ipc_shmget access denied\n"));
+	}
+#endif
 	if (error)
 		return (error);
-	if (uap->size && uap->size > shmseg->shm_segsz)
+	if (uap->size && uap->size > shmseg->u.shm_segsz)
 		return (EINVAL);
-	td->td_retval[0] = IXSEQ_TO_IPCID(segnum, shmseg->shm_perm);
+	td->td_retval[0] = IXSEQ_TO_IPCID(segnum, shmseg->u.shm_perm);
 	return (0);
 }
 
@@ -664,7 +759,7 @@
 {
 	int i, segnum, shmid, size;
 	struct ucred *cred = td->td_ucred;
-	struct shmid_ds *shmseg;
+	struct shmid_kernel *shmseg;
 	struct shm_handle *shm_handle;
 
 	GIANT_REQUIRED;
@@ -679,7 +774,7 @@
 	if (shm_last_free < 0) {
 		shmrealloc();	/* Maybe expand the shmsegs[] array. */
 		for (i = 0; i < shmalloced; i++)
-			if (shmsegs[i].shm_perm.mode & SHMSEG_FREE)
+			if (shmsegs[i].u.shm_perm.mode & SHMSEG_FREE)
 				break;
 		if (i == shmalloced)
 			return (ENOSPC);
@@ -693,12 +788,12 @@
 	 * In case we sleep in malloc(), mark the segment present but deleted
 	 * so that noone else tries to create the same key.
 	 */
-	shmseg->shm_perm.mode = SHMSEG_ALLOCATED | SHMSEG_REMOVED;
-	shmseg->shm_perm.key = uap->key;
-	shmseg->shm_perm.seq = (shmseg->shm_perm.seq + 1) & 0x7fff;
+	shmseg->u.shm_perm.mode = SHMSEG_ALLOCATED | SHMSEG_REMOVED;
+	shmseg->u.shm_perm.key = uap->key;
+	shmseg->u.shm_perm.seq = (shmseg->u.shm_perm.seq + 1) & 0x7fff;
 	shm_handle = (struct shm_handle *)
 	    malloc(sizeof(struct shm_handle), M_SHM, M_WAITOK);
-	shmid = IXSEQ_TO_IPCID(segnum, shmseg->shm_perm);
+	shmid = IXSEQ_TO_IPCID(segnum, shmseg->u.shm_perm);
 	
 	/*
 	 * We make sure that we have allocated a pager before we need
@@ -716,24 +811,27 @@
 	vm_object_set_flag(shm_handle->shm_object, OBJ_NOSPLIT);
 	VM_OBJECT_UNLOCK(shm_handle->shm_object);
 
-	shmseg->shm_internal = shm_handle;
-	shmseg->shm_perm.cuid = shmseg->shm_perm.uid = cred->cr_uid;
-	shmseg->shm_perm.cgid = shmseg->shm_perm.gid = cred->cr_gid;
-	shmseg->shm_perm.mode = (shmseg->shm_perm.mode & SHMSEG_WANTED) |
+	shmseg->u.shm_internal = shm_handle;
+	shmseg->u.shm_perm.cuid = shmseg->u.shm_perm.uid = cred->cr_uid;
+	shmseg->u.shm_perm.cgid = shmseg->u.shm_perm.gid = cred->cr_gid;
+	shmseg->u.shm_perm.mode = (shmseg->u.shm_perm.mode & SHMSEG_WANTED) |
 	    (mode & ACCESSPERMS) | SHMSEG_ALLOCATED;
-	shmseg->shm_segsz = uap->size;
-	shmseg->shm_cpid = td->td_proc->p_pid;
-	shmseg->shm_lpid = shmseg->shm_nattch = 0;
-	shmseg->shm_atime = shmseg->shm_dtime = 0;
-	shmseg->shm_ctime = time_second;
+	shmseg->u.shm_segsz = uap->size;
+	shmseg->u.shm_cpid = td->td_proc->p_pid;
+	shmseg->u.shm_lpid = shmseg->u.shm_nattch = 0;
+	shmseg->u.shm_atime = shmseg->u.shm_dtime = 0;
+#ifdef MAC
+  mac_create_ipc_shm(cred, shmseg);
+#endif
+	shmseg->u.shm_ctime = time_second;
 	shm_committed += btoc(size);
 	shm_nused++;
-	if (shmseg->shm_perm.mode & SHMSEG_WANTED) {
+	if (shmseg->u.shm_perm.mode & SHMSEG_WANTED) {
 		/*
 		 * Somebody else wanted this key while we were asleep.  Wake
 		 * them up now.
 		 */
-		shmseg->shm_perm.mode &= ~SHMSEG_WANTED;
+		shmseg->u.shm_perm.mode &= ~SHMSEG_WANTED;
 		wakeup(shmseg);
 	}
 	td->td_retval[0] = shmid;
@@ -753,6 +851,16 @@
 
 	if (!jail_sysvipc_allowed && jailed(td->td_ucred))
 		return (ENOSYS);
+
+	/* Prevent thread from going any further if module is (being) unloaded */
+	mtx_lock(&refcnt_mtx);
+	if (refcount < 0 ) {
+		mtx_unlock(&refcnt_mtx);
+		return (ENOSYS);
+	}
+	refcount++; /* Indicate that thread is active in the code-path */
+	mtx_unlock(&refcnt_mtx);
+
 	mtx_lock(&Giant);
 	mode = uap->shmflg & ACCESSPERMS;
 	if (uap->key != IPC_PRIVATE) {
@@ -772,6 +880,9 @@
 	error = shmget_allocate_segment(td, uap, mode);
 done2:
 	mtx_unlock(&Giant);
+	mtx_lock(&refcnt_mtx);
+	refcount--; /* Indicate that thread no longer active in the code-path */
+	mtx_unlock(&refcnt_mtx);
 	return (error);
 }
 
@@ -815,7 +926,7 @@
 	p2->p_vmspace->vm_shm = shmmap_s;
 	for (i = 0; i < shminfo.shmseg; i++, shmmap_s++)
 		if (shmmap_s->shmid != -1)
-			shmsegs[IPCID_TO_IX(shmmap_s->shmid)].shm_nattch++;
+			shmsegs[IPCID_TO_IX(shmmap_s->shmid)].u.shm_nattch++;
 }
 
 static void
@@ -830,6 +941,7 @@
 		vm->vm_shm = NULL;
 		for (i = 0, shm = base; i < shminfo.shmseg; i++, shm++) {
 			if (shm->shmid != -1)
+				/* XXX: Should the MAC framework enforce check here as well */
 				shm_delete_mapping(vm, shm);
 		}
 		free(base, M_SHM);
@@ -840,7 +952,7 @@
 shmrealloc(void)
 {
 	int i;
-	struct shmid_ds *newsegs;
+	struct shmid_kernel *newsegs;
 
 	if (shmalloced >= shminfo.shmmni)
 		return;
@@ -851,8 +963,11 @@
 	for (i = 0; i < shmalloced; i++)
 		bcopy(&shmsegs[i], &newsegs[i], sizeof(newsegs[0]));
 	for (; i < shminfo.shmmni; i++) {
-		shmsegs[i].shm_perm.mode = SHMSEG_FREE;
-		shmsegs[i].shm_perm.seq = 0;
+		shmsegs[i].u.shm_perm.mode = SHMSEG_FREE;
+		shmsegs[i].u.shm_perm.seq = 0;
+#ifdef MAC
+		mac_init_ipc_shm(&shmsegs[i]);
+#endif
 	}
 	free(shmsegs, M_SHM);
 	shmsegs = newsegs;
@@ -880,23 +995,53 @@
 	if (shmsegs == NULL)
 		panic("cannot allocate initial memory for sysvshm");
 	for (i = 0; i < shmalloced; i++) {
-		shmsegs[i].shm_perm.mode = SHMSEG_FREE;
-		shmsegs[i].shm_perm.seq = 0;
+		shmsegs[i].u.shm_perm.mode = SHMSEG_FREE;
+		shmsegs[i].u.shm_perm.seq = 0;
+#ifdef MAC
+		mac_init_ipc_shm(&shmsegs[i]);
+#endif
 	}
 	shm_last_free = 0;
 	shm_nused = 0;
 	shm_committed = 0;
 	shmexit_hook = &shmexit_myhook;
 	shmfork_hook = &shmfork_myhook;
+	refcount = 0;
+	/* 
+	 * It is not permissible to pass the same mutex to mtx_init() multiple 
+	 * times without intervening calls to mtx_destroy().
+	 * Since we cannot destroy the refcnt_mtx during shmunload, we check if the 
+	 * mtx_init has ever been called. If so, we dont need to do mtx_init as the 
+	 * mutex is already initialized.
+	 */
+	if ( mtx_initialized(&refcnt_mtx) == 0 )
+		mtx_init(&refcnt_mtx, "shmrefcnt", NULL, MTX_DEF);
 }
 
 static int
 shmunload()
 {
 
-	if (shm_nused > 0)
+	/* 
+	 * Make sure that the shmunload maintains the consistency of the shmsegs
+	 * data structure. This assures that the unload doesn't take place if any 
+	 * thread is in any of the code-paths (tinkering with the data structures), 
+	 * and also that no thread can enter the code-paths once the module is 
+	 * unloaded. 
+	 */
+	mtx_lock(&refcnt_mtx);
+	if ((refcount > 0) || (shm_nused > 0)) {
+		mtx_unlock(&refcnt_mtx);
 		return (EBUSY);
+	}
+	refcount= -1; /* Mark the module as being unloaded */
+	mtx_unlock(&refcnt_mtx);
 
+#ifdef MAC
+	int i;	
+	for (i = 0; i < shmalloced; i++) 
+  	mac_destroy_ipc_shm(&shmsegs[i]);
+#endif
 	free(shmsegs, M_SHM);
 	shmexit_hook = NULL;
 	shmfork_hook = NULL;
@@ -907,6 +1052,7 @@
 sysctl_shmsegs(SYSCTL_HANDLER_ARGS)
 {
 
+	/* TODO: Change from shmid_ds to shmid_kernel needs to be incorporated */
 	return (SYSCTL_OUT(req, shmsegs, shmalloced * sizeof(shmsegs[0])));
 }
 
--- //depot/projects/trustedbsd/mac/sys/modules/sysvipc/sysvmsg/Makefile	2001/11/17 06:10:00
+++ //depot/user/hdandeka/rishi_SystemVIPC/sys/modules/sysvipc/sysvmsg/Makefile	2003/05/23 16:38:07
@@ -3,6 +3,6 @@
 .PATH: ${.CURDIR}/../../../kern
 
 KMOD=	sysvmsg
-SRCS=	sysv_msg.c opt_sysvipc.h
+SRCS=	sysv_msg.c opt_sysvipc.h opt_mac.h
 
 .include <bsd.kmod.mk>
--- //depot/projects/trustedbsd/mac/sys/modules/sysvipc/sysvsem/Makefile	2001/11/17 06:10:00
+++ //depot/user/hdandeka/rishi_SystemVIPC/sys/modules/sysvipc/sysvsem/Makefile	2003/05/30 18:42:59
@@ -3,6 +3,6 @@
 .PATH: ${.CURDIR}/../../../kern
 
 KMOD=	sysvsem
-SRCS=	sysv_sem.c opt_sysvipc.h
+SRCS=	sysv_sem.c opt_sysvipc.h opt_mac.h
 
 .include <bsd.kmod.mk>
--- //depot/projects/trustedbsd/mac/sys/modules/sysvipc/sysvshm/Makefile	2001/11/17 06:10:00
+++ //depot/user/hdandeka/rishi_SystemVIPC/sys/modules/sysvipc/sysvshm/Makefile	2003/06/03 19:22:59
@@ -3,7 +3,7 @@
 .PATH: ${.CURDIR}/../../../kern
 
 KMOD=	sysvshm
-OPTS=	opt_sysvipc.h opt_compat.h
+OPTS=	opt_sysvipc.h opt_compat.h opt_mac.h
 SRCS=	sysv_shm.c $(OPTS)
 
 .include <bsd.kmod.mk>
--- //depot/projects/trustedbsd/mac/sys/security/mac_biba/mac_biba.c	2003/06/02 12:26:58
+++ //depot/user/hdandeka/rishi_SystemVIPC/sys/security/mac_biba/mac_biba.c	2003/06/13 16:12:32
@@ -60,6 +60,10 @@
 #include <sys/socketvar.h>
 #include <sys/pipe.h>
 #include <sys/sysctl.h>
+#include <sys/msg.h>
+#include <sys/msg_msg.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
 
 #include <fs/devfs/devfs.h>
 
@@ -1151,6 +1155,58 @@
 }
 
 /*
+ * Labeling event operations: System V IPC objects.
+ */
+
+static void
+mac_biba_create_ipc_msgmsg(struct ucred *cred, struct msg *msgptr,
+								    struct label *msglabel)
+{
+	struct mac_biba *source, *dest;
+
+	source = SLOT(&cred->cr_label);
+	dest = SLOT(msglabel);
+
+	mac_biba_copy_single(source, dest);
+}   
+
+static void 
+mac_biba_create_ipc_msgqueue(struct ucred *cred, struct msqid_kernel *msqkptr,
+								    struct label *msqlabel)
+{
+	struct mac_biba *source, *dest;
+
+	source = SLOT(&cred->cr_label);
+	dest = SLOT(msqlabel);
+
+	mac_biba_copy_single(source, dest);
+}
+
+static void
+mac_biba_create_ipc_sema(struct ucred *cred, struct semid_kernel *semakptr,
+								    struct label *semalabel)
+{
+	struct mac_biba *source, *dest;
+
+	source = SLOT(&cred->cr_label);
+	dest = SLOT(semalabel);
+
+	mac_biba_copy_single(source, dest);
+}
+
+static void
+mac_biba_create_ipc_shm(struct ucred *cred, struct shmid_kernel *shmsegptr,
+								    struct label *shmlabel)
+{
+	struct mac_biba *source, *dest;
+
+	source = SLOT(&cred->cr_label);
+	dest = SLOT(shmlabel);
+
+	mac_biba_copy_single(source, dest);
+}
+
+/*
  * Labeling event operations: network objects.
  */
 static void
@@ -1427,6 +1483,33 @@
 }
 
 /*
+ * Label cleanup/flush operations
+ */
+static void 
+mac_biba_cleanup_ipc_msgmsg(struct label *msglabel)
+{
+				bzero(SLOT(msglabel), sizeof(struct mac_biba));
+}
+
+static void 
+mac_biba_cleanup_ipc_msgqueue(struct label *msqlabel)
+{
+				bzero(SLOT(msqlabel), sizeof(struct mac_biba));
+}
+
+static void 
+mac_biba_cleanup_ipc_sema(struct label *semalabel)
+{
+				bzero(SLOT(semalabel), sizeof(struct mac_biba));
+}
+
+static void 
+mac_biba_cleanup_ipc_shm(struct label *shmlabel)
+{
+				bzero(SLOT(shmlabel), sizeof(struct mac_biba));
+}
+
+/*
  * Access control checks.
  */
 static int
@@ -1588,7 +1671,294 @@
 	return (mac_biba_single_in_range(p, i) ? 0 : EACCES);
 }
 
+    
+static int
+mac_biba_check_ipc_msgrcv(struct ucred *cred, struct msg *msgptr)
+{   
+
+	struct mac_biba *subj, *obj;
+
+	if (!mac_biba_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&msgptr->label);
+
+	if (!mac_biba_dominate_single(obj, subj))
+		return (EACCES);
+
+	return (0);
+}
+
+static int
+mac_biba_check_ipc_msgrmid(struct ucred *cred, struct msg *msgptr)
+{   
+
+	struct mac_biba *subj, *obj;
+
+	if (!mac_biba_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&msgptr->label);
+
+	if (!mac_biba_dominate_single(subj, obj))
+		return (EACCES);
+
+	return (0);
+}
+
+static int
+mac_biba_check_ipc_msqget(struct ucred *cred, struct msqid_kernel *msqkptr)
+{
+	struct mac_biba *subj, *obj;
+
+	if (!mac_biba_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&msqkptr->label);
+
+	if (!mac_biba_dominate_single(obj, subj))
+		return (EACCES);
+
+	return (0);
+}
+
+
+static int
+mac_biba_check_ipc_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr)
+{
+	struct mac_biba *subj, *obj;
+
+	if (!mac_biba_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&msqkptr->label);
+
+	if (!mac_biba_dominate_single(subj, obj))
+		return (EACCES);
+
+	return (0);
+}
+
+static int
+mac_biba_check_ipc_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr)
+{
+	struct mac_biba *subj, *obj;
+
+	if (!mac_biba_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&msqkptr->label);
+
+	if (!mac_biba_dominate_single(obj, subj))
+		return (EACCES);
+
+	return (0);
+}
+
+
+static int
+mac_biba_check_ipc_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
+								                    int cmd)
+{
+	struct mac_biba *subj, *obj;
+
+	if (!mac_biba_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&msqkptr->label);
+	switch(cmd) {
+					case IPC_RMID:
+					case IPC_SET:
+						if (!mac_biba_dominate_single(subj, obj))
+							return (EACCES);
+						break;
+					case IPC_STAT:
+						if (!mac_biba_dominate_single(obj, subj))
+							return (EACCES);
+						break;
+					default:
+						return (EACCES);
+	}
+	return (0);
+}
+
 static int
+mac_biba_check_ipc_semctl(struct ucred *cred, struct semid_kernel *semakptr,
+								                    int cmd)
+{
+	struct mac_biba *subj, *obj;
+
+	if (!mac_biba_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&semakptr->label);
+	switch(cmd) {
+					case IPC_RMID:
+					case IPC_SET:
+					case SETVAL:
+					case SETALL:
+						if (!mac_biba_dominate_single(subj, obj))
+							return (EACCES);
+						break;
+					case IPC_STAT:
+					case GETVAL:
+					case GETPID:
+					case GETNCNT:
+					case GETZCNT:
+					case GETALL:
+						if (!mac_biba_dominate_single(obj, subj))
+							return (EACCES);
+						break;
+					default:
+						return (EACCES);
+	}
+	return (0);
+}
+
+
+static int
+mac_biba_check_ipc_semget(struct ucred *cred, struct semid_kernel *semakptr)
+{
+	struct mac_biba *subj, *obj;
+
+	if (!mac_biba_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&semakptr->label);
+
+	if (!mac_biba_dominate_single(obj, subj))
+		return (EACCES);
+
+	return (0);
+}
+
+
+static int
+mac_biba_check_ipc_semop(struct ucred *cred, struct semid_kernel *semakptr,
+								                        size_t accesstype)
+{
+	struct mac_biba *subj, *obj;
+
+	if (!mac_biba_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&semakptr->label);
+
+	if( accesstype & SEM_R )
+		if (!mac_biba_dominate_single(obj, subj))
+			return (EACCES);
+
+	if( accesstype & SEM_A )
+		if (!mac_biba_dominate_single(subj, obj))
+			return (EACCES);
+
+	return (0);
+ 
+}
+
+static int
+mac_biba_check_ipc_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
+								                        int shmflg)
+{
+	struct mac_biba *subj, *obj;
+
+	if (!mac_biba_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&shmsegptr->label);
+
+	if (!mac_biba_dominate_single(obj, subj))
+			return (EACCES);
+	if ((shmflg & SHM_RDONLY) == 0) 
+		if (!mac_biba_dominate_single(subj, obj))
+			return (EACCES);
+	
+	return (0);
+}
+
+static int
+mac_biba_check_ipc_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
+								                        int cmd)
+{
+	struct mac_biba *subj, *obj;
+
+	if (!mac_biba_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&shmsegptr->label);
+	switch(cmd) {
+					case IPC_RMID:
+					case IPC_SET:
+						if (!mac_biba_dominate_single(subj, obj))
+							return (EACCES);
+						break;
+					case IPC_STAT:
+					case SHM_STAT:
+						if (!mac_biba_dominate_single(obj, subj))
+							return (EACCES);
+						break;
+					default:
+						return (EACCES);
+	}
+	return (0);
+}
+
+#if 0
+
+/* 
+ * TODO: Do we check the integrity of the implicit write access caused
+ * by the bookkeeping tasks associated with the shmdt call, which may 
+ * modify/delete the shmseg meta-data and/or the shared segment itself? 
+ */
+
+static int
+mac_biba_check_ipc_shmdt(struct ucred *cred, struct shmid_kernel *shmsegptr)
+{
+	struct mac_biba *subj, *obj;
+
+	if (!mac_biba_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&shmsegptr->label);
+
+	if (!mac_biba_dominate_single(subj, obj))
+		return (EACCES);
+	
+	return (0);
+}
+#endif
+
+static int
+mac_biba_check_ipc_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
+								                         int shmflg)
+{
+	struct mac_biba *subj, *obj;
+
+	if (!mac_biba_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&shmsegptr->label);
+
+	if (!mac_biba_dominate_single(obj, subj))
+		return (EACCES);
+
+	return (0);
+}
+
+static int
 mac_biba_check_kld_load(struct ucred *cred, struct vnode *vp,
     struct label *label)
 {
@@ -2667,6 +3037,10 @@
 	.mpo_init_cred_label = mac_biba_init_label,
 	.mpo_init_devfsdirent_label = mac_biba_init_label,
 	.mpo_init_ifnet_label = mac_biba_init_label,
+	.mpo_init_ipc_msgmsg_label = mac_biba_init_label,
+  .mpo_init_ipc_msgqueue_label = mac_biba_init_label,
+  .mpo_init_ipc_sema_label = mac_biba_init_label,
+  .mpo_init_ipc_shm_label = mac_biba_init_label,
 	.mpo_init_ipq_label = mac_biba_init_label_waitcheck,
 	.mpo_init_mbuf_label = mac_biba_init_label_waitcheck,
 	.mpo_init_mount_label = mac_biba_init_label,
@@ -2679,6 +3053,10 @@
 	.mpo_destroy_cred_label = mac_biba_destroy_label,
 	.mpo_destroy_devfsdirent_label = mac_biba_destroy_label,
 	.mpo_destroy_ifnet_label = mac_biba_destroy_label,
+	.mpo_destroy_ipc_msgmsg_label = mac_biba_destroy_label,
+  .mpo_destroy_ipc_msgqueue_label = mac_biba_destroy_label,
+  .mpo_destroy_ipc_sema_label = mac_biba_destroy_label,
+  .mpo_destroy_ipc_shm_label = mac_biba_destroy_label,
 	.mpo_destroy_ipq_label = mac_biba_destroy_label,
 	.mpo_destroy_mbuf_label = mac_biba_destroy_label,
 	.mpo_destroy_mount_label = mac_biba_destroy_label,
@@ -2725,6 +3103,10 @@
 	.mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq,
 	.mpo_create_fragment = mac_biba_create_fragment,
 	.mpo_create_ifnet = mac_biba_create_ifnet,
+	.mpo_create_ipc_msgmsg = mac_biba_create_ipc_msgmsg,
+  .mpo_create_ipc_msgqueue = mac_biba_create_ipc_msgqueue,
+  .mpo_create_ipc_sema = mac_biba_create_ipc_sema,
+  .mpo_create_ipc_shm = mac_biba_create_ipc_shm,
 	.mpo_create_ipq = mac_biba_create_ipq,
 	.mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf,
 	.mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer,
@@ -2739,11 +3121,28 @@
 	.mpo_create_proc0 = mac_biba_create_proc0,
 	.mpo_create_proc1 = mac_biba_create_proc1,
 	.mpo_relabel_cred = mac_biba_relabel_cred,
+	.mpo_cleanup_ipc_msgmsg = mac_biba_cleanup_ipc_msgmsg,
+	.mpo_cleanup_ipc_msgqueue = mac_biba_cleanup_ipc_msgqueue,
+	.mpo_cleanup_ipc_sema = mac_biba_cleanup_ipc_sema,
+	.mpo_cleanup_ipc_shm = mac_biba_cleanup_ipc_shm,
 	.mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive,
 	.mpo_check_cred_relabel = mac_biba_check_cred_relabel,
 	.mpo_check_cred_visible = mac_biba_check_cred_visible,
 	.mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel,
 	.mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit,
+  .mpo_check_ipc_msgrcv = mac_biba_check_ipc_msgrcv,
+	.mpo_check_ipc_msgrmid = mac_biba_check_ipc_msgrmid,
+  .mpo_check_ipc_msqget = mac_biba_check_ipc_msqget,
+  .mpo_check_ipc_msqsnd = mac_biba_check_ipc_msqsnd,
+  .mpo_check_ipc_msqrcv = mac_biba_check_ipc_msqrcv,
+  .mpo_check_ipc_msqctl = mac_biba_check_ipc_msqctl,
+  .mpo_check_ipc_semctl = mac_biba_check_ipc_semctl,
+  .mpo_check_ipc_semget = mac_biba_check_ipc_semget,
+  .mpo_check_ipc_semop = mac_biba_check_ipc_semop,
+  .mpo_check_ipc_shmat = mac_biba_check_ipc_shmat,
+  .mpo_check_ipc_shmctl = mac_biba_check_ipc_shmctl,
+/* .mpo_check_ipc_shmdt = mac_biba_check_ipc_shmdt, */
+  .mpo_check_ipc_shmget = mac_biba_check_ipc_shmget,
 	.mpo_check_kld_load = mac_biba_check_kld_load,
 	.mpo_check_kld_unload = mac_biba_check_kld_unload,
 	.mpo_check_mount_stat = mac_biba_check_mount_stat,
--- //depot/projects/trustedbsd/mac/sys/security/mac_lomac/mac_lomac.c	2003/06/02 12:26:58
+++ //depot/user/hdandeka/rishi_SystemVIPC/sys/security/mac_lomac/mac_lomac.c	2003/06/13 18:14:49
@@ -60,6 +60,10 @@
 #include <sys/pipe.h>
 #include <sys/sysctl.h>
 #include <sys/syslog.h>
+#include <sys/msg.h>
+#include <sys/msg_msg.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
 
 #include <fs/devfs/devfs.h>
 
@@ -1223,6 +1227,59 @@
 }
 
 /*
+ * Labeling event operations: System V IPC objects.
+ */
+
+static void
+mac_lomac_create_ipc_msgmsg(struct ucred *cred, struct msg *msgptr,
+								    struct label *msglabel)
+{
+	struct mac_lomac *source, *dest;
+
+	source = SLOT(&cred->cr_label);
+	dest = SLOT(msglabel);
+
+	mac_lomac_copy_single(source, dest);
+}   
+
+static void 
+mac_lomac_create_ipc_msgqueue(struct ucred *cred, struct msqid_kernel *msqkptr,
+								    struct label *msqlabel)
+{
+	struct mac_lomac *source, *dest;
+
+	source = SLOT(&cred->cr_label);
+	dest = SLOT(msqlabel);
+
+	mac_lomac_copy_single(source, dest);
+}
+
+static void
+mac_lomac_create_ipc_sema(struct ucred *cred, struct semid_kernel *semakptr,
+								    struct label *semalabel)
+{
+	struct mac_lomac *source, *dest;
+
+	source = SLOT(&cred->cr_label);
+	dest = SLOT(semalabel);
+
+	mac_lomac_copy_single(source, dest);
+}
+
+static void
+mac_lomac_create_ipc_shm(struct ucred *cred, struct shmid_kernel *shmsegptr,
+								    struct label *shmlabel)
+{
+	struct mac_lomac *source, *dest;
+
+	source = SLOT(&cred->cr_label);
+	dest = SLOT(shmlabel);
+
+	mac_lomac_copy_single(source, dest);
+}
+
+
+/*
  * Labeling event operations: network objects.
  */
 static void
@@ -1568,6 +1625,34 @@
 }
 
 /*
+ * Label cleanup/flush operations
+ */
+static void 
+mac_lomac_cleanup_ipc_msgmsg(struct label *msglabel)
+{
+				bzero(SLOT(msglabel), sizeof(struct mac_lomac));
+}
+
+static void 
+mac_lomac_cleanup_ipc_msgqueue(struct label *msqlabel)
+{
+				bzero(SLOT(msqlabel), sizeof(struct mac_lomac));
+}
+
+static void 
+mac_lomac_cleanup_ipc_sema(struct label *semalabel)
+{
+				bzero(SLOT(semalabel), sizeof(struct mac_lomac));
+}
+
+static void 
+mac_lomac_cleanup_ipc_shm(struct label *shmlabel)
+{
+				bzero(SLOT(shmlabel), sizeof(struct mac_lomac));
+}
+
+
+/*
  * Access control checks.
  */
 static int
@@ -1742,6 +1827,292 @@
 }
 
 static int
+mac_lomac_check_ipc_msgrcv(struct ucred *cred, struct msg *msgptr)
+{   
+
+	struct mac_lomac *subj, *obj;
+
+	if (!mac_lomac_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&msgptr->label);
+
+	if (!mac_lomac_dominate_single(obj, subj))
+		return (maybe_demote(subj, obj, "msgrcv", "msg", NULL));
+
+	return (0);
+}
+
+static int
+mac_lomac_check_ipc_msgrmid(struct ucred *cred, struct msg *msgptr)
+{   
+
+	struct mac_lomac *subj, *obj;
+
+	if (!mac_lomac_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&msgptr->label);
+
+	if (!mac_lomac_dominate_single(subj, obj))
+		return (EACCES);
+
+	return (0);
+}
+
+static int
+mac_lomac_check_ipc_msqget(struct ucred *cred, struct msqid_kernel *msqkptr)
+{
+	struct mac_lomac *subj, *obj;
+
+	if (!mac_lomac_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&msqkptr->label);
+
+	if (!mac_lomac_dominate_single(obj, subj))
+		return (maybe_demote(subj, obj, "msqget", "msg", NULL));
+
+	return (0);
+}
+
+
+static int
+mac_lomac_check_ipc_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr)
+{
+	struct mac_lomac *subj, *obj;
+
+	if (!mac_lomac_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&msqkptr->label);
+
+	if (!mac_lomac_dominate_single(subj, obj))
+		return (EACCES);
+
+	return (0);
+}
+
+static int
+mac_lomac_check_ipc_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr)
+{
+	struct mac_lomac *subj, *obj;
+
+	if (!mac_lomac_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&msqkptr->label);
+
+	if (!mac_lomac_dominate_single(obj, subj))
+		return (maybe_demote(subj, obj, "msqrcv", "msg", NULL));
+
+	return (0);
+}
+
+
+static int
+mac_lomac_check_ipc_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
+								                    int cmd)
+{
+	struct mac_lomac *subj, *obj;
+
+	if (!mac_lomac_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&msqkptr->label);
+	switch(cmd) {
+					case IPC_RMID:
+					case IPC_SET:
+						if (!mac_lomac_dominate_single(subj, obj))
+							return (EACCES);
+						break;
+					case IPC_STAT:
+						if (!mac_lomac_dominate_single(obj, subj))
+							return (maybe_demote(subj, obj, "msqctl", "msg", NULL));
+						break;
+					default:
+						return (EACCES);
+	}
+	return (0);
+}
+
+static int
+mac_lomac_check_ipc_semctl(struct ucred *cred, struct semid_kernel *semakptr,
+								                    int cmd)
+{
+	struct mac_lomac *subj, *obj;
+
+	if (!mac_lomac_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&semakptr->label);
+	switch(cmd) {
+					case IPC_RMID:
+					case IPC_SET:
+					case SETVAL:
+					case SETALL:
+						if (!mac_lomac_dominate_single(subj, obj))
+							return (EACCES);
+						break;
+					case IPC_STAT:
+					case GETVAL:
+					case GETPID:
+					case GETNCNT:
+					case GETZCNT:
+					case GETALL:
+						if (!mac_lomac_dominate_single(obj, subj))
+							return (maybe_demote(subj, obj, "semctl", "sem", NULL));
+						break;
+					default:
+						return (EACCES);
+	}
+	return (0);
+}
+
+
+static int
+mac_lomac_check_ipc_semget(struct ucred *cred, struct semid_kernel *semakptr)
+{
+	struct mac_lomac *subj, *obj;
+
+	if (!mac_lomac_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&semakptr->label);
+
+	if (!mac_lomac_dominate_single(obj, subj))
+		return (maybe_demote(subj, obj, "semget", "sem", NULL));
+
+	return (0);
+}
+
+
+static int
+mac_lomac_check_ipc_semop(struct ucred *cred, struct semid_kernel *semakptr,
+								                        size_t accesstype)
+{
+	struct mac_lomac *subj, *obj;
+
+	if (!mac_lomac_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&semakptr->label);
+
+	if( accesstype & SEM_R )
+		if (!mac_lomac_dominate_single(obj, subj))
+			return (maybe_demote(subj, obj, "semop", "sem", NULL));
+
+	if( accesstype & SEM_A )
+		if (!mac_lomac_dominate_single(subj, obj))
+			return (EACCES);
+
+	return (0);
+ 
+}
+
+static int
+mac_lomac_check_ipc_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
+								                        int shmflg)
+{
+	struct mac_lomac *subj, *obj;
+
+	if (!mac_lomac_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&shmsegptr->label);
+
+	if (!mac_lomac_dominate_single(obj, subj))
+			return (maybe_demote(subj, obj, "shmat", "shm", NULL));
+	if ((shmflg & SHM_RDONLY) == 0) 
+		if (!mac_lomac_dominate_single(subj, obj))
+			return (EACCES);
+	
+	return (0);
+}
+
+static int
+mac_lomac_check_ipc_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
+								                        int cmd)
+{
+	struct mac_lomac *subj, *obj;
+
+	if (!mac_lomac_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&shmsegptr->label);
+	switch(cmd) {
+					case IPC_RMID:
+					case IPC_SET:
+						if (!mac_lomac_dominate_single(subj, obj))
+							return (EACCES);
+						break;
+					case IPC_STAT:
+					case SHM_STAT:
+						if (!mac_lomac_dominate_single(obj, subj))
+							return (maybe_demote(subj, obj, "shmctl", "shm", NULL));
+						break;
+					default:
+						return (EACCES);
+	}
+	return (0);
+}
+
+#if 0
+
+/* 
+ * TODO: Do we check the integrity of the implicit write access caused
+ * by the bookkeeping tasks associated with the shmdt call, which may 
+ * modify/delete the shmseg meta-data and/or the shared segment itself? 
+ */
+
+static int
+mac_lomac_check_ipc_shmdt(struct ucred *cred, struct shmid_kernel *shmsegptr)
+{
+	struct mac_lomac *subj, *obj;
+
+	if (!mac_lomac_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&shmsegptr->label);
+
+	if (!mac_lomac_dominate_single(subj, obj))
+		return (EACCES);
+	
+	return (0);
+}
+#endif
+
+static int
+mac_lomac_check_ipc_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
+								                         int shmflg)
+{
+	struct mac_lomac *subj, *obj;
+
+	if (!mac_lomac_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&shmsegptr->label);
+
+	if (!mac_lomac_dominate_single(obj, subj))
+		return (maybe_demote(subj, obj, "shmget", "shm", NULL));
+
+	return (0);
+}
+
+static int
 mac_lomac_check_kld_load(struct ucred *cred, struct vnode *vp,
     struct label *label)
 {
@@ -2606,6 +2977,10 @@
 	.mpo_init_cred_label = mac_lomac_init_label,
 	.mpo_init_devfsdirent_label = mac_lomac_init_label,
 	.mpo_init_ifnet_label = mac_lomac_init_label,
+	.mpo_init_ipc_msgmsg_label = mac_lomac_init_label,
+  .mpo_init_ipc_msgqueue_label = mac_lomac_init_label,
+  .mpo_init_ipc_sema_label = mac_lomac_init_label,
+  .mpo_init_ipc_shm_label = mac_lomac_init_label,
 	.mpo_init_ipq_label = mac_lomac_init_label_waitcheck,
 	.mpo_init_mbuf_label = mac_lomac_init_label_waitcheck,
 	.mpo_init_mount_label = mac_lomac_init_label,
@@ -2619,6 +2994,10 @@
 	.mpo_destroy_cred_label = mac_lomac_destroy_label,
 	.mpo_destroy_devfsdirent_label = mac_lomac_destroy_label,
 	.mpo_destroy_ifnet_label = mac_lomac_destroy_label,
+	.mpo_destroy_ipc_msgmsg_label = mac_lomac_destroy_label,
+  .mpo_destroy_ipc_msgqueue_label = mac_lomac_destroy_label,
+  .mpo_destroy_ipc_sema_label = mac_lomac_destroy_label,
+  .mpo_destroy_ipc_shm_label = mac_lomac_destroy_label,
 	.mpo_destroy_ipq_label = mac_lomac_destroy_label,
 	.mpo_destroy_mbuf_label = mac_lomac_destroy_label,
 	.mpo_destroy_mount_label = mac_lomac_destroy_label,
@@ -2667,6 +3046,10 @@
 	.mpo_create_datagram_from_ipq = mac_lomac_create_datagram_from_ipq,
 	.mpo_create_fragment = mac_lomac_create_fragment,
 	.mpo_create_ifnet = mac_lomac_create_ifnet,
+	.mpo_create_ipc_msgmsg = mac_lomac_create_ipc_msgmsg,
+  .mpo_create_ipc_msgqueue = mac_lomac_create_ipc_msgqueue,
+  .mpo_create_ipc_sema = mac_lomac_create_ipc_sema,
+  .mpo_create_ipc_shm = mac_lomac_create_ipc_shm,
 	.mpo_create_ipq = mac_lomac_create_ipq,
 	.mpo_create_mbuf_from_mbuf = mac_lomac_create_mbuf_from_mbuf,
 	.mpo_create_mbuf_linklayer = mac_lomac_create_mbuf_linklayer,
@@ -2684,11 +3067,29 @@
 	.mpo_create_proc0 = mac_lomac_create_proc0,
 	.mpo_create_proc1 = mac_lomac_create_proc1,
 	.mpo_relabel_cred = mac_lomac_relabel_cred,
+	.mpo_cleanup_ipc_msgmsg = mac_lomac_cleanup_ipc_msgmsg,
+	.mpo_cleanup_ipc_msgqueue = mac_lomac_cleanup_ipc_msgqueue,
+	.mpo_cleanup_ipc_sema = mac_lomac_cleanup_ipc_sema,
+	.mpo_cleanup_ipc_shm = mac_lomac_cleanup_ipc_shm,
 	.mpo_check_bpfdesc_receive = mac_lomac_check_bpfdesc_receive,
 	.mpo_check_cred_relabel = mac_lomac_check_cred_relabel,
 	.mpo_check_cred_visible = mac_lomac_check_cred_visible,
 	.mpo_check_ifnet_relabel = mac_lomac_check_ifnet_relabel,
 	.mpo_check_ifnet_transmit = mac_lomac_check_ifnet_transmit,
+/* .mpo_check_ipc_msgmsq = mac_lomac_check_ipc_msgmsq, */
+  .mpo_check_ipc_msgrcv = mac_lomac_check_ipc_msgrcv,
+	.mpo_check_ipc_msgrmid = mac_lomac_check_ipc_msgrmid,
+  .mpo_check_ipc_msqget = mac_lomac_check_ipc_msqget,
+  .mpo_check_ipc_msqsnd = mac_lomac_check_ipc_msqsnd,
+  .mpo_check_ipc_msqrcv = mac_lomac_check_ipc_msqrcv,
+  .mpo_check_ipc_msqctl = mac_lomac_check_ipc_msqctl,
+  .mpo_check_ipc_semctl = mac_lomac_check_ipc_semctl,
+  .mpo_check_ipc_semget = mac_lomac_check_ipc_semget,
+  .mpo_check_ipc_semop = mac_lomac_check_ipc_semop,
+  .mpo_check_ipc_shmat = mac_lomac_check_ipc_shmat,
+  .mpo_check_ipc_shmctl = mac_lomac_check_ipc_shmctl,
+/* .mpo_check_ipc_shmdt = mac_lomac_check_ipc_shmdt, */
+  .mpo_check_ipc_shmget = mac_lomac_check_ipc_shmget,
 	.mpo_check_kld_load = mac_lomac_check_kld_load,
 	.mpo_check_kld_unload = mac_lomac_check_kld_unload,
 	.mpo_check_pipe_ioctl = mac_lomac_check_pipe_ioctl,
--- //depot/projects/trustedbsd/mac/sys/security/mac_mls/mac_mls.c	2003/06/02 12:26:58
+++ //depot/user/hdandeka/rishi_SystemVIPC/sys/security/mac_mls/mac_mls.c	2003/06/13 16:12:32
@@ -60,6 +60,10 @@
 #include <sys/socketvar.h>
 #include <sys/pipe.h>
 #include <sys/sysctl.h>
+#include <sys/msg.h>
+#include <sys/msg_msg.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
 
 #include <fs/devfs/devfs.h>
 
@@ -1117,6 +1121,58 @@
 }
 
 /*
+ * Labeling event operations: System V IPC objects.
+ */
+
+static void
+mac_mls_create_ipc_msgmsg(struct ucred *cred, struct msg *msgptr,
+								    struct label *msglabel)
+{
+	struct mac_mls *source, *dest;
+
+	source = SLOT(&cred->cr_label);
+	dest = SLOT(msglabel);
+
+	mac_mls_copy_single(source, dest);
+}   
+
+static void 
+mac_mls_create_ipc_msgqueue(struct ucred *cred, struct msqid_kernel *msqkptr,
+								    struct label *msqlabel)
+{
+	struct mac_mls *source, *dest;
+
+	source = SLOT(&cred->cr_label);
+	dest = SLOT(msqlabel);
+
+	mac_mls_copy_single(source, dest);
+}
+
+static void
+mac_mls_create_ipc_sema(struct ucred *cred, struct semid_kernel *semakptr,
+								    struct label *semalabel)
+{
+	struct mac_mls *source, *dest;
+
+	source = SLOT(&cred->cr_label);
+	dest = SLOT(semalabel);
+
+	mac_mls_copy_single(source, dest);
+}
+
+static void
+mac_mls_create_ipc_shm(struct ucred *cred, struct shmid_kernel *shmsegptr,
+								    struct label *shmlabel)
+{
+	struct mac_mls *source, *dest;
+
+	source = SLOT(&cred->cr_label);
+	dest = SLOT(shmlabel);
+
+	mac_mls_copy_single(source, dest);
+}
+
+/*
  * Labeling event operations: network objects.
  */
 static void
@@ -1362,6 +1418,38 @@
 }
 
 /*
+ * Label cleanup/flush operations
+ */
+
+static void
+mac_mls_cleanup_ipc_msgmsg(struct label *msglabel)
+{
+
+	bzero(SLOT(msglabel), sizeof(struct mac_mls));
+}
+
+static void
+mac_mls_cleanup_ipc_msgqueue(struct label *msqlabel)
+{
+
+  bzero(SLOT(msqlabel), sizeof(struct mac_mls));
+}
+
+static void
+mac_mls_cleanup_ipc_sema(struct label *semalabel)
+{
+
+	bzero(SLOT(semalabel), sizeof(struct mac_mls));
+}
+
+static void
+mac_mls_cleanup_ipc_shm(struct label *shmlabel)
+{
+
+	bzero(SLOT(shmlabel), sizeof(struct mac_mls));
+}
+
+/*
  * Access control checks.
  */
 static int
@@ -1517,6 +1605,292 @@
 }
 
 static int
+mac_mls_check_ipc_msgrcv(struct ucred *cred, struct msg *msgptr)
+{   
+
+	struct mac_mls *subj, *obj;
+
+	if (!mac_mls_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&msgptr->label);
+
+	if (!mac_mls_dominate_single(subj, obj))
+		return (EACCES);
+
+	return (0);
+}
+
+static int
+mac_mls_check_ipc_msgrmid(struct ucred *cred, struct msg *msgptr)
+{   
+
+	struct mac_mls *subj, *obj;
+
+	if (!mac_mls_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&msgptr->label);
+
+	if (!mac_mls_dominate_single(obj, subj))
+		return (EACCES);
+
+	return (0);
+}
+
+static int
+mac_mls_check_ipc_msqget(struct ucred *cred, struct msqid_kernel *msqkptr)
+{
+	struct mac_mls *subj, *obj;
+
+	if (!mac_mls_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&msqkptr->label);
+
+	if (!mac_mls_dominate_single(subj, obj))
+		return (EACCES);
+
+	return (0);
+}
+
+
+static int
+mac_mls_check_ipc_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr)
+{
+	struct mac_mls *subj, *obj;
+
+	if (!mac_mls_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&msqkptr->label);
+
+	if (!mac_mls_dominate_single(obj, subj))
+		return (EACCES);
+
+	return (0);
+}
+
+static int
+mac_mls_check_ipc_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr)
+{
+	struct mac_mls *subj, *obj;
+
+	if (!mac_mls_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&msqkptr->label);
+
+	if (!mac_mls_dominate_single(subj, obj))
+		return (EACCES);
+
+	return (0);
+}
+
+
+static int
+mac_mls_check_ipc_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
+								                    int cmd)
+{
+	struct mac_mls *subj, *obj;
+
+	if (!mac_mls_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&msqkptr->label);
+	switch(cmd) {
+					case IPC_RMID:
+					case IPC_SET:
+						if (!mac_mls_dominate_single(obj, subj))
+							return (EACCES);
+						break;
+					case IPC_STAT:
+						if (!mac_mls_dominate_single(subj, obj))
+							return (EACCES);
+						break;
+					default:
+						return (EACCES);
+	}
+	return (0);
+}
+
+static int
+mac_mls_check_ipc_semctl(struct ucred *cred, struct semid_kernel *semakptr,
+								                    int cmd)
+{
+	struct mac_mls *subj, *obj;
+
+	if (!mac_mls_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&semakptr->label);
+	switch(cmd) {
+					case IPC_RMID:
+					case IPC_SET:
+					case SETVAL:
+					case SETALL:
+						if (!mac_mls_dominate_single(obj, subj))
+							return (EACCES);
+						break;
+					case IPC_STAT:
+					case GETVAL:
+					case GETPID:
+					case GETNCNT:
+					case GETZCNT:
+					case GETALL:
+						if (!mac_mls_dominate_single(subj, obj))
+							return (EACCES);
+						break;
+					default:
+						return (EACCES);
+	}
+	return (0);
+}
+
+
+static int
+mac_mls_check_ipc_semget(struct ucred *cred, struct semid_kernel *semakptr)
+{
+	struct mac_mls *subj, *obj;
+
+	if (!mac_mls_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&semakptr->label);
+
+	if (!mac_mls_dominate_single(subj, obj))
+		return (EACCES);
+
+	return (0);
+}
+
+
+static int
+mac_mls_check_ipc_semop(struct ucred *cred, struct semid_kernel *semakptr,
+								                        size_t accesstype)
+{
+	struct mac_mls *subj, *obj;
+
+	if (!mac_mls_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&semakptr->label);
+
+	if( accesstype & SEM_R )
+		if (!mac_mls_dominate_single(subj, obj))
+			return (EACCES);
+
+	if( accesstype & SEM_A )
+		if (!mac_mls_dominate_single(obj, subj))
+			return (EACCES);
+
+	return (0);
+ 
+}
+
+static int
+mac_mls_check_ipc_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
+								                        int shmflg)
+{
+	struct mac_mls *subj, *obj;
+
+	if (!mac_mls_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&shmsegptr->label);
+
+	if (!mac_mls_dominate_single(subj, obj))
+			return (EACCES);
+	if ((shmflg & SHM_RDONLY) == 0) 
+		if (!mac_mls_dominate_single(obj, subj))
+			return (EACCES);
+	
+	return (0);
+}
+
+static int
+mac_mls_check_ipc_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
+								                        int cmd)
+{
+	struct mac_mls *subj, *obj;
+
+	if (!mac_mls_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&shmsegptr->label);
+	switch(cmd) {
+					case IPC_RMID:
+					case IPC_SET:
+						if (!mac_mls_dominate_single(obj, subj))
+							return (EACCES);
+						break;
+					case IPC_STAT:
+					case SHM_STAT:
+						if (!mac_mls_dominate_single(subj, obj))
+							return (EACCES);
+						break;
+					default:
+						return (EACCES);
+	}
+	return (0);
+}
+
+#if 0
+
+/* 
+ * TODO: Do we check the integrity of the implicit write access caused
+ * by the bookkeeping tasks associated with the shmdt call, which may 
+ * modify/delete the shmseg meta-data and/or the shared segment itself? 
+ */
+
+static int
+mac_mls_check_ipc_shmdt(struct ucred *cred, struct shmid_kernel *shmsegptr)
+{
+	struct mac_mls *subj, *obj;
+
+	if (!mac_mls_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&shmsegptr->label);
+
+	if (!mac_mls_dominate_single(obj, subj))
+		return (EACCES);
+	
+	return (0);
+}
+#endif
+
+static int
+mac_mls_check_ipc_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
+								                         int shmflg)
+{
+	struct mac_mls *subj, *obj;
+
+	if (!mac_mls_enabled)
+		return (0);
+
+	subj = SLOT(&cred->cr_label);
+	obj = SLOT(&shmsegptr->label);
+
+	if (!mac_mls_dominate_single(obj, subj))
+		return (EACCES);
+
+	return (0);
+}
+
+static int
 mac_mls_check_mount_stat(struct ucred *cred, struct mount *mp,
     struct label *mntlabel)
 {
@@ -2438,6 +2812,10 @@
 	.mpo_init_cred_label = mac_mls_init_label,
 	.mpo_init_devfsdirent_label = mac_mls_init_label,
 	.mpo_init_ifnet_label = mac_mls_init_label,
+	.mpo_init_ipc_msgmsg_label = mac_mls_init_label,
+  .mpo_init_ipc_msgqueue_label = mac_mls_init_label,
+  .mpo_init_ipc_sema_label = mac_mls_init_label,
+  .mpo_init_ipc_shm_label = mac_mls_init_label,
 	.mpo_init_ipq_label = mac_mls_init_label_waitcheck,
 	.mpo_init_mbuf_label = mac_mls_init_label_waitcheck,
 	.mpo_init_mount_label = mac_mls_init_label,
@@ -2450,6 +2828,10 @@
 	.mpo_destroy_cred_label = mac_mls_destroy_label,
 	.mpo_destroy_devfsdirent_label = mac_mls_destroy_label,
 	.mpo_destroy_ifnet_label = mac_mls_destroy_label,
+	.mpo_destroy_ipc_msgmsg_label = mac_mls_destroy_label,
+  .mpo_destroy_ipc_msgqueue_label = mac_mls_destroy_label,
+  .mpo_destroy_ipc_sema_label = mac_mls_destroy_label,
+  .mpo_destroy_ipc_shm_label = mac_mls_destroy_label,
 	.mpo_destroy_ipq_label = mac_mls_destroy_label,
 	.mpo_destroy_mbuf_label = mac_mls_destroy_label,
 	.mpo_destroy_mount_label = mac_mls_destroy_label,
@@ -2497,6 +2879,10 @@
 	.mpo_create_fragment = mac_mls_create_fragment,
 	.mpo_create_ifnet = mac_mls_create_ifnet,
 	.mpo_create_ipq = mac_mls_create_ipq,
+	.mpo_create_ipc_msgmsg = mac_mls_create_ipc_msgmsg,
+  .mpo_create_ipc_msgqueue = mac_mls_create_ipc_msgqueue,
+  .mpo_create_ipc_sema = mac_mls_create_ipc_sema,
+  .mpo_create_ipc_shm = mac_mls_create_ipc_shm,
 	.mpo_create_mbuf_from_mbuf = mac_mls_create_mbuf_from_mbuf,
 	.mpo_create_mbuf_linklayer = mac_mls_create_mbuf_linklayer,
 	.mpo_create_mbuf_from_bpfdesc = mac_mls_create_mbuf_from_bpfdesc,
@@ -2510,11 +2896,28 @@
 	.mpo_create_proc0 = mac_mls_create_proc0,
 	.mpo_create_proc1 = mac_mls_create_proc1,
 	.mpo_relabel_cred = mac_mls_relabel_cred,
+	.mpo_cleanup_ipc_msgmsg = mac_mls_cleanup_ipc_msgmsg,
+  .mpo_cleanup_ipc_msgqueue = mac_mls_cleanup_ipc_msgqueue,
+  .mpo_cleanup_ipc_sema = mac_mls_cleanup_ipc_sema,
+  .mpo_cleanup_ipc_shm = mac_mls_cleanup_ipc_shm,
 	.mpo_check_bpfdesc_receive = mac_mls_check_bpfdesc_receive,
 	.mpo_check_cred_relabel = mac_mls_check_cred_relabel,
 	.mpo_check_cred_visible = mac_mls_check_cred_visible,
 	.mpo_check_ifnet_relabel = mac_mls_check_ifnet_relabel,
 	.mpo_check_ifnet_transmit = mac_mls_check_ifnet_transmit,
+  .mpo_check_ipc_msgrcv = mac_mls_check_ipc_msgrcv,
+	.mpo_check_ipc_msgrmid = mac_mls_check_ipc_msgrmid,
+  .mpo_check_ipc_msqget = mac_mls_check_ipc_msqget,
+  .mpo_check_ipc_msqsnd = mac_mls_check_ipc_msqsnd,
+  .mpo_check_ipc_msqrcv = mac_mls_check_ipc_msqrcv,
+  .mpo_check_ipc_msqctl = mac_mls_check_ipc_msqctl,
+  .mpo_check_ipc_semctl = mac_mls_check_ipc_semctl,
+  .mpo_check_ipc_semget = mac_mls_check_ipc_semget,
+  .mpo_check_ipc_semop = mac_mls_check_ipc_semop,
+  .mpo_check_ipc_shmat = mac_mls_check_ipc_shmat,
+  .mpo_check_ipc_shmctl = mac_mls_check_ipc_shmctl,
+/* .mpo_check_ipc_shmdt = mac_mls_check_ipc_shmdt, */
+  .mpo_check_ipc_shmget = mac_mls_check_ipc_shmget,
 	.mpo_check_mount_stat = mac_mls_check_mount_stat,
 	.mpo_check_pipe_ioctl = mac_mls_check_pipe_ioctl,
 	.mpo_check_pipe_poll = mac_mls_check_pipe_poll,
--- //depot/projects/trustedbsd/mac/sys/security/mac_none/mac_none.c	2003/06/02 12:26:58
+++ //depot/user/hdandeka/rishi_SystemVIPC/sys/security/mac_none/mac_none.c	2003/06/13 16:12:32
@@ -57,6 +57,10 @@
 #include <sys/socketvar.h>
 #include <sys/pipe.h>
 #include <sys/sysctl.h>
+#include <sys/msg.h>
+#include <sys/msg_msg.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
 
 #include <fs/devfs/devfs.h>
 
@@ -329,6 +333,34 @@
 
 }
 
+static void 
+mac_none_create_ipc_msgmsg(struct ucred *cred, struct msg *msgptr, 
+		struct label *msglabel)
+{
+
+}
+
+static void 
+mac_none_create_ipc_msgqueue(struct ucred *cred, struct msqid_kernel *msqkptr, 
+		struct label *msqlabel)
+{
+
+}
+
+static void 
+mac_none_create_ipc_sema(struct ucred *cred, struct semid_kernel *semakptr,
+		struct label *semalabel)
+{
+
+}
+
+static void 
+mac_none_create_ipc_shm(struct ucred *cred, struct shmid_kernel *shmsegptr, 
+		struct label *shmalabel)
+{
+
+}
+
 static void
 mac_none_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
     struct ipq *ipq, struct label *ipqlabel)
@@ -466,6 +498,34 @@
 }
 
 /*
+ * Label cleanup/flush operations
+ */
+static void 
+mac_none_cleanup_ipc_msgmsg(struct label *msglabel)
+{
+
+}
+
+static void 
+mac_none_cleanup_ipc_msgqueue(struct label *msqlabel)
+{
+
+}
+
+static void 
+mac_none_cleanup_ipc_sema(struct label *semalabel)
+{
+
+}
+
+static void 
+mac_none_cleanup_ipc_shm(struct label *shmlabel)
+{
+
+}
+
+
+/*
  * Access control checks.
  */
 static int
@@ -507,6 +567,123 @@
 }
 
 static int
+mac_none_check_ipc_msgmsq(struct ucred *cred, struct msg *msgptr, 
+								        struct msqid_kernel *msqkptr)
+{
+
+				  return (0);
+}
+
+static int
+mac_none_check_ipc_msgrcv(struct ucred *cred, struct msg *msgptr)
+{
+
+				          return (0);
+}
+
+
+static int
+mac_none_check_ipc_msgrmid(struct ucred *cred, struct msg *msgptr)
+{
+
+				          return (0);
+}
+
+
+static int
+mac_none_check_ipc_msqget(struct ucred *cred, struct msqid_kernel *msqkptr)
+{
+
+				          return (0);
+}
+
+
+static int
+mac_none_check_ipc_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr)
+{
+
+				          return (0);
+}
+
+
+static int
+mac_none_check_ipc_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr)
+{
+
+				          return (0);
+}
+
+
+static int
+mac_none_check_ipc_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
+								    int cmd)
+{
+
+				          return (0);
+}
+
+
+static int
+mac_none_check_ipc_semctl(struct ucred *cred, struct semid_kernel *semakptr,
+								    int cmd)
+{
+
+				          return (0);
+}
+
+
+static int
+mac_none_check_ipc_semget(struct ucred *cred, struct semid_kernel *semakptr)
+{
+
+				          return (0);
+}
+
+
+static int
+mac_none_check_ipc_semop(struct ucred *cred, struct semid_kernel *semakptr,
+								        size_t accesstype)
+{
+
+				          return (0);
+}
+
+
+static int
+mac_none_check_ipc_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
+								        int shmflg)
+{
+
+				          return (0);
+}
+
+
+static int
+mac_none_check_ipc_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
+								        int cmd)
+{
+
+				          return (0);
+}
+
+
+static int
+mac_none_check_ipc_shmdt(struct ucred *cred, struct shmid_kernel *shmsegptr)
+{
+
+				          return (0);
+}
+
+
+static int
+mac_none_check_ipc_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
+								         int shmflg)
+{
+
+				          return (0);
+}
+
+static int
 mac_none_check_kenv_dump(struct ucred *cred)
 {
 
@@ -988,6 +1165,10 @@
 	.mpo_init_cred_label = mac_none_init_label,
 	.mpo_init_devfsdirent_label = mac_none_init_label,
 	.mpo_init_ifnet_label = mac_none_init_label,
+	.mpo_init_ipc_msgmsg_label = mac_none_init_label,
+	.mpo_init_ipc_msgqueue_label = mac_none_init_label,
+  .mpo_init_ipc_sema_label = mac_none_init_label,
+  .mpo_init_ipc_shm_label = mac_none_init_label,
 	.mpo_init_ipq_label = mac_none_init_label_waitcheck,
 	.mpo_init_mbuf_label = mac_none_init_label_waitcheck,
 	.mpo_init_mount_label = mac_none_init_label,
@@ -1000,6 +1181,10 @@
 	.mpo_destroy_cred_label = mac_none_destroy_label,
 	.mpo_destroy_devfsdirent_label = mac_none_destroy_label,
 	.mpo_destroy_ifnet_label = mac_none_destroy_label,
+	.mpo_destroy_ipc_msgmsg_label = mac_none_destroy_label,
+	.mpo_destroy_ipc_msgqueue_label = mac_none_destroy_label,
+  .mpo_destroy_ipc_sema_label = mac_none_destroy_label,
+  .mpo_destroy_ipc_shm_label = mac_none_destroy_label,
 	.mpo_destroy_ipq_label = mac_none_destroy_label,
 	.mpo_destroy_mbuf_label = mac_none_destroy_label,
 	.mpo_destroy_mount_label = mac_none_destroy_label,
@@ -1025,6 +1210,10 @@
 	.mpo_create_devfs_device = mac_none_create_devfs_device,
 	.mpo_create_devfs_directory = mac_none_create_devfs_directory,
 	.mpo_create_devfs_symlink = mac_none_create_devfs_symlink,
+	.mpo_create_ipc_msgmsg = mac_none_create_ipc_msgmsg,
+	.mpo_create_ipc_msgqueue = mac_none_create_ipc_msgqueue,
+	.mpo_create_ipc_sema = mac_none_create_ipc_sema,
+	.mpo_create_ipc_shm = mac_none_create_ipc_shm,
 	.mpo_create_vnode_extattr = mac_none_create_vnode_extattr,
 	.mpo_create_mount = mac_none_create_mount,
 	.mpo_create_root_mount = mac_none_create_root_mount,
@@ -1063,11 +1252,29 @@
 	.mpo_create_proc1 = mac_none_create_proc1,
 	.mpo_relabel_cred = mac_none_relabel_cred,
 	.mpo_thread_userret = mac_none_thread_userret,
+	.mpo_cleanup_ipc_msgmsg = mac_none_cleanup_ipc_msgmsg,
+	.mpo_cleanup_ipc_msgqueue = mac_none_cleanup_ipc_msgqueue,
+	.mpo_cleanup_ipc_sema = mac_none_cleanup_ipc_sema,
+	.mpo_cleanup_ipc_shm = mac_none_cleanup_ipc_shm,
 	.mpo_check_bpfdesc_receive = mac_none_check_bpfdesc_receive,
 	.mpo_check_cred_relabel = mac_none_check_cred_relabel,
 	.mpo_check_cred_visible = mac_none_check_cred_visible,
 	.mpo_check_ifnet_relabel = mac_none_check_ifnet_relabel,
 	.mpo_check_ifnet_transmit = mac_none_check_ifnet_transmit,
+	.mpo_check_ipc_msgmsq = mac_none_check_ipc_msgmsq,
+	.mpo_check_ipc_msgrcv = mac_none_check_ipc_msgrcv,
+	.mpo_check_ipc_msgrmid = mac_none_check_ipc_msgrmid,
+	.mpo_check_ipc_msqget = mac_none_check_ipc_msqget,
+	.mpo_check_ipc_msqsnd = mac_none_check_ipc_msqsnd,
+	.mpo_check_ipc_msqrcv = mac_none_check_ipc_msqrcv,
+	.mpo_check_ipc_msqctl = mac_none_check_ipc_msqctl,
+	.mpo_check_ipc_semctl = mac_none_check_ipc_semctl,
+	.mpo_check_ipc_semget = mac_none_check_ipc_semget,
+	.mpo_check_ipc_semop = mac_none_check_ipc_semop,
+	.mpo_check_ipc_shmat = mac_none_check_ipc_shmat,
+	.mpo_check_ipc_shmctl = mac_none_check_ipc_shmctl,
+	.mpo_check_ipc_shmdt = mac_none_check_ipc_shmdt,
+	.mpo_check_ipc_shmget = mac_none_check_ipc_shmget,
 	.mpo_check_kenv_dump = mac_none_check_kenv_dump,
 	.mpo_check_kenv_get = mac_none_check_kenv_get,
 	.mpo_check_kenv_set = mac_none_check_kenv_set,
--- //depot/projects/trustedbsd/mac/sys/security/mac_test/mac_test.c	2003/06/02 12:26:58
+++ //depot/user/hdandeka/rishi_SystemVIPC/sys/security/mac_test/mac_test.c	2003/06/13 16:12:32
@@ -57,6 +57,10 @@
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/sysctl.h>
+#include <sys/msg.h>
+#include <sys/msg_msg.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
 
 #include <fs/devfs/devfs.h>
 
@@ -85,6 +89,10 @@
 #define	MBUFMAGIC	0xbbefa5bb
 #define	MOUNTMAGIC	0xc7c46e47
 #define	SOCKETMAGIC	0x9199c6cd
+#define	SYSVIPCMSQMAGIC	0xea672391
+#define	SYSVIPCMSGMAGIC	0x8bbba61e
+#define	SYSVIPCSEMMAGIC	0x896e8a0b
+#define	SYSVIPCSHMMAGIC	0x76119ab0
 #define	PIPEMAGIC	0xdc6c9919
 #define	PROCMAGIC	0x3b4be98f
 #define	CREDMAGIC	0x9a5a4987
@@ -107,6 +115,14 @@
 	SLOT(x) == 0, ("%s: Bad MOUNT label", __func__ ))
 #define	ASSERT_SOCKET_LABEL(x)	KASSERT(SLOT(x) == SOCKETMAGIC ||	\
 	SLOT(x) == 0, ("%s: Bad SOCKET label", __func__ ))
+#define	ASSERT_SYSVIPCMSQ_LABEL(x)	KASSERT(SLOT(x) == SYSVIPCMSQMAGIC ||	\
+	SLOT(x) == 0, ("%s: Bad SYSVIPCMSQ label", __func__ ))
+#define	ASSERT_SYSVIPCMSG_LABEL(x)	KASSERT(SLOT(x) == SYSVIPCMSGMAGIC ||	\
+	SLOT(x) == 0, ("%s: Bad SYSVIPCMSG label", __func__ ))
+#define	ASSERT_SYSVIPCSEM_LABEL(x)	KASSERT(SLOT(x) == SYSVIPCSEMMAGIC ||	\
+	SLOT(x) == 0, ("%s: Bad SYSVIPCSEM label", __func__ ))
+#define	ASSERT_SYSVIPCSHM_LABEL(x)	KASSERT(SLOT(x) == SYSVIPCSHMMAGIC ||	\
+	SLOT(x) == 0, ("%s: Bad SYSVIPCSHM label", __func__ ))
 #define	ASSERT_PIPE_LABEL(x)	KASSERT(SLOT(x) == PIPEMAGIC ||		\
 	SLOT(x) == 0, ("%s: Bad PIPE label", __func__ ))
 #define	ASSERT_PROC_LABEL(x)	KASSERT(SLOT(x) == PROCMAGIC ||		\
@@ -132,6 +148,18 @@
 static int	init_count_ifnet;
 SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_ifnet, CTLFLAG_RD,
     &init_count_ifnet, 0, "ifnet init calls");
+static int	init_count_ipc_msg;
+SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_ipc_msg, CTLFLAG_RD,
+    &init_count_ipc_msg, 0, "ipc_msg init calls");
+static int	init_count_ipc_msq;
+SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_ipc_msq, CTLFLAG_RD,
+    &init_count_ipc_msq, 0, "ipc_msq init calls");
+static int	init_count_ipc_sema;
+SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_ipc_sema, CTLFLAG_RD,
+    &init_count_ipc_sema, 0, "ipc_sema init calls");
+static int	init_count_ipc_shm;
+SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_ipc_shm, CTLFLAG_RD,
+    &init_count_ipc_shm, 0, "ipc_shm init calls");
 static int	init_count_ipq;
 SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_ipq, CTLFLAG_RD,
     &init_count_ipq, 0, "ipq init calls");
@@ -173,6 +201,18 @@
 static int	destroy_count_ifnet;
 SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_ifnet, CTLFLAG_RD,
     &destroy_count_ifnet, 0, "ifnet destroy calls");
+static int	destroy_count_ipc_msg;
+SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_ipc_msg, CTLFLAG_RD,
+    &destroy_count_ipc_msg, 0, "ipc_msg destroy calls");
+static int	destroy_count_ipc_msq;
+SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_ipc_msq, CTLFLAG_RD,
+    &destroy_count_ipc_msq, 0, "ipc_msq destroy calls");
+static int	destroy_count_ipc_sema;
+SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_ipc_sema, CTLFLAG_RD,
+    &destroy_count_ipc_sema, 0, "ipc_sema destroy calls");
+static int	destroy_count_ipc_shm;
+SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_ipc_shm, CTLFLAG_RD,
+    &destroy_count_ipc_shm, 0, "ipc_shm destroy calls");
 static int	destroy_count_ipq;
 SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_ipq, CTLFLAG_RD,
     &destroy_count_ipq, 0, "ipq destroy calls");
@@ -267,6 +307,34 @@
 	atomic_add_int(&init_count_ifnet, 1);
 }
 
+static void
+mac_test_init_ipc_msgmsg_label(struct label *label)
+{
+	SLOT(label) = SYSVIPCMSGMAGIC;
+	atomic_add_int(&init_count_ipc_msg, 1);
+}
+
+static void
+mac_test_init_ipc_msgqueue_label(struct label *label)
+{
+	SLOT(label) = SYSVIPCMSQMAGIC;
+	atomic_add_int(&init_count_ipc_msq, 1);
+}
+
+static void
+mac_test_init_ipc_sema_label(struct label *label)
+{
+	SLOT(label) = SYSVIPCSEMMAGIC;
+	atomic_add_int(&init_count_ipc_sema, 1);
+}
+
+static void
+mac_test_init_ipc_shm_label(struct label *label)
+{
+	SLOT(label) = SYSVIPCSHMMAGIC;
+	atomic_add_int(&init_count_ipc_shm, 1);
+}
+
 static int
 mac_test_init_ipq_label(struct label *label, int flag)
 {
@@ -420,6 +488,62 @@
 }
 
 static void
+mac_test_destroy_ipc_msgmsg_label(struct label *label)
+{
+
+	if (SLOT(label) == SYSVIPCMSGMAGIC || SLOT(label) == 0) {
+		atomic_add_int(&destroy_count_ipc_msg, 1);
+		SLOT(label) = EXMAGIC;
+	} else if (SLOT(label) == EXMAGIC) {
+		Debugger("mac_test_destroy_ipc_msgmsg_label: dup destroy");
+	} else {
+		Debugger("mac_test_destroy_ipc_msgmsg_label: corrupted label");
+	}
+}
+
+static void
+mac_test_destroy_ipc_msgqueue_label(struct label *label)
+{
+
+	if (SLOT(label) == SYSVIPCMSQMAGIC || SLOT(label) == 0) {
+		atomic_add_int(&destroy_count_ipc_msq, 1);
+		SLOT(label) = EXMAGIC;
+	} else if (SLOT(label) == EXMAGIC) {
+		Debugger("mac_test_destroy_ipc_msgqueue_label: dup destroy");
+	} else {
+		Debugger("mac_test_destroy_ipc_msgqueue_label: corrupted label");
+	}
+}
+
+static void
+mac_test_destroy_ipc_sema_label(struct label *label)
+{
+
+	if (SLOT(label) == SYSVIPCSEMMAGIC || SLOT(label) == 0) {
+		atomic_add_int(&destroy_count_ipc_sema, 1);
+		SLOT(label) = EXMAGIC;
+	} else if (SLOT(label) == EXMAGIC) {
+		Debugger("mac_test_destroy_ipc_sema_label: dup destroy");
+	} else {
+		Debugger("mac_test_destroy_ipc_sema_label: corrupted label");
+	}
+}
+
+static void
+mac_test_destroy_ipc_shm_label(struct label *label)
+{
+
+	if (SLOT(label) == SYSVIPCSHMMAGIC || SLOT(label) == 0) {
+		atomic_add_int(&destroy_count_ipc_shm, 1);
+		SLOT(label) = EXMAGIC;
+	} else if (SLOT(label) == EXMAGIC) {
+		Debugger("mac_test_destroy_ipc_shm_label: dup destroy");
+	} else {
+		Debugger("mac_test_destroy_ipc_shm_label: corrupted label");
+	}
+}
+
+static void
 mac_test_destroy_ipq_label(struct label *label)
 {
 
@@ -822,6 +946,40 @@
 }
 
 static void
+mac_test_create_ipc_msgmsg(struct ucred *cred, struct msg *msgptr,
+								    struct label *msglabel)
+{
+
+	ASSERT_SYSVIPCMSG_LABEL(msglabel);
+}   
+
+static void 
+mac_test_create_ipc_msgqueue(struct ucred *cred, struct msqid_kernel *msqkptr,
+								    struct label *msqlabel)
+{
+
+	ASSERT_SYSVIPCMSQ_LABEL(msqlabel);
+}
+
+static void
+mac_test_create_ipc_sema(struct ucred *cred, struct semid_kernel *semakptr,
+								    struct label *semalabel)
+{
+
+	ASSERT_SYSVIPCSEM_LABEL(semalabel);
+}
+
+static void
+mac_test_create_ipc_shm(struct ucred *cred, struct shmid_kernel *shmsegptr,
+								    struct label *shmlabel)
+{
+
+	ASSERT_SYSVIPCSHM_LABEL(shmlabel);
+}
+
+
+
+static void
 mac_test_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
     struct ipq *ipq, struct label *ipqlabel)
 {
@@ -1023,6 +1181,37 @@
 }
 
 /*
+ * Label cleanup/flush operations
+ */
+static void 
+mac_test_cleanup_ipc_msgmsg(struct label *msglabel)
+{
+
+	ASSERT_SYSVIPCMSG_LABEL(msglabel);
+}
+
+static void 
+mac_test_cleanup_ipc_msgqueue(struct label *msqlabel)
+{
+
+	ASSERT_SYSVIPCMSQ_LABEL(msqlabel);
+}
+
+static void 
+mac_test_cleanup_ipc_sema(struct label *semalabel)
+{
+
+	ASSERT_SYSVIPCSEM_LABEL(semalabel);
+}
+
+static void 
+mac_test_cleanup_ipc_shm(struct label *shmlabel)
+{
+
+	ASSERT_SYSVIPCSHM_LABEL(shmlabel);
+}
+
+/*
  * Access control checks.
  */
 static int
@@ -1079,6 +1268,143 @@
 }
 
 static int
+mac_test_check_ipc_msgmsq(struct ucred *cred, struct msg *msgptr, 
+								                        struct msqid_kernel *msqkptr)
+{
+	ASSERT_SYSVIPCMSQ_LABEL(&msqkptr->label);
+	ASSERT_SYSVIPCMSG_LABEL(&msgptr->label);
+	ASSERT_CRED_LABEL(&cred->cr_label);
+  return (0);
+}
+    
+static int
+mac_test_check_ipc_msgrcv(struct ucred *cred, struct msg *msgptr)
+{   
+
+	ASSERT_SYSVIPCMSG_LABEL(&msgptr->label);
+	ASSERT_CRED_LABEL(&cred->cr_label);
+  return (0);
+}
+
+
+static int
+mac_test_check_ipc_msgrmid(struct ucred *cred, struct msg *msgptr)
+{
+
+	ASSERT_SYSVIPCMSG_LABEL(&msgptr->label);
+	ASSERT_CRED_LABEL(&cred->cr_label);
+  return (0);
+}
+
+static int
+mac_test_check_ipc_msqget(struct ucred *cred, struct msqid_kernel *msqkptr)
+{
+
+	ASSERT_SYSVIPCMSQ_LABEL(&msqkptr->label);
+	ASSERT_CRED_LABEL(&cred->cr_label);
+  return (0);
+}
+
+static int
+mac_test_check_ipc_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr)
+{
+
+	ASSERT_SYSVIPCMSQ_LABEL(&msqkptr->label);
+	ASSERT_CRED_LABEL(&cred->cr_label);
+  return (0);
+}
+
+static int
+mac_test_check_ipc_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr)
+{
+
+	ASSERT_SYSVIPCMSQ_LABEL(&msqkptr->label);
+	ASSERT_CRED_LABEL(&cred->cr_label);
+  return (0);
+}
+
+
+static int
+mac_test_check_ipc_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
+								                    int cmd)
+{
+
+	ASSERT_SYSVIPCMSQ_LABEL(&msqkptr->label);
+	ASSERT_CRED_LABEL(&cred->cr_label);
+	return (0);
+}
+
+static int
+mac_test_check_ipc_semctl(struct ucred *cred, struct semid_kernel *semakptr,
+								                    int cmd)
+{
+
+	ASSERT_CRED_LABEL(&cred->cr_label);
+	ASSERT_SYSVIPCSEM_LABEL(&semakptr->label);
+  return (0);
+}
+
+
+static int
+mac_test_check_ipc_semget(struct ucred *cred, struct semid_kernel *semakptr)
+{
+
+	ASSERT_CRED_LABEL(&cred->cr_label);
+	ASSERT_SYSVIPCSEM_LABEL(&semakptr->label);
+	return (0);
+}
+
+
+static int
+mac_test_check_ipc_semop(struct ucred *cred, struct semid_kernel *semakptr,
+								                        size_t accesstype)
+{
+ 
+	ASSERT_CRED_LABEL(&cred->cr_label);
+	ASSERT_SYSVIPCSEM_LABEL(&semakptr->label);
+	return (0);
+}
+
+
+static int
+mac_test_check_ipc_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr,
+								                        int shmflg)
+{
+
+	ASSERT_CRED_LABEL(&cred->cr_label);
+	ASSERT_SYSVIPCSHM_LABEL(&shmsegptr->label);
+  return (0);
+}
+
+static int
+mac_test_check_ipc_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr,
+								                        int cmd)
+{
+	ASSERT_CRED_LABEL(&cred->cr_label);
+	ASSERT_SYSVIPCSHM_LABEL(&shmsegptr->label);
+  return (0);
+}
+
+static int
+mac_test_check_ipc_shmdt(struct ucred *cred, struct shmid_kernel *shmsegptr)
+{
+
+	ASSERT_CRED_LABEL(&cred->cr_label);
+	ASSERT_SYSVIPCSHM_LABEL(&shmsegptr->label);
+	return (0);
+}
+
+static int
+mac_test_check_ipc_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr,
+								                         int shmflg)
+{
+
+	ASSERT_CRED_LABEL(&cred->cr_label);
+	ASSERT_SYSVIPCSHM_LABEL(&shmsegptr->label);
+	return (0);
+}
+
+static int
 mac_test_check_kenv_dump(struct ucred *cred)
 {
 
@@ -1752,6 +2078,10 @@
 	.mpo_init_cred_label = mac_test_init_cred_label,
 	.mpo_init_devfsdirent_label = mac_test_init_devfsdirent_label,
 	.mpo_init_ifnet_label = mac_test_init_ifnet_label,
+	.mpo_init_ipc_msgmsg_label = mac_test_init_ipc_msgmsg_label,
+  .mpo_init_ipc_msgqueue_label = mac_test_init_ipc_msgqueue_label,
+  .mpo_init_ipc_sema_label = mac_test_init_ipc_sema_label,
+  .mpo_init_ipc_shm_label = mac_test_init_ipc_shm_label,
 	.mpo_init_ipq_label = mac_test_init_ipq_label,
 	.mpo_init_mbuf_label = mac_test_init_mbuf_label,
 	.mpo_init_mount_label = mac_test_init_mount_label,
@@ -1765,6 +2095,10 @@
 	.mpo_destroy_cred_label = mac_test_destroy_cred_label,
 	.mpo_destroy_devfsdirent_label = mac_test_destroy_devfsdirent_label,
 	.mpo_destroy_ifnet_label = mac_test_destroy_ifnet_label,
+	.mpo_destroy_ipc_msgmsg_label = mac_test_destroy_ipc_msgmsg_label,
+  .mpo_destroy_ipc_msgqueue_label = mac_test_destroy_ipc_msgqueue_label,
+  .mpo_destroy_ipc_sema_label = mac_test_destroy_ipc_sema_label,
+  .mpo_destroy_ipc_shm_label = mac_test_destroy_ipc_shm_label,
 	.mpo_destroy_ipq_label = mac_test_destroy_ipq_label,
 	.mpo_destroy_mbuf_label = mac_test_destroy_mbuf_label,
 	.mpo_destroy_mount_label = mac_test_destroy_mount_label,
@@ -1807,6 +2141,10 @@
 	.mpo_set_socket_peer_from_socket = mac_test_set_socket_peer_from_socket,
 	.mpo_create_bpfdesc = mac_test_create_bpfdesc,
 	.mpo_create_ifnet = mac_test_create_ifnet,
+	.mpo_create_ipc_msgmsg = mac_test_create_ipc_msgmsg,
+  .mpo_create_ipc_msgqueue = mac_test_create_ipc_msgqueue,
+  .mpo_create_ipc_sema = mac_test_create_ipc_sema,
+  .mpo_create_ipc_shm = mac_test_create_ipc_shm,
 	.mpo_create_datagram_from_ipq = mac_test_create_datagram_from_ipq,
 	.mpo_create_fragment = mac_test_create_fragment,
 	.mpo_create_ipq = mac_test_create_ipq,
@@ -1828,11 +2166,29 @@
 	.mpo_create_proc1 = mac_test_create_proc1,
 	.mpo_relabel_cred = mac_test_relabel_cred,
 	.mpo_thread_userret = mac_test_thread_userret,
+	.mpo_cleanup_ipc_msgmsg = mac_test_cleanup_ipc_msgmsg,
+	.mpo_cleanup_ipc_msgqueue = mac_test_cleanup_ipc_msgqueue,
+	.mpo_cleanup_ipc_sema = mac_test_cleanup_ipc_sema,
+	.mpo_cleanup_ipc_shm = mac_test_cleanup_ipc_shm,
 	.mpo_check_bpfdesc_receive = mac_test_check_bpfdesc_receive,
 	.mpo_check_cred_relabel = mac_test_check_cred_relabel,
 	.mpo_check_cred_visible = mac_test_check_cred_visible,
 	.mpo_check_ifnet_relabel = mac_test_check_ifnet_relabel,
 	.mpo_check_ifnet_transmit = mac_test_check_ifnet_transmit,
+	.mpo_check_ipc_msgmsq = mac_test_check_ipc_msgmsq,
+  .mpo_check_ipc_msgrcv = mac_test_check_ipc_msgrcv,
+  .mpo_check_ipc_msgrmid = mac_test_check_ipc_msgrmid,
+  .mpo_check_ipc_msqget = mac_test_check_ipc_msqget,
+  .mpo_check_ipc_msqsnd = mac_test_check_ipc_msqsnd,
+  .mpo_check_ipc_msqrcv = mac_test_check_ipc_msqrcv,
+  .mpo_check_ipc_msqctl = mac_test_check_ipc_msqctl,
+  .mpo_check_ipc_semctl = mac_test_check_ipc_semctl,
+  .mpo_check_ipc_semget = mac_test_check_ipc_semget,
+  .mpo_check_ipc_semop = mac_test_check_ipc_semop,
+  .mpo_check_ipc_shmat = mac_test_check_ipc_shmat,
+  .mpo_check_ipc_shmctl = mac_test_check_ipc_shmctl,
+  .mpo_check_ipc_shmdt = mac_test_check_ipc_shmdt,
+  .mpo_check_ipc_shmget = mac_test_check_ipc_shmget,
 	.mpo_check_kenv_dump = mac_test_check_kenv_dump,
 	.mpo_check_kenv_get = mac_test_check_kenv_get,
 	.mpo_check_kenv_set = mac_test_check_kenv_set,
--- //depot/projects/trustedbsd/mac/sys/sys/mac.h	2003/06/07 22:05:57
+++ //depot/user/hdandeka/rishi_SystemVIPC/sys/sys/mac.h	2003/06/13 16:12:32
@@ -39,6 +39,7 @@
  * The POSIX.1e implementation page may be reached at:
  * http://www.trustedbsd.org/
  */
+
 #ifndef _SYS_MAC_H
 #define	_SYS_MAC_H
 
@@ -122,6 +123,10 @@
 struct uio;
 struct vattr;
 struct vnode;
+struct msqid_kernel;
+struct msg;
+struct semid_kernel;
+struct shmid_kernel;
 
 #include <sys/acl.h>			/* XXX acl_type_t */
 
@@ -134,6 +139,10 @@
 void	mac_init_cred(struct ucred *);
 void	mac_init_devfsdirent(struct devfs_dirent *);
 void	mac_init_ifnet(struct ifnet *);
+void	mac_init_ipc_msgmsg(struct msg *);
+void	mac_init_ipc_msgqueue(struct msqid_kernel*);
+void	mac_init_ipc_sema(struct semid_kernel*);
+void	mac_init_ipc_shm(struct shmid_kernel*);
 int	mac_init_ipq(struct ipq *, int flag);
 int	mac_init_socket(struct socket *, int flag);
 void	mac_init_pipe(struct pipe *);
@@ -149,6 +158,10 @@
 void	mac_destroy_cred(struct ucred *);
 void	mac_destroy_devfsdirent(struct devfs_dirent *);
 void	mac_destroy_ifnet(struct ifnet *);
+void 	mac_destroy_ipc_msgmsg(struct msg *);
+void	mac_destroy_ipc_msgqueue(struct msqid_kernel *);
+void	mac_destroy_ipc_sema(struct semid_kernel *);
+void	mac_destroy_ipc_shm(struct shmid_kernel *);
 void	mac_destroy_ipq(struct ipq *);
 void	mac_destroy_socket(struct socket *);
 void	mac_destroy_pipe(struct pipe *);
@@ -196,6 +209,15 @@
 void	mac_create_pipe(struct ucred *cred, struct pipe *pipe);
 
 /*
+ * Labeling event operations: System V IPC primitives
+ */
+void mac_create_ipc_msgmsg(struct ucred *cred, struct msg *msgptr);
+void mac_create_ipc_msgqueue(struct ucred *cred, struct msqid_kernel *msqkptr);
+void mac_create_ipc_sema(struct ucred *cred, struct semid_kernel *semakptr);
+void mac_create_ipc_shm(struct ucred *cred, struct shmid_kernel *shmsegptr);
+
+
+/*
  * Labeling event operations: network objects.
  */
 void	mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d);
@@ -232,10 +254,44 @@
 void	mac_create_proc1(struct ucred *cred);
 void	mac_thread_userret(struct thread *td);
 
+/*
+ * Label cleanup operation: This is the inverse complement for the mac_create
+ * and associate type of hooks. This hook lets the policy module(s) perform a 
+ * cleanup/flushing operation on the label associated with the objects,
+ * without freeing up the space allocated. This hook is useful in cases where it
+ * is desirable to remove any labeling reference when recycling any object to a
+ * pool. This hook does not replace the mac_destroy hooks.
+ */
+void mac_cleanup_ipc_msgmsg(struct msg *msgptr);
+void mac_cleanup_ipc_msgqueue(struct msqid_kernel *msqkptr);
+void mac_cleanup_ipc_sema(struct semid_kernel *semakptr);
+void mac_cleanup_ipc_shm(struct shmid_kernel *shmsegptr);
+
 /* Access control checks. */
 int	mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet);
 int	mac_check_cred_visible(struct ucred *u1, struct ucred *u2);
 int	mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *m);
+int mac_check_ipc_msgmsq(struct ucred *cred, struct msg *msgptr, 
+				struct msqid_kernel *msqkptr);
+int mac_check_ipc_msgrcv(struct ucred *cred, struct msg *msgptr);
+int mac_check_ipc_msgrmid(struct ucred *cred, struct msg *msgptr);
+int mac_check_ipc_msqget(struct ucred *cred, struct msqid_kernel *msqkptr);
+int mac_check_ipc_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr);
+int mac_check_ipc_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr);
+int mac_check_ipc_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr,
+    int cmd);
+int mac_check_ipc_semctl(struct ucred *cred, struct semid_kernel *semakptr,
+		int cmd);
+int mac_check_ipc_semget(struct ucred *cred, struct semid_kernel *semakptr);
+int mac_check_ipc_semop(struct ucred *cred, struct semid_kernel *semakptr, 
+				size_t accesstype);
+int mac_check_ipc_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, 
+				int shmflg);
+int mac_check_ipc_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, 
+				int cmd);
+int	mac_check_ipc_shmdt(struct ucred *cred, struct shmid_kernel *shmsegptr);
+int mac_check_ipc_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, 
+				int shmflg);
 int	mac_check_kenv_dump(struct ucred *cred);
 int	mac_check_kenv_get(struct ucred *cred, char *name);
 int	mac_check_kenv_set(struct ucred *cred, char *name, char *value);
--- //depot/projects/trustedbsd/mac/sys/sys/mac_policy.h	2003/06/07 22:05:57
+++ //depot/user/hdandeka/rishi_SystemVIPC/sys/sys/mac_policy.h	2003/06/13 16:12:32
@@ -74,6 +74,10 @@
 	void	(*mpo_init_cred_label)(struct label *label);
 	void	(*mpo_init_devfsdirent_label)(struct label *label);
 	void	(*mpo_init_ifnet_label)(struct label *label);
+	void	(*mpo_init_ipc_msgmsg_label)(struct label *label);
+	void	(*mpo_init_ipc_msgqueue_label)(struct label* label);
+	void  (*mpo_init_ipc_sema_label)(struct label* label);
+	void  (*mpo_init_ipc_shm_label)(struct label* label);
 	int	(*mpo_init_ipq_label)(struct label *label, int flag);
 	int	(*mpo_init_mbuf_label)(struct label *label, int flag);
 	void	(*mpo_init_mount_label)(struct label *label);
@@ -87,6 +91,10 @@
 	void	(*mpo_destroy_cred_label)(struct label *label);
 	void	(*mpo_destroy_devfsdirent_label)(struct label *label);
 	void	(*mpo_destroy_ifnet_label)(struct label *label);
+	void (*mpo_destroy_ipc_msgmsg_label)(struct label* label);
+	void (*mpo_destroy_ipc_msgqueue_label)(struct label* label);
+	void (*mpo_destroy_ipc_sema_label)(struct label* label);
+	void (*mpo_destroy_ipc_shm_label)(struct label* label);
 	void	(*mpo_destroy_ipq_label)(struct label *label);
 	void	(*mpo_destroy_mbuf_label)(struct label *label);
 	void	(*mpo_destroy_mount_label)(struct label *label);
@@ -192,6 +200,18 @@
 	void	(*mpo_create_pipe)(struct ucred *cred, struct pipe *pipe,
 		    struct label *pipelabel);
 
+	/*    
+	 * Labeling event operations: System V IPC primitives
+	 */
+	void (*mpo_create_ipc_msgmsg)(struct ucred *cred, 
+				struct msg *msgptr, struct label *msglabel);
+	void (*mpo_create_ipc_msgqueue)(struct ucred *cred, 
+				struct msqid_kernel *msqkptr, struct label *msqlabel);
+	void (*mpo_create_ipc_sema)(struct ucred *cred, 
+				struct semid_kernel *semakptr, struct label *semalabel); 
+	void (*mpo_create_ipc_shm)(struct ucred *cred, 
+				struct shmid_kernel *shmsegptr, struct label *shmlabel);
+
 	/*
 	 * Labeling event operations: network objects.
 	 */
@@ -261,6 +281,19 @@
 		    struct label *newlabel);
 	void	(*mpo_thread_userret)(struct thread *thread);
 
+	/* 
+	 * Label cleanup operation: This is the inverse complement for the mac_create
+	 * and associate type of hooks. This hook lets the policy module(s) perform a
+	 * cleanup/flushing operation on the label associated with the objects,
+	 * without freeing up the space allocated. This hook is useful in cases where 
+	 * it is desirable to remove any labeling reference when recycling any object 
+	 * to a pool. This hook does not replace the mac_destroy hooks.
+	 */
+	void (*mpo_cleanup_ipc_msgmsg)(struct label *msglabel);
+	void (*mpo_cleanup_ipc_msgqueue)(struct label *msqlabel);
+	void (*mpo_cleanup_ipc_sema)(struct label *semalabel);
+	void (*mpo_cleanup_ipc_shm)(struct label *shmlabel);
+
 	/*
 	 * Access control checks.
 	 */
@@ -276,6 +309,29 @@
 	int	(*mpo_check_ifnet_transmit)(struct ifnet *ifnet,
 		    struct label *ifnetlabel, struct mbuf *m,
 		    struct label *mbuflabel);
+	int (*mpo_check_ipc_msgmsq)(struct ucred *cred, struct msg *msgptr, 
+				struct msqid_kernel *msqkptr);
+	int (*mpo_check_ipc_msgrcv)(struct ucred *cred, struct msg *msgptr);
+  int (*mpo_check_ipc_msgrmid)(struct ucred *cred, struct msg *msgptr);
+	int (*mpo_check_ipc_msqget)(struct ucred *cred, struct msqid_kernel *msqkptr);
+	int (*mpo_check_ipc_msqsnd)(struct ucred *cred, struct msqid_kernel *msqkptr);
+	int (*mpo_check_ipc_msqrcv)(struct ucred *cred, struct msqid_kernel *msqkptr);
+	int (*mpo_check_ipc_msqctl)(struct ucred *cred, struct msqid_kernel *msqkptr,
+    int cmd);
+	int (*mpo_check_ipc_semctl)(struct ucred *cred, struct semid_kernel *semakptr,
+    int cmd);
+	int (*mpo_check_ipc_semget)(struct ucred *cred, 
+				struct semid_kernel *semakptr);
+	int (*mpo_check_ipc_semop)(struct ucred *cred, struct semid_kernel *semakptr, 
+				size_t accesstype);
+	int (*mpo_check_ipc_shmat)(struct ucred *cred, 
+				struct shmid_kernel *shmsegptr, int shmflg);
+	int (*mpo_check_ipc_shmctl)(struct ucred *cred, 
+				struct shmid_kernel *shmsegptr, int cmd);
+	int	(*mpo_check_ipc_shmdt)(struct ucred *cred, 
+				struct shmid_kernel *shmsegptr);
+	int (*mpo_check_ipc_shmget)(struct ucred *cred, 
+				struct shmid_kernel *shmsegptr, int shmflg);
 	int	(*mpo_check_kenv_dump)(struct ucred *cred);
 	int	(*mpo_check_kenv_get)(struct ucred *cred, char *name);
 	int	(*mpo_check_kenv_set)(struct ucred *cred, char *name,
--- //depot/projects/trustedbsd/mac/sys/sys/msg.h	2003/02/21 10:04:40
+++ //depot/user/hdandeka/rishi_SystemVIPC/sys/sys/msg.h	2003/05/29 11:51:12
@@ -26,6 +26,7 @@
 #include <sys/cdefs.h>
 #include <sys/_types.h>
 #include <sys/ipc.h>
+#include <sys/_label.h>
 
 /*
  * The MSG_NOERROR identifier value, the msqid_ds struct and the msg struct
@@ -120,6 +121,13 @@
 };
 extern struct msginfo	msginfo;
 
+struct msqid_kernel
+{
+        struct msqid_ds         u;
+        /* the following are private */
+	struct label label;         /* MAC label */
+};
+
 #else /* !_KERNEL */
 
 __BEGIN_DECLS
--- //depot/projects/trustedbsd/mac/sys/sys/sem.h	2003/02/21 10:04:40
+++ //depot/user/hdandeka/rishi_SystemVIPC/sys/sys/sem.h	2003/05/30 18:42:59
@@ -11,6 +11,7 @@
 #define _SYS_SEM_H_
 
 #include <sys/ipc.h>
+#include <sys/_label.h>
 
 struct sem;
 
@@ -84,6 +85,14 @@
 };
 extern struct seminfo	seminfo;
 
+/* Kernel wrapper for the user-level structure */
+struct semid_kernel
+{
+				  struct semid_ds   u;
+					  /* the following are private */
+					struct label label; /* MAC framework label */
+};
+
 /* internal "mode" bits */
 #define	SEM_ALLOC	01000	/* semaphore is allocated */
 #define	SEM_DEST	02000	/* semaphore will be destroyed on last detach */
--- //depot/projects/trustedbsd/mac/sys/sys/shm.h	2003/02/21 10:04:40
+++ //depot/user/hdandeka/rishi_SystemVIPC/sys/sys/shm.h	2003/06/02 19:36:08
@@ -40,6 +40,7 @@
 #define _SYS_SHM_H_
 
 #include <sys/ipc.h>
+#include <sys/_label.h>
 
 #define SHM_RDONLY  010000  /* Attach read-only (else read-write) */
 #define SHM_RND     020000  /* Round attach address to SHMLBA */
@@ -83,8 +84,20 @@
 		shmseg,		/* max shared memory segments per process */
 		shmall;		/* max amount of shared memory (pages) */
 };
+
+/* 
+ * Add a kernel wrapper to the shmid_ds struct so that private info
+ * (like the MAC label) can be added to it, without changing the user
+ * interface.
+ */
+struct shmid_kernel {
+	struct shmid_ds u;
+	/* the following are private */
+	struct label label; /* MAC label */
+};
+
 extern struct shminfo	shminfo;
-extern struct shmid_ds	*shmsegs;
+extern struct shmid_kernel	*shmsegs;
 
 struct shm_info {
 	int used_ids;
@@ -95,6 +108,7 @@
 	unsigned long swap_successes;
 };
 
+
 struct thread;
 struct proc;
 struct vmspace;
