<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">Signed-off-by: Andrew Morton &lt;akpm@osdl.org&gt;
---

 arch/i386/kernel/ptrace.c      |   19 +++-----
 arch/ia64/kernel/fsys.S        |    5 +-
 arch/ia64/kernel/ptrace.c      |   21 +++++----
 arch/ia64/kernel/signal.c      |    3 -
 arch/mips/kernel/ptrace.c      |   38 ++++++++++++----
 arch/ppc64/kernel/ptrace.c     |   15 ++++--
 arch/s390/kernel/ptrace.c      |   21 ++++-----
 arch/um/kernel/ptrace.c        |   21 +++++----
 arch/x86_64/kernel/ptrace.c    |   21 ++++++---
 fs/namei.c                     |   20 +++++---
 fs/proc/base.c                 |    2 
 include/asm-um/ptrace-i386.h   |    2 
 include/asm-um/ptrace-x86_64.h |    2 
 include/asm-um/thread_info.h   |    4 +
 include/linux/audit.h          |   64 ++++++++++++++++++++++++----
 include/linux/netlink.h        |    1 
 init/Kconfig                   |    2 
 kernel/audit.c                 |   93 ++++++++++++++++++++++++++---------------
 kernel/auditsc.c               |   47 +++++++++++++-------
 net/netlink/af_netlink.c       |    3 +
 20 files changed, 275 insertions(+), 129 deletions(-)

diff -puN arch/i386/kernel/ptrace.c~git-audit arch/i386/kernel/ptrace.c
--- 25/arch/i386/kernel/ptrace.c~git-audit	2005-05-04 16:42:14.000000000 -0700
+++ 25-akpm/arch/i386/kernel/ptrace.c	2005-05-04 16:42:14.000000000 -0700
@@ -683,24 +683,18 @@ void do_syscall_trace(struct pt_regs *re
 	/* do the secure computing check first */
 	secure_computing(regs-&gt;orig_eax);
 
-	if (unlikely(current-&gt;audit_context)) {
-		if (!entryexit)
-			audit_syscall_entry(current, regs-&gt;orig_eax,
-					    regs-&gt;ebx, regs-&gt;ecx,
-					    regs-&gt;edx, regs-&gt;esi);
-		else
-			audit_syscall_exit(current, regs-&gt;eax);
-	}
+	if (unlikely(current-&gt;audit_context) &amp;&amp; entryexit)
+		audit_syscall_exit(current, AUDITSC_RESULT(regs-&gt;eax), regs-&gt;eax);
 
 	if (!(current-&gt;ptrace &amp; PT_PTRACED))
-		return;
+		goto out;
 
 	/* Fake a debug trap */
 	if (test_thread_flag(TIF_SINGLESTEP))
 		send_sigtrap(current, regs, 0);
 
 	if (!test_thread_flag(TIF_SYSCALL_TRACE))
-		return;
+		goto out;
 
 	/* the 0x80 provides a way for the tracing parent to distinguish
 	   between a syscall stop and SIGTRAP delivery */
@@ -715,4 +709,9 @@ void do_syscall_trace(struct pt_regs *re
 		send_sig(current-&gt;exit_code, current, 1);
 		current-&gt;exit_code = 0;
 	}
+ out:
+	if (unlikely(current-&gt;audit_context) &amp;&amp; !entryexit)
+		audit_syscall_entry(current, AUDIT_ARCH_I386, regs-&gt;orig_eax,
+				    regs-&gt;ebx, regs-&gt;ecx, regs-&gt;edx, regs-&gt;esi);
+
 }
diff -puN arch/ia64/kernel/fsys.S~git-audit arch/ia64/kernel/fsys.S
--- 25/arch/ia64/kernel/fsys.S~git-audit	2005-05-04 16:42:14.000000000 -0700
+++ 25-akpm/arch/ia64/kernel/fsys.S	2005-05-04 16:42:29.000000000 -0700
@@ -633,7 +633,10 @@ GLOBAL_ENTRY(fsys_bubble_down)
 	nop.i 0
 	;;
 	ssm psr.i				// M2   we're on kernel stacks now, reenable irqs
-	tbit.z p8,p0=r3,TIF_SYSCALL_TRACE	// I0
+	and r3=_TIF_SYSCALL_TRACEAUDIT,r3
+	;;
+	cmp.eq p8,p0=r3,r0
+
 (p10)	br.cond.spnt.many ia64_ret_from_syscall	// B    return if bad call-frame or r15 is a NaT
 
 	nop.m 0
diff -puN arch/ia64/kernel/ptrace.c~git-audit arch/ia64/kernel/ptrace.c
--- 25/arch/ia64/kernel/ptrace.c~git-audit	2005-05-04 16:42:14.000000000 -0700
+++ 25-akpm/arch/ia64/kernel/ptrace.c	2005-05-04 16:42:14.000000000 -0700
@@ -1596,20 +1596,25 @@ syscall_trace_enter (long arg0, long arg
 		     long arg4, long arg5, long arg6, long arg7,
 		     struct pt_regs regs)
 {
-	long syscall;
+	if (test_thread_flag(TIF_SYSCALL_TRACE) 
+	    &amp;&amp; (current-&gt;ptrace &amp; PT_PTRACED))
+		syscall_trace();
 
 	if (unlikely(current-&gt;audit_context)) {
-		if (IS_IA32_PROCESS(&amp;regs))
+		long syscall;
+		int arch;
+
+		if (IS_IA32_PROCESS(&amp;regs)) {
 			syscall = regs.r1;
-		else
+			arch = AUDIT_ARCH_I386;
+		} else {
 			syscall = regs.r15;
+			arch = AUDIT_ARCH_IA64;
+		}
 
-		audit_syscall_entry(current, syscall, arg0, arg1, arg2, arg3);
+		audit_syscall_entry(current, arch, syscall, arg0, arg1, arg2, arg3);
 	}
 
-	if (test_thread_flag(TIF_SYSCALL_TRACE)
-	    &amp;&amp; (current-&gt;ptrace &amp; PT_PTRACED))
-		syscall_trace();
 }
 
 /* "asmlinkage" so the input arguments are preserved... */
@@ -1620,7 +1625,7 @@ syscall_trace_leave (long arg0, long arg
 		     struct pt_regs regs)
 {
 	if (unlikely(current-&gt;audit_context))
-		audit_syscall_exit(current, regs.r8);
+		audit_syscall_exit(current, AUDITSC_RESULT(regs.r10), regs.r8);
 
 	if (test_thread_flag(TIF_SYSCALL_TRACE)
 	    &amp;&amp; (current-&gt;ptrace &amp; PT_PTRACED))
diff -puN arch/ia64/kernel/signal.c~git-audit arch/ia64/kernel/signal.c
--- 25/arch/ia64/kernel/signal.c~git-audit	2005-05-04 16:42:14.000000000 -0700
+++ 25-akpm/arch/ia64/kernel/signal.c	2005-05-04 16:42:14.000000000 -0700
@@ -224,7 +224,8 @@ ia64_rt_sigreturn (struct sigscratch *sc
 	 * could be corrupted.
 	 */
 	retval = (long) &amp;ia64_leave_kernel;
-	if (test_thread_flag(TIF_SYSCALL_TRACE))
+	if (test_thread_flag(TIF_SYSCALL_TRACE) 
+	    || test_thread_flag(TIF_SYSCALL_AUDIT))
 		/*
 		 * strace expects to be notified after sigreturn returns even though the
 		 * context to which we return may not be in the middle of a syscall.
diff -puN arch/mips/kernel/ptrace.c~git-audit arch/mips/kernel/ptrace.c
--- 25/arch/mips/kernel/ptrace.c~git-audit	2005-05-04 16:42:14.000000000 -0700
+++ 25-akpm/arch/mips/kernel/ptrace.c	2005-05-04 16:42:14.000000000 -0700
@@ -301,25 +301,38 @@ out:
 	return ret;
 }
 
+static inline int audit_arch(void)
+{
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#ifdef CONFIG_MIPS64
+	if (!(current-&gt;thread.mflags &amp; MF_32BIT_REGS))
+		return AUDIT_ARCH_MIPSEL64;
+#endif /* MIPS64 */
+	return AUDIT_ARCH_MIPSEL;
+
+#else /* big endian... */
+#ifdef CONFIG_MIPS64
+	if (!(current-&gt;thread.mflags &amp; MF_32BIT_REGS))
+		return AUDIT_ARCH_MIPS64;
+#endif /* MIPS64 */
+	return AUDIT_ARCH_MIPS;
+
+#endif /* endian */
+}
+
 /*
  * Notification of system call entry/exit
  * - triggered by current-&gt;work.syscall_trace
  */
 asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
 {
-	if (unlikely(current-&gt;audit_context)) {
-		if (!entryexit)
-			audit_syscall_entry(current, regs-&gt;regs[2],
-			                    regs-&gt;regs[4], regs-&gt;regs[5],
-			                    regs-&gt;regs[6], regs-&gt;regs[7]);
-		else
-			audit_syscall_exit(current, regs-&gt;regs[2]);
-	}
+	if (unlikely(current-&gt;audit_context) &amp;&amp; entryexit)
+		audit_syscall_exit(current, AUDITSC_RESULT(regs-&gt;regs[2]), regs-&gt;regs[2]);
 
 	if (!test_thread_flag(TIF_SYSCALL_TRACE))
-		return;
+		goto out;
 	if (!(current-&gt;ptrace &amp; PT_PTRACED))
-		return;
+		goto out;
 
 	/* The 0x80 provides a way for the tracing parent to distinguish
 	   between a syscall stop and SIGTRAP delivery */
@@ -335,4 +348,9 @@ asmlinkage void do_syscall_trace(struct 
 		send_sig(current-&gt;exit_code, current, 1);
 		current-&gt;exit_code = 0;
 	}
+ out:
+	if (unlikely(current-&gt;audit_context) &amp;&amp; !entryexit)
+		audit_syscall_entry(current, audit_arch(), regs-&gt;regs[2],
+				    regs-&gt;regs[4], regs-&gt;regs[5],
+				    regs-&gt;regs[6], regs-&gt;regs[7]);
 }
diff -puN arch/ppc64/kernel/ptrace.c~git-audit arch/ppc64/kernel/ptrace.c
--- 25/arch/ppc64/kernel/ptrace.c~git-audit	2005-05-04 16:42:14.000000000 -0700
+++ 25-akpm/arch/ppc64/kernel/ptrace.c	2005-05-04 16:42:14.000000000 -0700
@@ -305,14 +305,17 @@ static void do_syscall_trace(void)
 
 void do_syscall_trace_enter(struct pt_regs *regs)
 {
+	if (test_thread_flag(TIF_SYSCALL_TRACE)
+	    &amp;&amp; (current-&gt;ptrace &amp; PT_PTRACED))
+		do_syscall_trace();
+
 	if (unlikely(current-&gt;audit_context))
-		audit_syscall_entry(current, regs-&gt;gpr[0],
+		audit_syscall_entry(current,
+				    test_thread_flag(TIF_32BIT)?AUDIT_ARCH_PPC:AUDIT_ARCH_PPC64,
+				    regs-&gt;gpr[0],
 				    regs-&gt;gpr[3], regs-&gt;gpr[4],
 				    regs-&gt;gpr[5], regs-&gt;gpr[6]);
 
-	if (test_thread_flag(TIF_SYSCALL_TRACE)
-	    &amp;&amp; (current-&gt;ptrace &amp; PT_PTRACED))
-		do_syscall_trace();
 }
 
 void do_syscall_trace_leave(struct pt_regs *regs)
@@ -320,7 +323,9 @@ void do_syscall_trace_leave(struct pt_re
 	secure_computing(regs-&gt;gpr[0]);
 
 	if (unlikely(current-&gt;audit_context))
-		audit_syscall_exit(current, regs-&gt;result);
+		audit_syscall_exit(current, 
+				   (regs-&gt;ccr&amp;0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
+				   regs-&gt;result);
 
 	if ((test_thread_flag(TIF_SYSCALL_TRACE)
 	     || test_thread_flag(TIF_SINGLESTEP))
diff -puN arch/s390/kernel/ptrace.c~git-audit arch/s390/kernel/ptrace.c
--- 25/arch/s390/kernel/ptrace.c~git-audit	2005-05-04 16:42:14.000000000 -0700
+++ 25-akpm/arch/s390/kernel/ptrace.c	2005-05-04 16:42:14.000000000 -0700
@@ -712,18 +712,13 @@ out:
 asmlinkage void
 syscall_trace(struct pt_regs *regs, int entryexit)
 {
-	if (unlikely(current-&gt;audit_context)) {
-		if (!entryexit)
-			audit_syscall_entry(current, regs-&gt;gprs[2],
-					    regs-&gt;orig_gpr2, regs-&gt;gprs[3],
-					    regs-&gt;gprs[4], regs-&gt;gprs[5]);
-		else
-			audit_syscall_exit(current, regs-&gt;gprs[2]);
-	}
+	if (unlikely(current-&gt;audit_context) &amp;&amp; entryexit)
+		audit_syscall_exit(current, AUDITSC_RESULT(regs-&gt;gprs[2]), regs-&gt;gprs[2]);
+
 	if (!test_thread_flag(TIF_SYSCALL_TRACE))
-		return;
+		goto out;
 	if (!(current-&gt;ptrace &amp; PT_PTRACED))
-		return;
+		goto out;
 	ptrace_notify(SIGTRAP | ((current-&gt;ptrace &amp; PT_TRACESYSGOOD)
 				 ? 0x80 : 0));
 
@@ -736,4 +731,10 @@ syscall_trace(struct pt_regs *regs, int 
 		send_sig(current-&gt;exit_code, current, 1);
 		current-&gt;exit_code = 0;
 	}
+ out:
+	if (unlikely(current-&gt;audit_context) &amp;&amp; !entryexit)
+		audit_syscall_entry(current, 
+				    test_thread_flag(TIF_31BIT)?AUDIT_ARCH_S390:AUDIT_ARCH_S390X,
+				    regs-&gt;gprs[2], regs-&gt;orig_gpr2, regs-&gt;gprs[3],
+				    regs-&gt;gprs[4], regs-&gt;gprs[5]);
 }
diff -puN arch/um/kernel/ptrace.c~git-audit arch/um/kernel/ptrace.c
--- 25/arch/um/kernel/ptrace.c~git-audit	2005-05-04 16:42:14.000000000 -0700
+++ 25-akpm/arch/um/kernel/ptrace.c	2005-05-04 16:42:14.000000000 -0700
@@ -337,15 +337,18 @@ void syscall_trace(union uml_pt_regs *re
 
 	if (unlikely(current-&gt;audit_context)) {
 		if (!entryexit)
-			audit_syscall_entry(current, 
-					    UPT_SYSCALL_NR(&amp;regs-&gt;regs),
-					    UPT_SYSCALL_ARG1(&amp;regs-&gt;regs),
-					    UPT_SYSCALL_ARG2(&amp;regs-&gt;regs),
-					    UPT_SYSCALL_ARG3(&amp;regs-&gt;regs),
-					    UPT_SYSCALL_ARG4(&amp;regs-&gt;regs));
-		else
-			audit_syscall_exit(current, 
-					   UPT_SYSCALL_RET(&amp;regs-&gt;regs));
+			audit_syscall_entry(current,
+                                            HOST_AUDIT_ARCH,
+					    UPT_SYSCALL_NR(regs),
+					    UPT_SYSCALL_ARG1(regs),
+					    UPT_SYSCALL_ARG2(regs),
+					    UPT_SYSCALL_ARG3(regs),
+					    UPT_SYSCALL_ARG4(regs));
+		else {
+                        int res = UPT_SYSCALL_RET(regs);
+			audit_syscall_exit(current, AUDITSC_RESULT(res),
+                                           res);
+                }
 	}
 
 	/* Fake a debug trap */
diff -puN arch/x86_64/kernel/ptrace.c~git-audit arch/x86_64/kernel/ptrace.c
--- 25/arch/x86_64/kernel/ptrace.c~git-audit	2005-05-04 16:42:14.000000000 -0700
+++ 25-akpm/arch/x86_64/kernel/ptrace.c	2005-05-04 16:42:14.000000000 -0700
@@ -635,20 +635,29 @@ asmlinkage void syscall_trace_enter(stru
 	/* do the secure computing check first */
 	secure_computing(regs-&gt;orig_rax);
 
-	if (unlikely(current-&gt;audit_context))
-		audit_syscall_entry(current, regs-&gt;orig_rax,
-				    regs-&gt;rdi, regs-&gt;rsi,
-				    regs-&gt;rdx, regs-&gt;r10);
-
 	if (test_thread_flag(TIF_SYSCALL_TRACE)
 	    &amp;&amp; (current-&gt;ptrace &amp; PT_PTRACED))
 		syscall_trace(regs);
+
+	if (unlikely(current-&gt;audit_context)) {
+		if (test_thread_flag(TIF_IA32)) {
+			audit_syscall_entry(current, AUDIT_ARCH_I386,
+					    regs-&gt;orig_rax,
+					    regs-&gt;rbx, regs-&gt;rcx,
+					    regs-&gt;rdx, regs-&gt;rsi);
+		} else {
+			audit_syscall_entry(current, AUDIT_ARCH_X86_64,
+					    regs-&gt;orig_rax,
+					    regs-&gt;rdi, regs-&gt;rsi,
+					    regs-&gt;rdx, regs-&gt;r10);
+		}
+	}
 }
 
 asmlinkage void syscall_trace_leave(struct pt_regs *regs)
 {
 	if (unlikely(current-&gt;audit_context))
-		audit_syscall_exit(current, regs-&gt;rax);
+		audit_syscall_exit(current, AUDITSC_RESULT(regs-&gt;rax), regs-&gt;rax);
 
 	if ((test_thread_flag(TIF_SYSCALL_TRACE)
 	     || test_thread_flag(TIF_SINGLESTEP))
diff -puN fs/namei.c~git-audit fs/namei.c
--- 25/fs/namei.c~git-audit	2005-05-04 16:42:14.000000000 -0700
+++ 25-akpm/fs/namei.c	2005-05-04 16:42:14.000000000 -0700
@@ -686,11 +686,11 @@ fail:
 
 /*
  * Name resolution.
+ * This is the basic name resolution function, turning a pathname into
+ * the final dentry. We expect 'base' to be positive and a directory.
  *
- * This is the basic name resolution function, turning a pathname
- * into the final dentry.
- *
- * We expect 'base' to be positive and a directory.
+ * Returns 0 and nd will have valid dentry and mnt on success.
+ * Returns error and drops reference to input namei data on failure.
  */
 static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
 {
@@ -929,8 +929,10 @@ int fastcall path_walk(const char * name
 	return link_path_walk(name, nd);
 }
 
-/* SMP-safe */
-/* returns 1 if everything is done */
+/* 
+ * SMP-safe: Returns 1 and nd will have valid dentry and mnt, if
+ * everything is done. Returns 0 and drops input nd, if lookup failed;
+ */
 static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
 {
 	if (path_walk(name, nd))
@@ -994,9 +996,10 @@ set_it:
 	}
 }
 
+/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
 int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata *nd)
 {
-	int retval;
+	int retval = 0;
 
 	nd-&gt;last_type = LAST_ROOT; /* if there are only slashes... */
 	nd-&gt;flags = flags;
@@ -1009,7 +1012,7 @@ int fastcall path_lookup(const char *nam
 			nd-&gt;dentry = dget(current-&gt;fs-&gt;altroot);
 			read_unlock(&amp;current-&gt;fs-&gt;lock);
 			if (__emul_lookup_dentry(name,nd))
-				return 0;
+				goto out; /* found in altroot */
 			read_lock(&amp;current-&gt;fs-&gt;lock);
 		}
 		nd-&gt;mnt = mntget(current-&gt;fs-&gt;rootmnt);
@@ -1021,6 +1024,7 @@ int fastcall path_lookup(const char *nam
 	read_unlock(&amp;current-&gt;fs-&gt;lock);
 	current-&gt;total_link_count = 0;
 	retval = link_path_walk(name, nd);
+out:
 	if (unlikely(current-&gt;audit_context
 		     &amp;&amp; nd &amp;&amp; nd-&gt;dentry &amp;&amp; nd-&gt;dentry-&gt;d_inode))
 		audit_inode(name, nd-&gt;dentry-&gt;d_inode);
diff -puN fs/proc/base.c~git-audit fs/proc/base.c
--- 25/fs/proc/base.c~git-audit	2005-05-04 16:42:14.000000000 -0700
+++ 25-akpm/fs/proc/base.c	2005-05-04 16:42:14.000000000 -0700
@@ -820,7 +820,7 @@ static ssize_t proc_loginuid_write(struc
 		goto out_free_page;
 
 	}
-	length = audit_set_loginuid(task-&gt;audit_context, loginuid);
+	length = audit_set_loginuid(task, loginuid);
 	if (likely(length == 0))
 		length = count;
 
diff -puN include/asm-um/ptrace-i386.h~git-audit include/asm-um/ptrace-i386.h
--- 25/include/asm-um/ptrace-i386.h~git-audit	2005-05-04 16:42:14.000000000 -0700
+++ 25-akpm/include/asm-um/ptrace-i386.h	2005-05-04 16:42:14.000000000 -0700
@@ -6,6 +6,8 @@
 #ifndef __UM_PTRACE_I386_H
 #define __UM_PTRACE_I386_H
 
+#define HOST_AUDIT_ARCH AUDIT_ARCH_I386
+
 #include "sysdep/ptrace.h"
 #include "asm/ptrace-generic.h"
 
diff -puN include/asm-um/ptrace-x86_64.h~git-audit include/asm-um/ptrace-x86_64.h
--- 25/include/asm-um/ptrace-x86_64.h~git-audit	2005-05-04 16:42:14.000000000 -0700
+++ 25-akpm/include/asm-um/ptrace-x86_64.h	2005-05-04 16:42:14.000000000 -0700
@@ -14,6 +14,8 @@
 #include "asm/ptrace-generic.h"
 #undef signal_fault
 
+#define HOST_AUDIT_ARCH AUDIT_ARCH_X86_64
+
 void signal_fault(struct pt_regs_subarch *regs, void *frame, char *where);
 
 #define FS_BASE (21 * sizeof(unsigned long))
diff -puN include/asm-um/thread_info.h~git-audit include/asm-um/thread_info.h
--- 25/include/asm-um/thread_info.h~git-audit	2005-05-04 16:42:14.000000000 -0700
+++ 25-akpm/include/asm-um/thread_info.h	2005-05-04 16:42:14.000000000 -0700
@@ -72,12 +72,14 @@ static inline struct thread_info *curren
 					 */
 #define TIF_RESTART_BLOCK 	4
 #define TIF_MEMDIE	 	5
+#define TIF_SYSCALL_AUDIT	6
 
 #define _TIF_SYSCALL_TRACE	(1 &lt;&lt; TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING		(1 &lt;&lt; TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1 &lt;&lt; TIF_NEED_RESCHED)
 #define _TIF_POLLING_NRFLAG     (1 &lt;&lt; TIF_POLLING_NRFLAG)
-#define _TIF_RESTART_BLOCK	(1 &lt;&lt; TIF_RESTART_BLOCK)
+#define _TIF_MEMDIE		(1 &lt;&lt; TIF_MEMDIE)
+#define _TIF_SYSCALL_AUDIT	(1 &lt;&lt; TIF_SYSCALL_AUDIT)
 
 #endif
 
diff -puN include/linux/audit.h~git-audit include/linux/audit.h
--- 25/include/linux/audit.h~git-audit	2005-05-04 16:42:14.000000000 -0700
+++ 25-akpm/include/linux/audit.h	2005-05-04 16:42:14.000000000 -0700
@@ -1,4 +1,4 @@
-/* audit.h -- Auditing support -*- linux-c -*-
+/* audit.h -- Auditing support
  *
  * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
  * All Rights Reserved.
@@ -24,6 +24,9 @@
 #ifndef _LINUX_AUDIT_H_
 #define _LINUX_AUDIT_H_
 
+#include &lt;linux/sched.h&gt;
+#include &lt;linux/elf.h&gt;
+
 /* Request and reply types */
 #define AUDIT_GET      1000	/* Get status */
 #define AUDIT_SET      1001	/* Set status (enable/disable/auditd) */
@@ -67,6 +70,7 @@
 #define AUDIT_FSGID	8
 #define AUDIT_LOGINUID	9
 #define AUDIT_PERS	10
+#define AUDIT_ARCH	11
 
 				/* These are ONLY useful when checking
 				 * at syscall exit time (AUDIT_AT_EXIT). */
@@ -96,6 +100,38 @@
 #define AUDIT_FAIL_PRINTK	1
 #define AUDIT_FAIL_PANIC	2
 
+/* distinguish syscall tables */
+#define __AUDIT_ARCH_64BIT 0x80000000
+#define __AUDIT_ARCH_LE	   0x40000000
+#define AUDIT_ARCH_ALPHA	(EM_ALPHA|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_ARM		(EM_ARM|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_ARMEB	(EM_ARM)
+#define AUDIT_ARCH_CRIS		(EM_CRIS|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_FRV		(EM_FRV)
+#define AUDIT_ARCH_H8300	(EM_H8_300)
+#define AUDIT_ARCH_I386		(EM_386|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_IA64		(EM_IA_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_M32R		(EM_M32R)
+#define AUDIT_ARCH_M68K		(EM_68K)
+#define AUDIT_ARCH_MIPS		(EM_MIPS)
+#define AUDIT_ARCH_MIPSEL	(EM_MIPS|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_MIPS64	(EM_MIPS|__AUDIT_ARCH_64BIT)
+#define AUDIT_ARCH_MIPSEL64	(EM_MIPS|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_PARISC	(EM_PARISC)
+#define AUDIT_ARCH_PARISC64	(EM_PARISC|__AUDIT_ARCH_64BIT)
+#define AUDIT_ARCH_PPC		(EM_PPC)
+#define AUDIT_ARCH_PPC64	(EM_PPC64|__AUDIT_ARCH_64BIT)
+#define AUDIT_ARCH_S390		(EM_S390)
+#define AUDIT_ARCH_S390X	(EM_S390|__AUDIT_ARCH_64BIT)
+#define AUDIT_ARCH_SH		(EM_SH)
+#define AUDIT_ARCH_SHEL		(EM_SH|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_SH64		(EM_SH|__AUDIT_ARCH_64BIT)
+#define AUDIT_ARCH_SHEL64	(EM_SH|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_SPARC	(EM_SPARC)
+#define AUDIT_ARCH_SPARC64	(EM_SPARC64|__AUDIT_ARCH_64BIT)
+#define AUDIT_ARCH_V850		(EM_V850|__AUDIT_ARCH_LE)
+#define AUDIT_ARCH_X86_64	(EM_X86_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+
 #ifndef __KERNEL__
 struct audit_message {
 	struct nlmsghdr nlh;
@@ -129,32 +165,36 @@ struct audit_buffer;
 struct audit_context;
 struct inode;
 
+#define AUDITSC_INVALID 0
+#define AUDITSC_SUCCESS 1
+#define AUDITSC_FAILURE 2
+#define AUDITSC_RESULT(x) ( ((long)(x))&lt;0?AUDITSC_FAILURE:AUDITSC_SUCCESS )
 #ifdef CONFIG_AUDITSYSCALL
 /* These are defined in auditsc.c */
 				/* Public API */
 extern int  audit_alloc(struct task_struct *task);
 extern void audit_free(struct task_struct *task);
-extern void audit_syscall_entry(struct task_struct *task,
+extern void audit_syscall_entry(struct task_struct *task, int arch,
 				int major, unsigned long a0, unsigned long a1,
 				unsigned long a2, unsigned long a3);
-extern void audit_syscall_exit(struct task_struct *task, int return_code);
+extern void audit_syscall_exit(struct task_struct *task, int failed, long return_code);
 extern void audit_getname(const char *name);
 extern void audit_putname(const char *name);
 extern void audit_inode(const char *name, const struct inode *inode);
 
 				/* Private API (for audit.c only) */
 extern int  audit_receive_filter(int type, int pid, int uid, int seq,
-				 void *data);
+				 void *data, uid_t loginuid);
 extern void audit_get_stamp(struct audit_context *ctx,
-			    struct timespec *t, int *serial);
-extern int  audit_set_loginuid(struct audit_context *ctx, uid_t loginuid);
+			    struct timespec *t, unsigned int *serial);
+extern int  audit_set_loginuid(struct task_struct *task, uid_t loginuid);
 extern uid_t audit_get_loginuid(struct audit_context *ctx);
 extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
 #else
 #define audit_alloc(t) ({ 0; })
 #define audit_free(t) do { ; } while (0)
-#define audit_syscall_entry(t,a,b,c,d,e) do { ; } while (0)
-#define audit_syscall_exit(t,r) do { ; } while (0)
+#define audit_syscall_entry(t,ta,a,b,c,d,e) do { ; } while (0)
+#define audit_syscall_exit(t,f,r) do { ; } while (0)
 #define audit_getname(n) do { ; } while (0)
 #define audit_putname(n) do { ; } while (0)
 #define audit_inode(n,i) do { ; } while (0)
@@ -174,11 +214,15 @@ extern void		    audit_log_format(struct
 					     const char *fmt, ...)
 			    __attribute__((format(printf,2,3)));
 extern void		    audit_log_end(struct audit_buffer *ab);
+extern void		    audit_log_hex(struct audit_buffer *ab,
+					  const unsigned char *buf,
+					  size_t len);
+extern void		    audit_log_untrustedstring(struct audit_buffer *ab,
+						      const char *string);
 extern void		    audit_log_d_path(struct audit_buffer *ab,
 					     const char *prefix,
 					     struct dentry *dentry,
 					     struct vfsmount *vfsmnt);
-
 				/* Private API (for auditsc.c only) */
 extern void		    audit_send_reply(int pid, int seq, int type,
 					     int done, int multi,
@@ -190,6 +234,8 @@ extern void		    audit_log_lost(const ch
 #define audit_log_vformat(b,f,a) do { ; } while (0)
 #define audit_log_format(b,f,...) do { ; } while (0)
 #define audit_log_end(b) do { ; } while (0)
+#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)
 #endif
 #endif
diff -puN include/linux/netlink.h~git-audit include/linux/netlink.h
--- 25/include/linux/netlink.h~git-audit	2005-05-04 16:42:14.000000000 -0700
+++ 25-akpm/include/linux/netlink.h	2005-05-04 16:42:14.000000000 -0700
@@ -110,6 +110,7 @@ struct netlink_skb_parms
 	__u32			dst_pid;
 	__u32			dst_groups;
 	kernel_cap_t		eff_cap;
+	__u32			loginuid;	/* Login (audit) uid */
 };
 
 #define NETLINK_CB(skb)		(*(struct netlink_skb_parms*)&amp;((skb)-&gt;cb))
diff -puN init/Kconfig~git-audit init/Kconfig
--- 25/init/Kconfig~git-audit	2005-05-04 16:42:14.000000000 -0700
+++ 25-akpm/init/Kconfig	2005-05-04 16:42:14.000000000 -0700
@@ -173,7 +173,7 @@ config AUDIT
 
 config AUDITSYSCALL
 	bool "Enable system-call auditing support"
-	depends on AUDIT &amp;&amp; (X86 || PPC64 || ARCH_S390 || IA64)
+	depends on AUDIT &amp;&amp; (X86 || PPC64 || ARCH_S390 || IA64 || UML)
 	default y if SECURITY_SELINUX
 	help
 	  Enable low-overhead system-call auditing infrastructure that
diff -puN kernel/audit.c~git-audit kernel/audit.c
--- 25/kernel/audit.c~git-audit	2005-05-04 16:42:14.000000000 -0700
+++ 25-akpm/kernel/audit.c	2005-05-04 16:42:14.000000000 -0700
@@ -1,4 +1,4 @@
-/* audit.c -- Auditing support -*- linux-c -*-
+/* audit.c -- Auditing support
  * Gateway between the kernel (e.g., selinux) and the user-space audit daemon.
  * System-call specific features have moved to auditsc.c
  *
@@ -38,7 +38,7 @@
  *	  6) Support low-overhead kernel-based filtering to minimize the
  *	     information that must be passed to user-space.
  *
- * Example user-space utilities: http://people.redhat.com/faith/audit/
+ * Example user-space utilities: http://people.redhat.com/sgrubb/audit/
  */
 
 #include &lt;linux/init.h&gt;
@@ -142,7 +142,6 @@ struct audit_buffer {
 	int		     total;
 	int		     type;
 	int		     pid;
-	int		     count; /* Times requeued */
 };
 
 void audit_set_type(struct audit_buffer *ab, int type)
@@ -239,36 +238,36 @@ void audit_log_lost(const char *message)
 
 }
 
-static int audit_set_rate_limit(int limit)
+static int audit_set_rate_limit(int limit, uid_t loginuid)
 {
 	int old		 = audit_rate_limit;
 	audit_rate_limit = limit;
-	audit_log(current-&gt;audit_context, "audit_rate_limit=%d old=%d",
-		  audit_rate_limit, old);
+	audit_log(NULL, "audit_rate_limit=%d old=%d by auid %u",
+			audit_rate_limit, old, loginuid);
 	return old;
 }
 
-static int audit_set_backlog_limit(int limit)
+static int audit_set_backlog_limit(int limit, uid_t loginuid)
 {
 	int old		 = audit_backlog_limit;
 	audit_backlog_limit = limit;
-	audit_log(current-&gt;audit_context, "audit_backlog_limit=%d old=%d",
-		  audit_backlog_limit, old);
+	audit_log(NULL, "audit_backlog_limit=%d old=%d by auid %u",
+			audit_backlog_limit, old, loginuid);
 	return old;
 }
 
-static int audit_set_enabled(int state)
+static int audit_set_enabled(int state, uid_t loginuid)
 {
 	int old		 = audit_enabled;
 	if (state != 0 &amp;&amp; state != 1)
 		return -EINVAL;
 	audit_enabled = state;
-	audit_log(current-&gt;audit_context, "audit_enabled=%d old=%d",
-		  audit_enabled, old);
+	audit_log(NULL, "audit_enabled=%d old=%d by auid %u",
+		  audit_enabled, old, loginuid);
 	return old;
 }
 
-static int audit_set_failure(int state)
+static int audit_set_failure(int state, uid_t loginuid)
 {
 	int old		 = audit_failure;
 	if (state != AUDIT_FAIL_SILENT
@@ -276,8 +275,8 @@ static int audit_set_failure(int state)
 	    &amp;&amp; state != AUDIT_FAIL_PANIC)
 		return -EINVAL;
 	audit_failure = state;
-	audit_log(current-&gt;audit_context, "audit_failure=%d old=%d",
-		  audit_failure, old);
+	audit_log(NULL, "audit_failure=%d old=%d by auid %u",
+		  audit_failure, old, loginuid);
 	return old;
 }
 
@@ -344,6 +343,7 @@ static int audit_receive_msg(struct sk_b
 	int			err;
 	struct audit_buffer	*ab;
 	u16			msg_type = nlh-&gt;nlmsg_type;
+	uid_t			loginuid; /* loginuid of sender */
 
 	err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type);
 	if (err)
@@ -351,6 +351,7 @@ static int audit_receive_msg(struct sk_b
 
 	pid  = NETLINK_CREDS(skb)-&gt;pid;
 	uid  = NETLINK_CREDS(skb)-&gt;uid;
+	loginuid = NETLINK_CB(skb).loginuid;
 	seq  = nlh-&gt;nlmsg_seq;
 	data = NLMSG_DATA(nlh);
 
@@ -371,34 +372,36 @@ static int audit_receive_msg(struct sk_b
 			return -EINVAL;
 		status_get   = (struct audit_status *)data;
 		if (status_get-&gt;mask &amp; AUDIT_STATUS_ENABLED) {
-			err = audit_set_enabled(status_get-&gt;enabled);
+			err = audit_set_enabled(status_get-&gt;enabled, loginuid);
 			if (err &lt; 0) return err;
 		}
 		if (status_get-&gt;mask &amp; AUDIT_STATUS_FAILURE) {
-			err = audit_set_failure(status_get-&gt;failure);
+			err = audit_set_failure(status_get-&gt;failure, loginuid);
 			if (err &lt; 0) return err;
 		}
 		if (status_get-&gt;mask &amp; AUDIT_STATUS_PID) {
 			int old   = audit_pid;
 			audit_pid = status_get-&gt;pid;
-			audit_log(current-&gt;audit_context,
-				  "audit_pid=%d old=%d", audit_pid, old);
+			audit_log(NULL, "audit_pid=%d old=%d by auid %u",
+				  audit_pid, old, loginuid);
 		}
 		if (status_get-&gt;mask &amp; AUDIT_STATUS_RATE_LIMIT)
-			audit_set_rate_limit(status_get-&gt;rate_limit);
+			audit_set_rate_limit(status_get-&gt;rate_limit, loginuid);
 		if (status_get-&gt;mask &amp; AUDIT_STATUS_BACKLOG_LIMIT)
-			audit_set_backlog_limit(status_get-&gt;backlog_limit);
+			audit_set_backlog_limit(status_get-&gt;backlog_limit,
+							loginuid);
 		break;
 	case AUDIT_USER:
 		ab = audit_log_start(NULL);
 		if (!ab)
 			break;	/* audit_panic has been called */
 		audit_log_format(ab,
-				 "user pid=%d uid=%d length=%d msg='%.1024s'",
+				 "user pid=%d uid=%d length=%d loginuid=%u"
+				 " msg='%.1024s'",
 				 pid, uid,
 				 (int)(nlh-&gt;nlmsg_len
 				       - ((char *)data - (char *)nlh)),
-				 (char *)data);
+				 loginuid, (char *)data);
 		ab-&gt;type = AUDIT_USER;
 		ab-&gt;pid  = pid;
 		audit_log_end(ab);
@@ -411,7 +414,7 @@ static int audit_receive_msg(struct sk_b
 	case AUDIT_LIST:
 #ifdef CONFIG_AUDITSYSCALL
 		err = audit_receive_filter(nlh-&gt;nlmsg_type, NETLINK_CB(skb).pid,
-					   uid, seq, data);
+					   uid, seq, data, loginuid);
 #else
 		err = -EOPNOTSUPP;
 #endif
@@ -480,7 +483,7 @@ static void audit_log_move(struct audit_
 	if (ab-&gt;len == 0)
 		return;
 
-	skb = skb_peek(&amp;ab-&gt;sklist);
+	skb = skb_peek_tail(&amp;ab-&gt;sklist);
 	if (!skb || skb_tailroom(skb) &lt;= ab-&gt;len + extra) {
 		skb = alloc_skb(2 * ab-&gt;len + extra, GFP_ATOMIC);
 		if (!skb) {
@@ -519,9 +522,9 @@ static inline int audit_log_drain(struct
 			retval = netlink_unicast(audit_sock, skb, audit_pid,
 						 MSG_DONTWAIT);
 		}
-		if (retval == -EAGAIN &amp;&amp; ab-&gt;count &lt; 5) {
-			++ab-&gt;count;
-			skb_queue_tail(&amp;ab-&gt;sklist, skb);
+		if (retval == -EAGAIN &amp;&amp;
+		    (atomic_read(&amp;audit_backlog)) &lt; audit_backlog_limit) {
+			skb_queue_head(&amp;ab-&gt;sklist, skb);
 			audit_log_end_irq(ab);
 			return 1;
 		}
@@ -537,8 +540,8 @@ static inline int audit_log_drain(struct
 		if (!audit_pid) { /* No daemon */
 			int offset = ab-&gt;nlh ? NLMSG_SPACE(0) : 0;
 			int len    = skb-&gt;len - offset;
-			printk(KERN_ERR "%*.*s\n",
-			       len, len, skb-&gt;data + offset);
+			skb-&gt;data[offset + len] = '\0';
+			printk(KERN_ERR "%s\n", skb-&gt;data + offset);
 		}
 		kfree_skb(skb);
 		ab-&gt;nlh = NULL;
@@ -617,7 +620,7 @@ struct audit_buffer *audit_log_start(str
 	struct audit_buffer	*ab	= NULL;
 	unsigned long		flags;
 	struct timespec		t;
-	int			serial	= 0;
+	unsigned int		serial;
 
 	if (!audit_initialized)
 		return NULL;
@@ -659,15 +662,16 @@ struct audit_buffer *audit_log_start(str
 	ab-&gt;total = 0;
 	ab-&gt;type  = AUDIT_KERNEL;
 	ab-&gt;pid   = 0;
-	ab-&gt;count = 0;
 
 #ifdef CONFIG_AUDITSYSCALL
 	if (ab-&gt;ctx)
 		audit_get_stamp(ab-&gt;ctx, &amp;t, &amp;serial);
 	else
 #endif
+	{
 		t = CURRENT_TIME;
-
+		serial = 0;
+	}
 	audit_log_format(ab, "audit(%lu.%03lu:%u): ",
 			 t.tv_sec, t.tv_nsec/1000000, serial);
 	return ab;
@@ -717,6 +721,29 @@ void audit_log_format(struct audit_buffe
 	va_end(args);
 }
 
+void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, size_t len)
+{
+	int i;
+
+	for (i=0; i&lt;len; i++)
+		audit_log_format(ab, "%02x", buf[i]);
+}
+
+void audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
+{
+	const unsigned char *p = string;
+
+	while (*p) {
+		if (*p == '"' || *p == ' ' || *p &lt; 0x20 || *p &gt; 0x7f) {
+			audit_log_hex(ab, string, strlen(string));
+			return;
+		}
+		p++;
+	}
+	audit_log_format(ab, "\"%s\"", string);
+}
+
+
 /* This is a helper-function to print the d_path without using a static
  * buffer or allocating another buffer in addition to the one in
  * audit_buffer. */
diff -puN kernel/auditsc.c~git-audit kernel/auditsc.c
--- 25/kernel/auditsc.c~git-audit	2005-05-04 16:42:14.000000000 -0700
+++ 25-akpm/kernel/auditsc.c	2005-05-04 16:42:14.000000000 -0700
@@ -1,4 +1,4 @@
-/* auditsc.c -- System-call auditing support -*- linux-c -*-
+/* auditsc.c -- System-call auditing support
  * Handles all system-call specific auditing features.
  *
  * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
@@ -123,7 +123,7 @@ struct audit_context {
 	int		    major;      /* syscall number */
 	unsigned long	    argv[4];    /* syscall arguments */
 	int		    return_valid; /* return code is valid */
-	int		    return_code;/* syscall return code */
+	long		    return_code;/* syscall return code */
 	int		    auditable;  /* 1 if record should be written */
 	int		    name_count;
 	struct audit_names  names[AUDIT_NAMES];
@@ -135,6 +135,7 @@ struct audit_context {
 	uid_t		    uid, euid, suid, fsuid;
 	gid_t		    gid, egid, sgid, fsgid;
 	unsigned long	    personality;
+	int		    arch;
 
 #if AUDIT_DEBUG
 	int		    put_count;
@@ -250,7 +251,8 @@ static int audit_copy_rule(struct audit_
 	return 0;
 }
 
-int audit_receive_filter(int type, int pid, int uid, int seq, void *data)
+int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
+							uid_t loginuid)
 {
 	u32		   flags;
 	struct audit_entry *entry;
@@ -285,6 +287,7 @@ int audit_receive_filter(int type, int p
 			err = audit_add_rule(entry, &amp;audit_entlist);
 		if (!err &amp;&amp; (flags &amp; AUDIT_AT_EXIT))
 			err = audit_add_rule(entry, &amp;audit_extlist);
+		audit_log(NULL, "auid %u added an audit rule\n", loginuid);
 		break;
 	case AUDIT_DEL:
 		flags =((struct audit_rule *)data)-&gt;flags;
@@ -294,6 +297,7 @@ int audit_receive_filter(int type, int p
 			err = audit_del_rule(data, &amp;audit_entlist);
 		if (!err &amp;&amp; (flags &amp; AUDIT_AT_EXIT))
 			err = audit_del_rule(data, &amp;audit_extlist);
+		audit_log(NULL, "auid %u removed an audit rule\n", loginuid);
 		break;
 	default:
 		return -EINVAL;
@@ -348,6 +352,10 @@ static int audit_filter_rules(struct tas
 		case AUDIT_PERS:
 			result = (tsk-&gt;personality == value);
 			break;
+		case AUDIT_ARCH:
+			if (ctx) 
+				result = (ctx-&gt;arch == value);
+			break;
 
 		case AUDIT_EXIT:
 			if (ctx &amp;&amp; ctx-&gt;return_valid)
@@ -355,7 +363,7 @@ static int audit_filter_rules(struct tas
 			break;
 		case AUDIT_SUCCESS:
 			if (ctx &amp;&amp; ctx-&gt;return_valid)
-				result = (ctx-&gt;return_code &gt;= 0);
+				result = (ctx-&gt;return_valid == AUDITSC_SUCCESS);
 			break;
 		case AUDIT_DEVMAJOR:
 			if (ctx) {
@@ -648,8 +656,11 @@ static void audit_log_exit(struct audit_
 	audit_log_format(ab, "syscall=%d", context-&gt;major);
 	if (context-&gt;personality != PER_LINUX)
 		audit_log_format(ab, " per=%lx", context-&gt;personality);
+	audit_log_format(ab, " arch=%x", context-&gt;arch);
 	if (context-&gt;return_valid)
-		audit_log_format(ab, " exit=%d", context-&gt;return_code);
+		audit_log_format(ab, " success=%s exit=%ld", 
+				 (context-&gt;return_valid==AUDITSC_SUCCESS)?"yes":"no",
+				 context-&gt;return_code);
 	audit_log_format(ab,
 		  " a0=%lx a1=%lx a2=%lx a3=%lx items=%d"
 		  " pid=%d loginuid=%d uid=%d gid=%d"
@@ -696,9 +707,10 @@ static void audit_log_exit(struct audit_
 		if (!ab)
 			continue; /* audit_panic has been called */
 		audit_log_format(ab, "item=%d", i);
-		if (context-&gt;names[i].name)
-			audit_log_format(ab, " name=%s",
-					 context-&gt;names[i].name);
+		if (context-&gt;names[i].name) {
+			audit_log_format(ab, " name=");
+			audit_log_untrustedstring(ab, context-&gt;names[i].name);
+		}
 		if (context-&gt;names[i].ino != (unsigned long)-1)
 			audit_log_format(ab, " inode=%lu dev=%02x:%02x mode=%#o"
 					     " uid=%d gid=%d rdev=%02x:%02x",
@@ -772,7 +784,7 @@ static inline unsigned int audit_serial(
  * then the record will be written at syscall exit time (otherwise, it
  * will only be written if another part of the kernel requests that it
  * be written). */
-void audit_syscall_entry(struct task_struct *tsk, int major,
+void audit_syscall_entry(struct task_struct *tsk, int arch, int major,
 			 unsigned long a1, unsigned long a2,
 			 unsigned long a3, unsigned long a4)
 {
@@ -826,6 +838,7 @@ void audit_syscall_entry(struct task_str
 	if (!audit_enabled)
 		return;
 
+	context-&gt;arch	    = arch;
 	context-&gt;major      = major;
 	context-&gt;argv[0]    = a1;
 	context-&gt;argv[1]    = a2;
@@ -849,13 +862,13 @@ void audit_syscall_entry(struct task_str
  * filtering, or because some other part of the kernel write an audit
  * message), then write out the syscall information.  In call cases,
  * free the names stored from getname(). */
-void audit_syscall_exit(struct task_struct *tsk, int return_code)
+void audit_syscall_exit(struct task_struct *tsk, int valid, long return_code)
 {
 	struct audit_context *context;
 
 	get_task_struct(tsk);
 	task_lock(tsk);
-	context = audit_get_context(tsk, 1, return_code);
+	context = audit_get_context(tsk, valid, return_code);
 	task_unlock(tsk);
 
 	/* Not having a context here is ok, since the parent may have
@@ -868,6 +881,7 @@ void audit_syscall_exit(struct task_stru
 
 	context-&gt;in_syscall = 0;
 	context-&gt;auditable  = 0;
+
 	if (context-&gt;previous) {
 		struct audit_context *new_context = context-&gt;previous;
 		context-&gt;previous  = NULL;
@@ -981,7 +995,7 @@ void audit_inode(const char *name, const
 }
 
 void audit_get_stamp(struct audit_context *ctx,
-		     struct timespec *t, int *serial)
+		     struct timespec *t, unsigned int *serial)
 {
 	if (ctx) {
 		t-&gt;tv_sec  = ctx-&gt;ctime.tv_sec;
@@ -996,20 +1010,21 @@ void audit_get_stamp(struct audit_contex
 
 extern int audit_set_type(struct audit_buffer *ab, int type);
 
-int audit_set_loginuid(struct audit_context *ctx, uid_t loginuid)
+int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
 {
-	if (ctx) {
+	if (task-&gt;audit_context) {
 		struct audit_buffer *ab;
 
 		ab = audit_log_start(NULL);
 		if (ab) {
 			audit_log_format(ab, "login pid=%d uid=%u "
 				"old loginuid=%u new loginuid=%u",
-				ctx-&gt;pid, ctx-&gt;uid, ctx-&gt;loginuid, loginuid);
+				task-&gt;pid, task-&gt;uid, 
+				task-&gt;audit_context-&gt;loginuid, loginuid);
 			audit_set_type(ab, AUDIT_LOGIN);
 			audit_log_end(ab);
 		}
-		ctx-&gt;loginuid = loginuid;
+		task-&gt;audit_context-&gt;loginuid = loginuid;
 	}
 	return 0;
 }
diff -puN net/netlink/af_netlink.c~git-audit net/netlink/af_netlink.c
--- 25/net/netlink/af_netlink.c~git-audit	2005-05-04 16:42:14.000000000 -0700
+++ 25-akpm/net/netlink/af_netlink.c	2005-05-04 16:42:14.000000000 -0700
@@ -49,6 +49,8 @@
 #include &lt;linux/bitops.h&gt;
 #include &lt;linux/mm.h&gt;
 #include &lt;linux/types.h&gt;
+#include &lt;linux/audit.h&gt;
+
 #include &lt;net/sock.h&gt;
 #include &lt;net/scm.h&gt;
 
@@ -904,6 +906,7 @@ static int netlink_sendmsg(struct kiocb 
 	NETLINK_CB(skb).groups	= nlk-&gt;groups;
 	NETLINK_CB(skb).dst_pid = dst_pid;
 	NETLINK_CB(skb).dst_groups = dst_groups;
+	NETLINK_CB(skb).loginuid = audit_get_loginuid(current-&gt;audit_context);
 	memcpy(NETLINK_CREDS(skb), &amp;siocb-&gt;scm-&gt;creds, sizeof(struct ucred));
 
 	/* What can I do? Netlink is asynchronous, so that
_
</pre></body></html>