diff -uprN linux-2.6.13-rc6-mm2/include/linux/audit.h linux-2.6.13-rc6-mm2-lspp_audit/include/linux/audit.h
--- linux-2.6.13-rc6-mm2/include/linux/audit.h	2005-08-29 11:32:14.000000000 -0500
+++ linux-2.6.13-rc6-mm2-lspp_audit/include/linux/audit.h	2005-08-29 10:44:08.000000000 -0500
@@ -68,6 +68,7 @@
 #define AUDIT_CONFIG_CHANGE	1305	/* Audit system configuration change */
 #define AUDIT_SOCKADDR		1306	/* sockaddr copied as syscall arg */
 #define AUDIT_CWD		1307	/* Current working directory */
+#define AUDIT_SECURITY_CONTEXT	1350	/* security context */
 
 #define AUDIT_AVC		1400	/* SE Linux avc denial or grant */
 #define AUDIT_SELINUX_ERR	1401	/* Internal SE Linux Errors */
@@ -238,6 +239,8 @@ extern int audit_sockaddr(int len, void 
 extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
 extern void audit_signal_info(int sig, struct task_struct *t);
 extern int audit_filter_user(struct netlink_skb_parms *cb, int type);
+extern int audit_ipc_security_context(struct kern_ipc_perm *ipcp);
+extern int audit_set_macxattr(const char *name);
 #else
 #define audit_alloc(t) ({ 0; })
 #define audit_free(t) do { ; } while (0)
@@ -255,6 +258,8 @@ extern int audit_filter_user(struct netl
 #define audit_avc_path(dentry, mnt) ({ 0; })
 #define audit_signal_info(s,t) do { ; } while (0)
 #define audit_filter_user(cb,t) ({ 1; })
+#define audit_ipc_security_context(p) ({ 0; })
+#define audit_set_macxattr(n) ({ 0; })
 #endif
 
 #ifdef CONFIG_AUDIT
@@ -283,6 +288,7 @@ extern void		    audit_send_reply(int pi
 					     int done, int multi,
 					     void *payload, int size);
 extern void		    audit_log_lost(const char *message);
+extern void		    audit_panic(const char *message);
 extern struct semaphore audit_netlink_sem;
 #else
 #define audit_log(c,g,t,f,...) do { ; } while (0)
@@ -293,6 +299,7 @@ extern struct semaphore audit_netlink_se
 #define audit_log_hex(a,b,l) do { ; } while (0)
 #define audit_log_untrustedstring(a,s) do { ; } while (0)
 #define audit_log_d_path(b,p,d,v) do { ; } while (0)
+#define audit_panic(m) do { ; } while (0)
 #endif
 #endif
 #endif
diff -uprN linux-2.6.13-rc6-mm2/include/linux/security.h linux-2.6.13-rc6-mm2-lspp_audit/include/linux/security.h
--- linux-2.6.13-rc6-mm2/include/linux/security.h	2005-08-29 11:32:16.000000000 -0500
+++ linux-2.6.13-rc6-mm2-lspp_audit/include/linux/security.h	2005-08-29 10:37:50.000000000 -0500
@@ -792,6 +792,11 @@ struct swap_info_struct;
  *	@ipcp contains the kernel IPC permission structure
  *	@flag contains the desired (requested) permission set
  *	Return 0 if permission is granted.
+ * @ipc_getsecurity:
+ *      Copy the security label associated with the ipc object into
+ *      @buffer.  @buffer may be NULL to request the size of the buffer 
+ *      required.  @size indicates the size of @buffer in bytes. Return 
+ *      number of bytes used/required on success.
  *
  * Security hooks for individual messages held in System V IPC message queues
  * @msg_msg_alloc_security:
@@ -1140,6 +1145,7 @@ struct security_operations {
 	void (*task_to_inode)(struct task_struct *p, struct inode *inode);
 
 	int (*ipc_permission) (struct kern_ipc_perm * ipcp, short flag);
+	int (*ipc_getsecurity)(struct kern_ipc_perm *ipcp, void *buffer, size_t size);
 
 	int (*msg_msg_alloc_security) (struct msg_msg * msg);
 	void (*msg_msg_free_security) (struct msg_msg * msg);
@@ -1775,6 +1781,11 @@ static inline int security_ipc_permissio
 	return security_ops->ipc_permission (ipcp, flag);
 }
 
+static inline int security_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
+{
+	return security_ops->ipc_getsecurity(ipcp, buffer, size);
+}
+
 static inline int security_msg_msg_alloc (struct msg_msg * msg)
 {
 	return security_ops->msg_msg_alloc_security (msg);
@@ -2405,6 +2416,11 @@ static inline int security_ipc_permissio
 	return 0;
 }
 
+static inline int security_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
+{
+	return -EOPNOTSUPP;
+}
+
 static inline int security_msg_msg_alloc (struct msg_msg * msg)
 {
 	return 0;
diff -uprN linux-2.6.13-rc6-mm2/ipc/msg.c linux-2.6.13-rc6-mm2-lspp_audit/ipc/msg.c
--- linux-2.6.13-rc6-mm2/ipc/msg.c	2005-08-29 11:32:16.000000000 -0500
+++ linux-2.6.13-rc6-mm2-lspp_audit/ipc/msg.c	2005-08-29 10:37:51.000000000 -0500
@@ -443,6 +443,13 @@ asmlinkage long sys_msgctl (int msqid, i
 	if (msq == NULL)
 		goto out_up;
 
+	ipcp = &msq->q_perm;
+
+	if (cmd == IPC_SET) {
+		if ((err = audit_ipc_security_context(ipcp)))
+			goto out_unlock_up;
+	}
+
 	err = -EIDRM;
 	if (msg_checkid(msq,msqid))
 		goto out_unlock_up;
diff -uprN linux-2.6.13-rc6-mm2/ipc/sem.c linux-2.6.13-rc6-mm2-lspp_audit/ipc/sem.c
--- linux-2.6.13-rc6-mm2/ipc/sem.c	2005-08-29 11:32:16.000000000 -0500
+++ linux-2.6.13-rc6-mm2-lspp_audit/ipc/sem.c	2005-08-29 10:37:51.000000000 -0500
@@ -813,12 +813,18 @@ static int semctl_down(int semid, int se
 	if(sma==NULL)
 		return -EINVAL;
 
+	ipcp = &sma->sem_perm;
+
+	if(cmd == IPC_SET) {
+		if ((err = audit_ipc_security_context(ipcp)))
+			goto out_unlock;
+	}
+	
 	if (sem_checkid(sma,semid)) {
 		err=-EIDRM;
 		goto out_unlock;
 	}	
-	ipcp = &sma->sem_perm;
-	
+
 	if (current->euid != ipcp->cuid && 
 	    current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN)) {
 	    	err=-EPERM;
diff -uprN linux-2.6.13-rc6-mm2/ipc/shm.c linux-2.6.13-rc6-mm2-lspp_audit/ipc/shm.c
--- linux-2.6.13-rc6-mm2/ipc/shm.c	2005-08-29 11:32:16.000000000 -0500
+++ linux-2.6.13-rc6-mm2-lspp_audit/ipc/shm.c	2005-08-29 10:37:51.000000000 -0500
@@ -611,6 +611,9 @@ asmlinkage long sys_shmctl (int shmid, i
 		err=-EINVAL;
 		if(shp==NULL)
 			goto out_up;
+		err = audit_ipc_security_context(&(shp->shm_perm));
+		if(err)
+			goto out_unlock_up;
 		err = shm_checkid(shp,shmid);
 		if(err)
 			goto out_unlock_up;
diff -uprN linux-2.6.13-rc6-mm2/ipc/util.c linux-2.6.13-rc6-mm2-lspp_audit/ipc/util.c
--- linux-2.6.13-rc6-mm2/ipc/util.c	2005-08-29 11:32:16.000000000 -0500
+++ linux-2.6.13-rc6-mm2-lspp_audit/ipc/util.c	2005-08-29 10:39:17.000000000 -0500
@@ -26,6 +26,7 @@
 #include <linux/workqueue.h>
 #include <linux/seq_file.h>
 #include <linux/proc_fs.h>
+#include <linux/audit.h>
 
 #include <asm/unistd.h>
 
@@ -466,6 +467,8 @@ int ipcperms (struct kern_ipc_perm *ipcp
 {	/* flag will most probably be 0 or S_...UGO from <linux/stat.h> */
 	int requested_mode, granted_mode;
 
+	audit_ipc_security_context(ipcp);
+
 	requested_mode = (flag >> 6) | (flag >> 3) | flag;
 	granted_mode = ipcp->mode;
 	if (current->euid == ipcp->cuid || current->euid == ipcp->uid)
diff -uprN linux-2.6.13-rc6-mm2/kernel/audit.c linux-2.6.13-rc6-mm2-lspp_audit/kernel/audit.c
--- linux-2.6.13-rc6-mm2/kernel/audit.c	2005-08-29 11:32:16.000000000 -0500
+++ linux-2.6.13-rc6-mm2-lspp_audit/kernel/audit.c	2005-08-29 11:29:16.000000000 -0500
@@ -142,7 +142,7 @@ static void audit_set_pid(struct audit_b
 	nlh->nlmsg_pid = pid;
 }
 
-static void audit_panic(const char *message)
+void audit_panic(const char *message)
 {
 	switch (audit_failure)
 	{
@@ -893,3 +893,4 @@ void audit_log(struct audit_context *ctx
 		audit_log_end(ab);
 	}
 }
+
diff -uprN linux-2.6.13-rc6-mm2/kernel/auditsc.c linux-2.6.13-rc6-mm2-lspp_audit/kernel/auditsc.c
--- linux-2.6.13-rc6-mm2/kernel/auditsc.c	2005-08-29 11:32:16.000000000 -0500
+++ linux-2.6.13-rc6-mm2-lspp_audit/kernel/auditsc.c	2005-08-29 11:09:43.000000000 -0500
@@ -43,6 +43,7 @@
 #include <linux/netlink.h>
 #include <linux/compiler.h>
 #include <asm/unistd.h>
+#include <linux/security.h>
 
 /* 0 = no checking
    1 = put_count checking
@@ -99,6 +100,7 @@ struct audit_names {
 	gid_t		gid;
 	dev_t		rdev;
 	unsigned	flags;
+	char		*security_context;
 };
 
 struct audit_aux_data {
@@ -108,6 +110,12 @@ struct audit_aux_data {
 
 #define AUDIT_AUX_IPCPERM	0
 
+struct audit_aux_data_security_context {
+	struct			audit_aux_data d;
+	char			*security_context;
+	size_t			security_context_len;
+};
+
 struct audit_aux_data_ipcctl {
 	struct audit_aux_data	d;
 	struct ipc_perm		p;
@@ -167,6 +175,8 @@ struct audit_context {
 #endif
 };
 
+static const char *audit_macxattr;
+
 				/* Public API */
 /* There are three lists of rules -- one to search at task creation
  * time, one to search at syscall entry time, and another to search at
@@ -670,9 +680,11 @@ static inline void audit_free_names(stru
 	context->ino_count  = 0;
 #endif
 
-	for (i = 0; i < context->name_count; i++)
+	for (i = 0; i < context->name_count; i++) {
 		if (context->names[i].name)
 			__putname(context->names[i].name);
+		kfree(context->names[i].security_context);
+	}
 	context->name_count = 0;
 	if (context->pwd)
 		dput(context->pwd);
@@ -771,6 +783,37 @@ static inline void audit_free_context(st
 		printk(KERN_ERR "audit: freed %d contexts\n", count);
 }
 
+static void audit_log_task_security_context(struct audit_buffer *ab)
+{
+	char *security_context;
+	ssize_t len = 0;
+
+	len = security_getprocattr(current, "current", NULL, 0);
+	if (len < 0) {
+		if (len != -EINVAL) 
+			audit_panic("security_getprocattr error in audit_log_task_security_context");
+		return;
+	}
+
+	security_context = kmalloc(len, GFP_KERNEL);
+	if (!security_context) {
+		audit_panic("memory allocation error in audit_log_task_security_context");
+		return;
+	}
+
+	len = security_getprocattr(current, "current", security_context, len);
+	if (len < 0 ) {
+		audit_panic("security_getprocattr error in audit_log_task_security_context");
+		goto out;
+	}
+	
+	audit_log_format(ab, " scontext=%s", security_context);
+	
+out:
+	kfree(security_context);
+	return;
+}
+
 static void audit_log_task_info(struct audit_buffer *ab)
 {
 	char name[sizeof(current->comm)];
@@ -797,6 +840,7 @@ static void audit_log_task_info(struct a
 		vma = vma->vm_next;
 	}
 	up_read(&mm->mmap_sem);
+	audit_log_task_security_context(ab);
 }
 
 static void audit_log_exit(struct audit_context *context, unsigned int gfp_mask)
@@ -868,6 +912,11 @@ static void audit_log_exit(struct audit_
 			struct audit_aux_data_path *axi = (void *)aux;
 			audit_log_d_path(ab, "path=", axi->dentry, axi->mnt);
 			break; }
+		case AUDIT_SECURITY_CONTEXT: {
+			struct audit_aux_data_security_context *axi = (void *)aux;
+			audit_log_format(ab, " ocontext=%s", axi->security_context);
+			kfree(axi->security_context);
+			break; }
 
 		}
 		audit_log_end(ab);
@@ -903,6 +952,10 @@ static void audit_log_exit(struct audit_
 					 context->names[i].gid,
 					 MAJOR(context->names[i].rdev),
 					 MINOR(context->names[i].rdev));
+		if (context->names[i].security_context) {
+			audit_log_format(ab, " ocontext=%s",
+				context->names[i].security_context);
+		}
 		audit_log_end(ab);
 	}
 }
@@ -1118,6 +1171,37 @@ void audit_putname(const char *name)
 #endif
 }
 
+void audit_inode_security_context(int idx, const struct inode *inode)
+{
+	struct audit_context *context = current->audit_context;
+	int len = 0;
+
+	if (!audit_macxattr)
+		return;
+
+	len = security_inode_getsecurity((struct inode *)inode, audit_macxattr, NULL, 0);
+	if (len < 0) {
+		if (len != -EOPNOTSUPP) 
+			audit_panic("security_inode_getsecurity error in audit_inode_security_context");
+		return;
+	}
+
+	context->names[idx].security_context = kmalloc(len, GFP_KERNEL);
+	if (!(context->names[idx].security_context)) {
+		audit_panic("memory allocation error in audit_inode_security_context");
+		return;
+	}
+
+	len = security_inode_getsecurity((struct inode *)inode, audit_macxattr,
+					context->names[idx].security_context, len);
+	if (len < 0) {
+		kfree(context->names[idx].security_context);
+		audit_panic("security_inode_getsecurity error in audit_inode_security_context");
+	}
+
+	return;
+}
+
 /* Store the inode and device from a lookup.  Called from
  * fs/namei.c:path_lookup(). */
 void audit_inode(const char *name, const struct inode *inode, unsigned flags)
@@ -1153,6 +1237,8 @@ void audit_inode(const char *name, const
 	context->names[idx].uid   = inode->i_uid;
 	context->names[idx].gid   = inode->i_gid;
 	context->names[idx].rdev  = inode->i_rdev;
+
+	audit_inode_security_context(idx, inode);
 }
 
 void auditsc_get_stamp(struct audit_context *ctx,
@@ -1292,3 +1378,58 @@ void audit_signal_info(int sig, struct t
 	}
 }
 
+int audit_ipc_security_context(struct kern_ipc_perm *ipcp)
+{
+	struct audit_aux_data_security_context *ax;
+	struct audit_context *context = current->audit_context;
+	int len = 0;
+
+	if (likely(!context))
+		return 0;
+
+	ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
+	if (!ax) {
+		audit_panic("memory allocation error in audit_ipc_security_context");
+		return -ENOMEM;
+	}
+
+	len = security_ipc_getsecurity(ipcp, NULL, 0);
+	if (len < 0) {
+		if (len != -EOPNOTSUPP)
+			audit_panic("security_ipc_getsecurity error in audit_ipc_security_context");
+			return len;
+	}
+
+	ax->security_context = kmalloc(len, GFP_ATOMIC);
+	if (!ax->security_context) {
+		audit_panic("memory allocation error in audit_ipc_security_context");
+		kfree(ax);
+		return -ENOMEM;
+	}
+
+	len = security_ipc_getsecurity(ipcp, ax->security_context, len);
+	if (len < 0) {
+		audit_panic("security_ipc_getsecurity error in audit_ipc_security_context");
+		kfree(ax->security_context);
+		kfree(ax);
+		return len;
+	}
+
+	ax->security_context_len = len;
+
+	ax->d.type = AUDIT_SECURITY_CONTEXT;
+	ax->d.next = context->aux;
+	context->aux = (void *)ax;
+	return 0;
+}
+
+/* Set the security XATTR name. This is needed for audit functions
+ * to obtain the security context of file system objects. */
+int audit_set_macxattr(const char *name)
+{
+	if (audit_macxattr)
+		return -EINVAL;
+
+	audit_macxattr = kstrdup(name, GFP_KERNEL);
+	return 0;
+}
diff -uprN linux-2.6.13-rc6-mm2/security/dummy.c linux-2.6.13-rc6-mm2-lspp_audit/security/dummy.c
--- linux-2.6.13-rc6-mm2/security/dummy.c	2005-08-29 11:32:17.000000000 -0500
+++ linux-2.6.13-rc6-mm2-lspp_audit/security/dummy.c	2005-08-29 10:37:51.000000000 -0500
@@ -557,6 +557,11 @@ static int dummy_ipc_permission (struct 
 	return 0;
 }
 
+static int dummy_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
+{
+	return -EOPNOTSUPP;
+}
+
 static int dummy_msg_msg_alloc_security (struct msg_msg *msg)
 {
 	return 0;
@@ -907,6 +912,7 @@ void security_fixup_ops (struct security
 	set_to_dummy_if_null(ops, task_reparent_to_init);
  	set_to_dummy_if_null(ops, task_to_inode);
 	set_to_dummy_if_null(ops, ipc_permission);
+	set_to_dummy_if_null(ops, ipc_getsecurity);
 	set_to_dummy_if_null(ops, msg_msg_alloc_security);
 	set_to_dummy_if_null(ops, msg_msg_free_security);
 	set_to_dummy_if_null(ops, msg_queue_alloc_security);
diff -uprN linux-2.6.13-rc6-mm2/security/selinux/hooks.c linux-2.6.13-rc6-mm2-lspp_audit/security/selinux/hooks.c
--- linux-2.6.13-rc6-mm2/security/selinux/hooks.c	2005-08-29 11:32:17.000000000 -0500
+++ linux-2.6.13-rc6-mm2-lspp_audit/security/selinux/hooks.c	2005-08-29 10:37:51.000000000 -0500
@@ -116,6 +116,35 @@ static struct security_operations *secon
 static LIST_HEAD(superblock_security_head);
 static DEFINE_SPINLOCK(sb_security_lock);
 
+/* Return security context for a given sid or just the context 
+   length if the buffer is null or length is 0 */
+static int selinux_getsecurity(u32 sid, void *buffer, size_t size)
+{
+	char *context;
+	unsigned len;
+	int rc;
+
+	if (buffer && !size)
+		return -ERANGE;
+
+	rc = security_sid_to_context(sid, &context, &len);
+	if (rc)
+		return rc;
+
+	if (!buffer || !size)
+		goto getsecurity_exit;
+
+	if (size < len) {
+		kfree(context);
+		return -ERANGE;
+	}
+	memcpy(buffer, context, len);
+
+getsecurity_exit:
+	kfree(context);
+	return len;
+}
+
 /* Allocate and free functions for each kind of security blob. */
 
 static int task_alloc_security(struct task_struct *task)
@@ -2234,30 +2263,13 @@ static int selinux_inode_removexattr (st
 static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size)
 {
 	struct inode_security_struct *isec = inode->i_security;
-	char *context;
-	unsigned len;
-	int rc;
 
 	/* Permission check handled by selinux_inode_getxattr hook.*/
 
 	if (strcmp(name, XATTR_SELINUX_SUFFIX))
 		return -EOPNOTSUPP;
 
-	rc = security_sid_to_context(isec->sid, &context, &len);
-	if (rc)
-		return rc;
-
-	if (!buffer || !size) {
-		kfree(context);
-		return len;
-	}
-	if (size < len) {
-		kfree(context);
-		return -ERANGE;
-	}
-	memcpy(buffer, context, len);
-	kfree(context);
-	return len;
+	return(selinux_getsecurity(isec->sid, buffer, size));
 }
 
 static int selinux_inode_setsecurity(struct inode *inode, const char *name,
@@ -3362,6 +3374,13 @@ out:	
 	return err;
 }
 
+static int selinux_socket_getsecurity(struct socket *sock, void *buffer, size_t size)
+{
+	struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
+
+	return(selinux_getsecurity(isec->sid, buffer, size));
+}
+ 
 static int selinux_sk_alloc_security(struct sock *sk, int family, int priority)
 {
 	return sk_alloc_security(sk, family, priority);
@@ -4027,6 +4046,13 @@ static int selinux_ipc_permission(struct
 	return ipc_has_perm(ipcp, av);
 }
 
+static int selinux_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
+{
+	struct ipc_security_struct *isec = ipcp->security;
+
+	return(selinux_getsecurity(isec->sid, buffer, size));
+}
+
 /* module stacking operations */
 static int selinux_register_security (const char *name, struct security_operations *ops)
 {
@@ -4068,8 +4094,7 @@ static int selinux_getprocattr(struct ta
 			       char *name, void *value, size_t size)
 {
 	struct task_security_struct *tsec;
-	u32 sid, len;
-	char *context;
+	u32 sid;
 	int error;
 
 	if (current != p) {
@@ -4078,9 +4103,6 @@ static int selinux_getprocattr(struct ta
 			return error;
 	}
 
-	if (!size)
-		return -ERANGE;
-
 	tsec = p->security;
 
 	if (!strcmp(name, "current"))
@@ -4097,16 +4119,7 @@ static int selinux_getprocattr(struct ta
 	if (!sid)
 		return 0;
 
-	error = security_sid_to_context(sid, &context, &len);
-	if (error)
-		return error;
-	if (len > size) {
-		kfree(context);
-		return -ERANGE;
-	}
-	memcpy(value, context, len);
-	kfree(context);
-	return len;
+	return(selinux_getsecurity(sid, value, size));
 }
 
 static int selinux_setprocattr(struct task_struct *p,
@@ -4301,6 +4314,7 @@ static struct security_operations selinu
 	.task_to_inode =                selinux_task_to_inode,
 
 	.ipc_permission =		selinux_ipc_permission,
+	.ipc_getsecurity =		selinux_ipc_getsecurity,
 
 	.msg_msg_alloc_security =	selinux_msg_msg_alloc_security,
 	.msg_msg_free_security =	selinux_msg_msg_free_security,
@@ -4381,6 +4395,10 @@ static __init int selinux_init(void)
 	if (register_security (&selinux_ops))
 		panic("SELinux: Unable to register with kernel.\n");
 
+	if (audit_set_macxattr(XATTR_SELINUX_SUFFIX)) {
+		printk(KERN_WARNING "SELinux: Unable to register xattr name with audit.\n");	
+	}
+
 	if (selinux_enforcing) {
 		printk(KERN_INFO "SELinux:  Starting in enforcing mode\n");
 	} else {
