aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Kleikamp <shaggy@austin.ibm.com>2005-05-05 15:43:19 -0400
committerDave Kleikamp <shaggy@austin.ibm.com>2005-05-05 15:43:19 -0400
commit6f817abc643ec84cf07c99f964d04976212e1fd3 (patch)
tree982d6e35796cf0c3c01899db1a8dc062d95c92c2
parentf77165df5ba75461b491a9f20f778307f1b4a0ac (diff)
parentbfd4bda097f8758d28e632ff2035e25577f6b060 (diff)
Merge with /home/shaggy/git/linus-clean/
-rw-r--r--arch/i386/kernel/ptrace.c19
-rw-r--r--arch/ia64/kernel/ptrace.c21
-rw-r--r--arch/mips/kernel/ptrace.c38
-rw-r--r--arch/ppc64/kernel/ptrace.c15
-rw-r--r--arch/s390/kernel/ptrace.c21
-rw-r--r--arch/um/kernel/ptrace.c21
-rw-r--r--arch/x86_64/kernel/ptrace.c21
-rw-r--r--fs/namei.c20
-rw-r--r--fs/proc/base.c2
-rw-r--r--include/asm-um/ptrace-i386.h2
-rw-r--r--include/asm-um/ptrace-x86_64.h2
-rw-r--r--include/asm-um/thread_info.h4
-rw-r--r--include/linux/audit.h64
-rw-r--r--include/linux/netlink.h1
-rw-r--r--init/Kconfig2
-rw-r--r--kernel/audit.c93
-rw-r--r--kernel/auditsc.c47
-rw-r--r--net/netlink/af_netlink.c3
18 files changed, 269 insertions, 127 deletions
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index e8c965ce86eb..e34f651fa13c 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -683,24 +683,18 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit)
683 /* do the secure computing check first */ 683 /* do the secure computing check first */
684 secure_computing(regs->orig_eax); 684 secure_computing(regs->orig_eax);
685 685
686 if (unlikely(current->audit_context)) { 686 if (unlikely(current->audit_context) && entryexit)
687 if (!entryexit) 687 audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax);
688 audit_syscall_entry(current, regs->orig_eax,
689 regs->ebx, regs->ecx,
690 regs->edx, regs->esi);
691 else
692 audit_syscall_exit(current, regs->eax);
693 }
694 688
695 if (!(current->ptrace & PT_PTRACED)) 689 if (!(current->ptrace & PT_PTRACED))
696 return; 690 goto out;
697 691
698 /* Fake a debug trap */ 692 /* Fake a debug trap */
699 if (test_thread_flag(TIF_SINGLESTEP)) 693 if (test_thread_flag(TIF_SINGLESTEP))
700 send_sigtrap(current, regs, 0); 694 send_sigtrap(current, regs, 0);
701 695
702 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 696 if (!test_thread_flag(TIF_SYSCALL_TRACE))
703 return; 697 goto out;
704 698
705 /* the 0x80 provides a way for the tracing parent to distinguish 699 /* the 0x80 provides a way for the tracing parent to distinguish
706 between a syscall stop and SIGTRAP delivery */ 700 between a syscall stop and SIGTRAP delivery */
@@ -715,4 +709,9 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit)
715 send_sig(current->exit_code, current, 1); 709 send_sig(current->exit_code, current, 1);
716 current->exit_code = 0; 710 current->exit_code = 0;
717 } 711 }
712 out:
713 if (unlikely(current->audit_context) && !entryexit)
714 audit_syscall_entry(current, AUDIT_ARCH_I386, regs->orig_eax,
715 regs->ebx, regs->ecx, regs->edx, regs->esi);
716
718} 717}
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index c253fd5914fc..907464ee7273 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -1596,20 +1596,25 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3,
1596 long arg4, long arg5, long arg6, long arg7, 1596 long arg4, long arg5, long arg6, long arg7,
1597 struct pt_regs regs) 1597 struct pt_regs regs)
1598{ 1598{
1599 long syscall; 1599 if (test_thread_flag(TIF_SYSCALL_TRACE)
1600 && (current->ptrace & PT_PTRACED))
1601 syscall_trace();
1600 1602
1601 if (unlikely(current->audit_context)) { 1603 if (unlikely(current->audit_context)) {
1602 if (IS_IA32_PROCESS(&regs)) 1604 long syscall;
1605 int arch;
1606
1607 if (IS_IA32_PROCESS(&regs)) {
1603 syscall = regs.r1; 1608 syscall = regs.r1;
1604 else 1609 arch = AUDIT_ARCH_I386;
1610 } else {
1605 syscall = regs.r15; 1611 syscall = regs.r15;
1612 arch = AUDIT_ARCH_IA64;
1613 }
1606 1614
1607 audit_syscall_entry(current, syscall, arg0, arg1, arg2, arg3); 1615 audit_syscall_entry(current, arch, syscall, arg0, arg1, arg2, arg3);
1608 } 1616 }
1609 1617
1610 if (test_thread_flag(TIF_SYSCALL_TRACE)
1611 && (current->ptrace & PT_PTRACED))
1612 syscall_trace();
1613} 1618}
1614 1619
1615/* "asmlinkage" so the input arguments are preserved... */ 1620/* "asmlinkage" so the input arguments are preserved... */
@@ -1620,7 +1625,7 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
1620 struct pt_regs regs) 1625 struct pt_regs regs)
1621{ 1626{
1622 if (unlikely(current->audit_context)) 1627 if (unlikely(current->audit_context))
1623 audit_syscall_exit(current, regs.r8); 1628 audit_syscall_exit(current, AUDITSC_RESULT(regs.r10), regs.r8);
1624 1629
1625 if (test_thread_flag(TIF_SYSCALL_TRACE) 1630 if (test_thread_flag(TIF_SYSCALL_TRACE)
1626 && (current->ptrace & PT_PTRACED)) 1631 && (current->ptrace & PT_PTRACED))
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index a2f899c2f4d4..92e70ca3bff9 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -301,25 +301,38 @@ out:
301 return ret; 301 return ret;
302} 302}
303 303
304static inline int audit_arch(void)
305{
306#ifdef CONFIG_CPU_LITTLE_ENDIAN
307#ifdef CONFIG_MIPS64
308 if (!(current->thread.mflags & MF_32BIT_REGS))
309 return AUDIT_ARCH_MIPSEL64;
310#endif /* MIPS64 */
311 return AUDIT_ARCH_MIPSEL;
312
313#else /* big endian... */
314#ifdef CONFIG_MIPS64
315 if (!(current->thread.mflags & MF_32BIT_REGS))
316 return AUDIT_ARCH_MIPS64;
317#endif /* MIPS64 */
318 return AUDIT_ARCH_MIPS;
319
320#endif /* endian */
321}
322
304/* 323/*
305 * Notification of system call entry/exit 324 * Notification of system call entry/exit
306 * - triggered by current->work.syscall_trace 325 * - triggered by current->work.syscall_trace
307 */ 326 */
308asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) 327asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
309{ 328{
310 if (unlikely(current->audit_context)) { 329 if (unlikely(current->audit_context) && entryexit)
311 if (!entryexit) 330 audit_syscall_exit(current, AUDITSC_RESULT(regs->regs[2]), regs->regs[2]);
312 audit_syscall_entry(current, regs->regs[2],
313 regs->regs[4], regs->regs[5],
314 regs->regs[6], regs->regs[7]);
315 else
316 audit_syscall_exit(current, regs->regs[2]);
317 }
318 331
319 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 332 if (!test_thread_flag(TIF_SYSCALL_TRACE))
320 return; 333 goto out;
321 if (!(current->ptrace & PT_PTRACED)) 334 if (!(current->ptrace & PT_PTRACED))
322 return; 335 goto out;
323 336
324 /* The 0x80 provides a way for the tracing parent to distinguish 337 /* The 0x80 provides a way for the tracing parent to distinguish
325 between a syscall stop and SIGTRAP delivery */ 338 between a syscall stop and SIGTRAP delivery */
@@ -335,4 +348,9 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
335 send_sig(current->exit_code, current, 1); 348 send_sig(current->exit_code, current, 1);
336 current->exit_code = 0; 349 current->exit_code = 0;
337 } 350 }
351 out:
352 if (unlikely(current->audit_context) && !entryexit)
353 audit_syscall_entry(current, audit_arch(), regs->regs[2],
354 regs->regs[4], regs->regs[5],
355 regs->regs[6], regs->regs[7]);
338} 356}
diff --git a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c
index 5a846324ca8c..9f8c6087ae56 100644
--- a/arch/ppc64/kernel/ptrace.c
+++ b/arch/ppc64/kernel/ptrace.c
@@ -305,14 +305,17 @@ static void do_syscall_trace(void)
305 305
306void do_syscall_trace_enter(struct pt_regs *regs) 306void do_syscall_trace_enter(struct pt_regs *regs)
307{ 307{
308 if (test_thread_flag(TIF_SYSCALL_TRACE)
309 && (current->ptrace & PT_PTRACED))
310 do_syscall_trace();
311
308 if (unlikely(current->audit_context)) 312 if (unlikely(current->audit_context))
309 audit_syscall_entry(current, regs->gpr[0], 313 audit_syscall_entry(current,
314 test_thread_flag(TIF_32BIT)?AUDIT_ARCH_PPC:AUDIT_ARCH_PPC64,
315 regs->gpr[0],
310 regs->gpr[3], regs->gpr[4], 316 regs->gpr[3], regs->gpr[4],
311 regs->gpr[5], regs->gpr[6]); 317 regs->gpr[5], regs->gpr[6]);
312 318
313 if (test_thread_flag(TIF_SYSCALL_TRACE)
314 && (current->ptrace & PT_PTRACED))
315 do_syscall_trace();
316} 319}
317 320
318void do_syscall_trace_leave(struct pt_regs *regs) 321void do_syscall_trace_leave(struct pt_regs *regs)
@@ -320,7 +323,9 @@ void do_syscall_trace_leave(struct pt_regs *regs)
320 secure_computing(regs->gpr[0]); 323 secure_computing(regs->gpr[0]);
321 324
322 if (unlikely(current->audit_context)) 325 if (unlikely(current->audit_context))
323 audit_syscall_exit(current, regs->result); 326 audit_syscall_exit(current,
327 (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
328 regs->result);
324 329
325 if ((test_thread_flag(TIF_SYSCALL_TRACE) 330 if ((test_thread_flag(TIF_SYSCALL_TRACE)
326 || test_thread_flag(TIF_SINGLESTEP)) 331 || test_thread_flag(TIF_SINGLESTEP))
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 9f0d73e3f5f7..26889366929a 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -712,18 +712,13 @@ out:
712asmlinkage void 712asmlinkage void
713syscall_trace(struct pt_regs *regs, int entryexit) 713syscall_trace(struct pt_regs *regs, int entryexit)
714{ 714{
715 if (unlikely(current->audit_context)) { 715 if (unlikely(current->audit_context) && entryexit)
716 if (!entryexit) 716 audit_syscall_exit(current, AUDITSC_RESULT(regs->gprs[2]), regs->gprs[2]);
717 audit_syscall_entry(current, regs->gprs[2], 717
718 regs->orig_gpr2, regs->gprs[3],
719 regs->gprs[4], regs->gprs[5]);
720 else
721 audit_syscall_exit(current, regs->gprs[2]);
722 }
723 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 718 if (!test_thread_flag(TIF_SYSCALL_TRACE))
724 return; 719 goto out;
725 if (!(current->ptrace & PT_PTRACED)) 720 if (!(current->ptrace & PT_PTRACED))
726 return; 721 goto out;
727 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) 722 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
728 ? 0x80 : 0)); 723 ? 0x80 : 0));
729 724
@@ -736,4 +731,10 @@ syscall_trace(struct pt_regs *regs, int entryexit)
736 send_sig(current->exit_code, current, 1); 731 send_sig(current->exit_code, current, 1);
737 current->exit_code = 0; 732 current->exit_code = 0;
738 } 733 }
734 out:
735 if (unlikely(current->audit_context) && !entryexit)
736 audit_syscall_entry(current,
737 test_thread_flag(TIF_31BIT)?AUDIT_ARCH_S390:AUDIT_ARCH_S390X,
738 regs->gprs[2], regs->orig_gpr2, regs->gprs[3],
739 regs->gprs[4], regs->gprs[5]);
739} 740}
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index e50e60ff5d27..959b2d2490df 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -337,15 +337,18 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit)
337 337
338 if (unlikely(current->audit_context)) { 338 if (unlikely(current->audit_context)) {
339 if (!entryexit) 339 if (!entryexit)
340 audit_syscall_entry(current, 340 audit_syscall_entry(current,
341 UPT_SYSCALL_NR(&regs->regs), 341 HOST_AUDIT_ARCH,
342 UPT_SYSCALL_ARG1(&regs->regs), 342 UPT_SYSCALL_NR(regs),
343 UPT_SYSCALL_ARG2(&regs->regs), 343 UPT_SYSCALL_ARG1(regs),
344 UPT_SYSCALL_ARG3(&regs->regs), 344 UPT_SYSCALL_ARG2(regs),
345 UPT_SYSCALL_ARG4(&regs->regs)); 345 UPT_SYSCALL_ARG3(regs),
346 else 346 UPT_SYSCALL_ARG4(regs));
347 audit_syscall_exit(current, 347 else {
348 UPT_SYSCALL_RET(&regs->regs)); 348 int res = UPT_SYSCALL_RET(regs);
349 audit_syscall_exit(current, AUDITSC_RESULT(res),
350 res);
351 }
349 } 352 }
350 353
351 /* Fake a debug trap */ 354 /* Fake a debug trap */
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
index c64b9c97c745..e26e86bb56fe 100644
--- a/arch/x86_64/kernel/ptrace.c
+++ b/arch/x86_64/kernel/ptrace.c
@@ -635,20 +635,29 @@ asmlinkage void syscall_trace_enter(struct pt_regs *regs)
635 /* do the secure computing check first */ 635 /* do the secure computing check first */
636 secure_computing(regs->orig_rax); 636 secure_computing(regs->orig_rax);
637 637
638 if (unlikely(current->audit_context))
639 audit_syscall_entry(current, regs->orig_rax,
640 regs->rdi, regs->rsi,
641 regs->rdx, regs->r10);
642
643 if (test_thread_flag(TIF_SYSCALL_TRACE) 638 if (test_thread_flag(TIF_SYSCALL_TRACE)
644 && (current->ptrace & PT_PTRACED)) 639 && (current->ptrace & PT_PTRACED))
645 syscall_trace(regs); 640 syscall_trace(regs);
641
642 if (unlikely(current->audit_context)) {
643 if (test_thread_flag(TIF_IA32)) {
644 audit_syscall_entry(current, AUDIT_ARCH_I386,
645 regs->orig_rax,
646 regs->rbx, regs->rcx,
647 regs->rdx, regs->rsi);
648 } else {
649 audit_syscall_entry(current, AUDIT_ARCH_X86_64,
650 regs->orig_rax,
651 regs->rdi, regs->rsi,
652 regs->rdx, regs->r10);
653 }
654 }
646} 655}
647 656
648asmlinkage void syscall_trace_leave(struct pt_regs *regs) 657asmlinkage void syscall_trace_leave(struct pt_regs *regs)
649{ 658{
650 if (unlikely(current->audit_context)) 659 if (unlikely(current->audit_context))
651 audit_syscall_exit(current, regs->rax); 660 audit_syscall_exit(current, AUDITSC_RESULT(regs->rax), regs->rax);
652 661
653 if ((test_thread_flag(TIF_SYSCALL_TRACE) 662 if ((test_thread_flag(TIF_SYSCALL_TRACE)
654 || test_thread_flag(TIF_SINGLESTEP)) 663 || test_thread_flag(TIF_SINGLESTEP))
diff --git a/fs/namei.c b/fs/namei.c
index 9e4aef2a1a21..0f76fd75591b 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -686,11 +686,11 @@ fail:
686 686
687/* 687/*
688 * Name resolution. 688 * Name resolution.
689 * This is the basic name resolution function, turning a pathname into
690 * the final dentry. We expect 'base' to be positive and a directory.
689 * 691 *
690 * This is the basic name resolution function, turning a pathname 692 * Returns 0 and nd will have valid dentry and mnt on success.
691 * into the final dentry. 693 * Returns error and drops reference to input namei data on failure.
692 *
693 * We expect 'base' to be positive and a directory.
694 */ 694 */
695static fastcall int __link_path_walk(const char * name, struct nameidata *nd) 695static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
696{ 696{
@@ -929,8 +929,10 @@ int fastcall path_walk(const char * name, struct nameidata *nd)
929 return link_path_walk(name, nd); 929 return link_path_walk(name, nd);
930} 930}
931 931
932/* SMP-safe */ 932/*
933/* returns 1 if everything is done */ 933 * SMP-safe: Returns 1 and nd will have valid dentry and mnt, if
934 * everything is done. Returns 0 and drops input nd, if lookup failed;
935 */
934static int __emul_lookup_dentry(const char *name, struct nameidata *nd) 936static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
935{ 937{
936 if (path_walk(name, nd)) 938 if (path_walk(name, nd))
@@ -994,9 +996,10 @@ set_it:
994 } 996 }
995} 997}
996 998
999/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
997int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata *nd) 1000int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata *nd)
998{ 1001{
999 int retval; 1002 int retval = 0;
1000 1003
1001 nd->last_type = LAST_ROOT; /* if there are only slashes... */ 1004 nd->last_type = LAST_ROOT; /* if there are only slashes... */
1002 nd->flags = flags; 1005 nd->flags = flags;
@@ -1009,7 +1012,7 @@ int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata
1009 nd->dentry = dget(current->fs->altroot); 1012 nd->dentry = dget(current->fs->altroot);
1010 read_unlock(&current->fs->lock); 1013 read_unlock(&current->fs->lock);
1011 if (__emul_lookup_dentry(name,nd)) 1014 if (__emul_lookup_dentry(name,nd))
1012 return 0; 1015 goto out; /* found in altroot */
1013 read_lock(&current->fs->lock); 1016 read_lock(&current->fs->lock);
1014 } 1017 }
1015 nd->mnt = mntget(current->fs->rootmnt); 1018 nd->mnt = mntget(current->fs->rootmnt);
@@ -1021,6 +1024,7 @@ int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata
1021 read_unlock(&current->fs->lock); 1024 read_unlock(&current->fs->lock);
1022 current->total_link_count = 0; 1025 current->total_link_count = 0;
1023 retval = link_path_walk(name, nd); 1026 retval = link_path_walk(name, nd);
1027out:
1024 if (unlikely(current->audit_context 1028 if (unlikely(current->audit_context
1025 && nd && nd->dentry && nd->dentry->d_inode)) 1029 && nd && nd->dentry && nd->dentry->d_inode))
1026 audit_inode(name, nd->dentry->d_inode); 1030 audit_inode(name, nd->dentry->d_inode);
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 07cafdf74ef2..e31903aadd96 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -820,7 +820,7 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
820 goto out_free_page; 820 goto out_free_page;
821 821
822 } 822 }
823 length = audit_set_loginuid(task->audit_context, loginuid); 823 length = audit_set_loginuid(task, loginuid);
824 if (likely(length == 0)) 824 if (likely(length == 0))
825 length = count; 825 length = count;
826 826
diff --git a/include/asm-um/ptrace-i386.h b/include/asm-um/ptrace-i386.h
index 9e47590ec293..04222f35c43e 100644
--- a/include/asm-um/ptrace-i386.h
+++ b/include/asm-um/ptrace-i386.h
@@ -6,6 +6,8 @@
6#ifndef __UM_PTRACE_I386_H 6#ifndef __UM_PTRACE_I386_H
7#define __UM_PTRACE_I386_H 7#define __UM_PTRACE_I386_H
8 8
9#define HOST_AUDIT_ARCH AUDIT_ARCH_I386
10
9#include "sysdep/ptrace.h" 11#include "sysdep/ptrace.h"
10#include "asm/ptrace-generic.h" 12#include "asm/ptrace-generic.h"
11 13
diff --git a/include/asm-um/ptrace-x86_64.h b/include/asm-um/ptrace-x86_64.h
index c34be39b78b2..be51219a8ffe 100644
--- a/include/asm-um/ptrace-x86_64.h
+++ b/include/asm-um/ptrace-x86_64.h
@@ -14,6 +14,8 @@
14#include "asm/ptrace-generic.h" 14#include "asm/ptrace-generic.h"
15#undef signal_fault 15#undef signal_fault
16 16
17#define HOST_AUDIT_ARCH AUDIT_ARCH_X86_64
18
17void signal_fault(struct pt_regs_subarch *regs, void *frame, char *where); 19void signal_fault(struct pt_regs_subarch *regs, void *frame, char *where);
18 20
19#define FS_BASE (21 * sizeof(unsigned long)) 21#define FS_BASE (21 * sizeof(unsigned long))
diff --git a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h
index bffb577bc54e..a10ea155907e 100644
--- a/include/asm-um/thread_info.h
+++ b/include/asm-um/thread_info.h
@@ -72,12 +72,14 @@ static inline struct thread_info *current_thread_info(void)
72 */ 72 */
73#define TIF_RESTART_BLOCK 4 73#define TIF_RESTART_BLOCK 4
74#define TIF_MEMDIE 5 74#define TIF_MEMDIE 5
75#define TIF_SYSCALL_AUDIT 6
75 76
76#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) 77#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
77#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) 78#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
78#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) 79#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
79#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) 80#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
80#define _TIF_RESTART_BLOCK (1 << TIF_RESTART_BLOCK) 81#define _TIF_MEMDIE (1 << TIF_MEMDIE)
82#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
81 83
82#endif 84#endif
83 85
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 3628f7cfb178..19f04b049798 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -1,4 +1,4 @@
1/* audit.h -- Auditing support -*- linux-c -*- 1/* audit.h -- Auditing support
2 * 2 *
3 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina. 3 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
4 * All Rights Reserved. 4 * All Rights Reserved.
@@ -24,6 +24,9 @@
24#ifndef _LINUX_AUDIT_H_ 24#ifndef _LINUX_AUDIT_H_
25#define _LINUX_AUDIT_H_ 25#define _LINUX_AUDIT_H_
26 26
27#include <linux/sched.h>
28#include <linux/elf.h>
29
27/* Request and reply types */ 30/* Request and reply types */
28#define AUDIT_GET 1000 /* Get status */ 31#define AUDIT_GET 1000 /* Get status */
29#define AUDIT_SET 1001 /* Set status (enable/disable/auditd) */ 32#define AUDIT_SET 1001 /* Set status (enable/disable/auditd) */
@@ -67,6 +70,7 @@
67#define AUDIT_FSGID 8 70#define AUDIT_FSGID 8
68#define AUDIT_LOGINUID 9 71#define AUDIT_LOGINUID 9
69#define AUDIT_PERS 10 72#define AUDIT_PERS 10
73#define AUDIT_ARCH 11
70 74
71 /* These are ONLY useful when checking 75 /* These are ONLY useful when checking
72 * at syscall exit time (AUDIT_AT_EXIT). */ 76 * at syscall exit time (AUDIT_AT_EXIT). */
@@ -96,6 +100,38 @@
96#define AUDIT_FAIL_PRINTK 1 100#define AUDIT_FAIL_PRINTK 1
97#define AUDIT_FAIL_PANIC 2 101#define AUDIT_FAIL_PANIC 2
98 102
103/* distinguish syscall tables */
104#define __AUDIT_ARCH_64BIT 0x80000000
105#define __AUDIT_ARCH_LE 0x40000000
106#define AUDIT_ARCH_ALPHA (EM_ALPHA|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
107#define AUDIT_ARCH_ARM (EM_ARM|__AUDIT_ARCH_LE)
108#define AUDIT_ARCH_ARMEB (EM_ARM)
109#define AUDIT_ARCH_CRIS (EM_CRIS|__AUDIT_ARCH_LE)
110#define AUDIT_ARCH_FRV (EM_FRV)
111#define AUDIT_ARCH_H8300 (EM_H8_300)
112#define AUDIT_ARCH_I386 (EM_386|__AUDIT_ARCH_LE)
113#define AUDIT_ARCH_IA64 (EM_IA_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
114#define AUDIT_ARCH_M32R (EM_M32R)
115#define AUDIT_ARCH_M68K (EM_68K)
116#define AUDIT_ARCH_MIPS (EM_MIPS)
117#define AUDIT_ARCH_MIPSEL (EM_MIPS|__AUDIT_ARCH_LE)
118#define AUDIT_ARCH_MIPS64 (EM_MIPS|__AUDIT_ARCH_64BIT)
119#define AUDIT_ARCH_MIPSEL64 (EM_MIPS|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
120#define AUDIT_ARCH_PARISC (EM_PARISC)
121#define AUDIT_ARCH_PARISC64 (EM_PARISC|__AUDIT_ARCH_64BIT)
122#define AUDIT_ARCH_PPC (EM_PPC)
123#define AUDIT_ARCH_PPC64 (EM_PPC64|__AUDIT_ARCH_64BIT)
124#define AUDIT_ARCH_S390 (EM_S390)
125#define AUDIT_ARCH_S390X (EM_S390|__AUDIT_ARCH_64BIT)
126#define AUDIT_ARCH_SH (EM_SH)
127#define AUDIT_ARCH_SHEL (EM_SH|__AUDIT_ARCH_LE)
128#define AUDIT_ARCH_SH64 (EM_SH|__AUDIT_ARCH_64BIT)
129#define AUDIT_ARCH_SHEL64 (EM_SH|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
130#define AUDIT_ARCH_SPARC (EM_SPARC)
131#define AUDIT_ARCH_SPARC64 (EM_SPARC64|__AUDIT_ARCH_64BIT)
132#define AUDIT_ARCH_V850 (EM_V850|__AUDIT_ARCH_LE)
133#define AUDIT_ARCH_X86_64 (EM_X86_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
134
99#ifndef __KERNEL__ 135#ifndef __KERNEL__
100struct audit_message { 136struct audit_message {
101 struct nlmsghdr nlh; 137 struct nlmsghdr nlh;
@@ -129,32 +165,36 @@ struct audit_buffer;
129struct audit_context; 165struct audit_context;
130struct inode; 166struct inode;
131 167
168#define AUDITSC_INVALID 0
169#define AUDITSC_SUCCESS 1
170#define AUDITSC_FAILURE 2
171#define AUDITSC_RESULT(x) ( ((long)(x))<0?AUDITSC_FAILURE:AUDITSC_SUCCESS )
132#ifdef CONFIG_AUDITSYSCALL 172#ifdef CONFIG_AUDITSYSCALL
133/* These are defined in auditsc.c */ 173/* These are defined in auditsc.c */
134 /* Public API */ 174 /* Public API */
135extern int audit_alloc(struct task_struct *task); 175extern int audit_alloc(struct task_struct *task);
136extern void audit_free(struct task_struct *task); 176extern void audit_free(struct task_struct *task);
137extern void audit_syscall_entry(struct task_struct *task, 177extern void audit_syscall_entry(struct task_struct *task, int arch,
138 int major, unsigned long a0, unsigned long a1, 178 int major, unsigned long a0, unsigned long a1,
139 unsigned long a2, unsigned long a3); 179 unsigned long a2, unsigned long a3);
140extern void audit_syscall_exit(struct task_struct *task, int return_code); 180extern void audit_syscall_exit(struct task_struct *task, int failed, long return_code);
141extern void audit_getname(const char *name); 181extern void audit_getname(const char *name);
142extern void audit_putname(const char *name); 182extern void audit_putname(const char *name);
143extern void audit_inode(const char *name, const struct inode *inode); 183extern void audit_inode(const char *name, const struct inode *inode);
144 184
145 /* Private API (for audit.c only) */ 185 /* Private API (for audit.c only) */
146extern int audit_receive_filter(int type, int pid, int uid, int seq, 186extern int audit_receive_filter(int type, int pid, int uid, int seq,
147 void *data); 187 void *data, uid_t loginuid);
148extern void audit_get_stamp(struct audit_context *ctx, 188extern void audit_get_stamp(struct audit_context *ctx,
149 struct timespec *t, int *serial); 189 struct timespec *t, unsigned int *serial);
150extern int audit_set_loginuid(struct audit_context *ctx, uid_t loginuid); 190extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid);
151extern uid_t audit_get_loginuid(struct audit_context *ctx); 191extern uid_t audit_get_loginuid(struct audit_context *ctx);
152extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode); 192extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
153#else 193#else
154#define audit_alloc(t) ({ 0; }) 194#define audit_alloc(t) ({ 0; })
155#define audit_free(t) do { ; } while (0) 195#define audit_free(t) do { ; } while (0)
156#define audit_syscall_entry(t,a,b,c,d,e) do { ; } while (0) 196#define audit_syscall_entry(t,ta,a,b,c,d,e) do { ; } while (0)
157#define audit_syscall_exit(t,r) do { ; } while (0) 197#define audit_syscall_exit(t,f,r) do { ; } while (0)
158#define audit_getname(n) do { ; } while (0) 198#define audit_getname(n) do { ; } while (0)
159#define audit_putname(n) do { ; } while (0) 199#define audit_putname(n) do { ; } while (0)
160#define audit_inode(n,i) do { ; } while (0) 200#define audit_inode(n,i) do { ; } while (0)
@@ -174,11 +214,15 @@ extern void audit_log_format(struct audit_buffer *ab,
174 const char *fmt, ...) 214 const char *fmt, ...)
175 __attribute__((format(printf,2,3))); 215 __attribute__((format(printf,2,3)));
176extern void audit_log_end(struct audit_buffer *ab); 216extern void audit_log_end(struct audit_buffer *ab);
217extern void audit_log_hex(struct audit_buffer *ab,
218 const unsigned char *buf,
219 size_t len);
220extern void audit_log_untrustedstring(struct audit_buffer *ab,
221 const char *string);
177extern void audit_log_d_path(struct audit_buffer *ab, 222extern void audit_log_d_path(struct audit_buffer *ab,
178 const char *prefix, 223 const char *prefix,
179 struct dentry *dentry, 224 struct dentry *dentry,
180 struct vfsmount *vfsmnt); 225 struct vfsmount *vfsmnt);
181
182 /* Private API (for auditsc.c only) */ 226 /* Private API (for auditsc.c only) */
183extern void audit_send_reply(int pid, int seq, int type, 227extern void audit_send_reply(int pid, int seq, int type,
184 int done, int multi, 228 int done, int multi,
@@ -190,6 +234,8 @@ extern void audit_log_lost(const char *message);
190#define audit_log_vformat(b,f,a) do { ; } while (0) 234#define audit_log_vformat(b,f,a) do { ; } while (0)
191#define audit_log_format(b,f,...) do { ; } while (0) 235#define audit_log_format(b,f,...) do { ; } while (0)
192#define audit_log_end(b) do { ; } while (0) 236#define audit_log_end(b) do { ; } while (0)
237#define audit_log_hex(a,b,l) do { ; } while (0)
238#define audit_log_untrustedstring(a,s) do { ; } while (0)
193#define audit_log_d_path(b,p,d,v) do { ; } while (0) 239#define audit_log_d_path(b,p,d,v) do { ; } while (0)
194#endif 240#endif
195#endif 241#endif
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index f731abdc1a29..b2738ac8bc99 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -110,6 +110,7 @@ struct netlink_skb_parms
110 __u32 dst_pid; 110 __u32 dst_pid;
111 __u32 dst_groups; 111 __u32 dst_groups;
112 kernel_cap_t eff_cap; 112 kernel_cap_t eff_cap;
113 __u32 loginuid; /* Login (audit) uid */
113}; 114};
114 115
115#define NETLINK_CB(skb) (*(struct netlink_skb_parms*)&((skb)->cb)) 116#define NETLINK_CB(skb) (*(struct netlink_skb_parms*)&((skb)->cb))
diff --git a/init/Kconfig b/init/Kconfig
index 40d286d1d118..d920baed109a 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -173,7 +173,7 @@ config AUDIT
173 173
174config AUDITSYSCALL 174config AUDITSYSCALL
175 bool "Enable system-call auditing support" 175 bool "Enable system-call auditing support"
176 depends on AUDIT && (X86 || PPC64 || ARCH_S390 || IA64) 176 depends on AUDIT && (X86 || PPC64 || ARCH_S390 || IA64 || UML)
177 default y if SECURITY_SELINUX 177 default y if SECURITY_SELINUX
178 help 178 help
179 Enable low-overhead system-call auditing infrastructure that 179 Enable low-overhead system-call auditing infrastructure that
diff --git a/kernel/audit.c b/kernel/audit.c
index ac26d4d960d3..9c4f1af0c794 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1,4 +1,4 @@
1/* audit.c -- Auditing support -*- linux-c -*- 1/* audit.c -- Auditing support
2 * Gateway between the kernel (e.g., selinux) and the user-space audit daemon. 2 * Gateway between the kernel (e.g., selinux) and the user-space audit daemon.
3 * System-call specific features have moved to auditsc.c 3 * System-call specific features have moved to auditsc.c
4 * 4 *
@@ -38,7 +38,7 @@
38 * 6) Support low-overhead kernel-based filtering to minimize the 38 * 6) Support low-overhead kernel-based filtering to minimize the
39 * information that must be passed to user-space. 39 * information that must be passed to user-space.
40 * 40 *
41 * Example user-space utilities: http://people.redhat.com/faith/audit/ 41 * Example user-space utilities: http://people.redhat.com/sgrubb/audit/
42 */ 42 */
43 43
44#include <linux/init.h> 44#include <linux/init.h>
@@ -142,7 +142,6 @@ struct audit_buffer {
142 int total; 142 int total;
143 int type; 143 int type;
144 int pid; 144 int pid;
145 int count; /* Times requeued */
146}; 145};
147 146
148void audit_set_type(struct audit_buffer *ab, int type) 147void audit_set_type(struct audit_buffer *ab, int type)
@@ -239,36 +238,36 @@ void audit_log_lost(const char *message)
239 238
240} 239}
241 240
242static int audit_set_rate_limit(int limit) 241static int audit_set_rate_limit(int limit, uid_t loginuid)
243{ 242{
244 int old = audit_rate_limit; 243 int old = audit_rate_limit;
245 audit_rate_limit = limit; 244 audit_rate_limit = limit;
246 audit_log(current->audit_context, "audit_rate_limit=%d old=%d", 245 audit_log(NULL, "audit_rate_limit=%d old=%d by auid %u",
247 audit_rate_limit, old); 246 audit_rate_limit, old, loginuid);
248 return old; 247 return old;
249} 248}
250 249
251static int audit_set_backlog_limit(int limit) 250static int audit_set_backlog_limit(int limit, uid_t loginuid)
252{ 251{
253 int old = audit_backlog_limit; 252 int old = audit_backlog_limit;
254 audit_backlog_limit = limit; 253 audit_backlog_limit = limit;
255 audit_log(current->audit_context, "audit_backlog_limit=%d old=%d", 254 audit_log(NULL, "audit_backlog_limit=%d old=%d by auid %u",
256 audit_backlog_limit, old); 255 audit_backlog_limit, old, loginuid);
257 return old; 256 return old;
258} 257}
259 258
260static int audit_set_enabled(int state) 259static int audit_set_enabled(int state, uid_t loginuid)
261{ 260{
262 int old = audit_enabled; 261 int old = audit_enabled;
263 if (state != 0 && state != 1) 262 if (state != 0 && state != 1)
264 return -EINVAL; 263 return -EINVAL;
265 audit_enabled = state; 264 audit_enabled = state;
266 audit_log(current->audit_context, "audit_enabled=%d old=%d", 265 audit_log(NULL, "audit_enabled=%d old=%d by auid %u",
267 audit_enabled, old); 266 audit_enabled, old, loginuid);
268 return old; 267 return old;
269} 268}
270 269
271static int audit_set_failure(int state) 270static int audit_set_failure(int state, uid_t loginuid)
272{ 271{
273 int old = audit_failure; 272 int old = audit_failure;
274 if (state != AUDIT_FAIL_SILENT 273 if (state != AUDIT_FAIL_SILENT
@@ -276,8 +275,8 @@ static int audit_set_failure(int state)
276 && state != AUDIT_FAIL_PANIC) 275 && state != AUDIT_FAIL_PANIC)
277 return -EINVAL; 276 return -EINVAL;
278 audit_failure = state; 277 audit_failure = state;
279 audit_log(current->audit_context, "audit_failure=%d old=%d", 278 audit_log(NULL, "audit_failure=%d old=%d by auid %u",
280 audit_failure, old); 279 audit_failure, old, loginuid);
281 return old; 280 return old;
282} 281}
283 282
@@ -344,6 +343,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
344 int err; 343 int err;
345 struct audit_buffer *ab; 344 struct audit_buffer *ab;
346 u16 msg_type = nlh->nlmsg_type; 345 u16 msg_type = nlh->nlmsg_type;
346 uid_t loginuid; /* loginuid of sender */
347 347
348 err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type); 348 err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type);
349 if (err) 349 if (err)
@@ -351,6 +351,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
351 351
352 pid = NETLINK_CREDS(skb)->pid; 352 pid = NETLINK_CREDS(skb)->pid;
353 uid = NETLINK_CREDS(skb)->uid; 353 uid = NETLINK_CREDS(skb)->uid;
354 loginuid = NETLINK_CB(skb).loginuid;
354 seq = nlh->nlmsg_seq; 355 seq = nlh->nlmsg_seq;
355 data = NLMSG_DATA(nlh); 356 data = NLMSG_DATA(nlh);
356 357
@@ -371,34 +372,36 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
371 return -EINVAL; 372 return -EINVAL;
372 status_get = (struct audit_status *)data; 373 status_get = (struct audit_status *)data;
373 if (status_get->mask & AUDIT_STATUS_ENABLED) { 374 if (status_get->mask & AUDIT_STATUS_ENABLED) {
374 err = audit_set_enabled(status_get->enabled); 375 err = audit_set_enabled(status_get->enabled, loginuid);
375 if (err < 0) return err; 376 if (err < 0) return err;
376 } 377 }
377 if (status_get->mask & AUDIT_STATUS_FAILURE) { 378 if (status_get->mask & AUDIT_STATUS_FAILURE) {
378 err = audit_set_failure(status_get->failure); 379 err = audit_set_failure(status_get->failure, loginuid);
379 if (err < 0) return err; 380 if (err < 0) return err;
380 } 381 }
381 if (status_get->mask & AUDIT_STATUS_PID) { 382 if (status_get->mask & AUDIT_STATUS_PID) {
382 int old = audit_pid; 383 int old = audit_pid;
383 audit_pid = status_get->pid; 384 audit_pid = status_get->pid;
384 audit_log(current->audit_context, 385 audit_log(NULL, "audit_pid=%d old=%d by auid %u",
385 "audit_pid=%d old=%d", audit_pid, old); 386 audit_pid, old, loginuid);
386 } 387 }
387 if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) 388 if (status_get->mask & AUDIT_STATUS_RATE_LIMIT)
388 audit_set_rate_limit(status_get->rate_limit); 389 audit_set_rate_limit(status_get->rate_limit, loginuid);
389 if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) 390 if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT)
390 audit_set_backlog_limit(status_get->backlog_limit); 391 audit_set_backlog_limit(status_get->backlog_limit,
392 loginuid);
391 break; 393 break;
392 case AUDIT_USER: 394 case AUDIT_USER:
393 ab = audit_log_start(NULL); 395 ab = audit_log_start(NULL);
394 if (!ab) 396 if (!ab)
395 break; /* audit_panic has been called */ 397 break; /* audit_panic has been called */
396 audit_log_format(ab, 398 audit_log_format(ab,
397 "user pid=%d uid=%d length=%d msg='%.1024s'", 399 "user pid=%d uid=%d length=%d loginuid=%u"
400 " msg='%.1024s'",
398 pid, uid, 401 pid, uid,
399 (int)(nlh->nlmsg_len 402 (int)(nlh->nlmsg_len
400 - ((char *)data - (char *)nlh)), 403 - ((char *)data - (char *)nlh)),
401 (char *)data); 404 loginuid, (char *)data);
402 ab->type = AUDIT_USER; 405 ab->type = AUDIT_USER;
403 ab->pid = pid; 406 ab->pid = pid;
404 audit_log_end(ab); 407 audit_log_end(ab);
@@ -411,7 +414,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
411 case AUDIT_LIST: 414 case AUDIT_LIST:
412#ifdef CONFIG_AUDITSYSCALL 415#ifdef CONFIG_AUDITSYSCALL
413 err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, 416 err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid,
414 uid, seq, data); 417 uid, seq, data, loginuid);
415#else 418#else
416 err = -EOPNOTSUPP; 419 err = -EOPNOTSUPP;
417#endif 420#endif
@@ -480,7 +483,7 @@ static void audit_log_move(struct audit_buffer *ab)
480 if (ab->len == 0) 483 if (ab->len == 0)
481 return; 484 return;
482 485
483 skb = skb_peek(&ab->sklist); 486 skb = skb_peek_tail(&ab->sklist);
484 if (!skb || skb_tailroom(skb) <= ab->len + extra) { 487 if (!skb || skb_tailroom(skb) <= ab->len + extra) {
485 skb = alloc_skb(2 * ab->len + extra, GFP_ATOMIC); 488 skb = alloc_skb(2 * ab->len + extra, GFP_ATOMIC);
486 if (!skb) { 489 if (!skb) {
@@ -519,9 +522,9 @@ static inline int audit_log_drain(struct audit_buffer *ab)
519 retval = netlink_unicast(audit_sock, skb, audit_pid, 522 retval = netlink_unicast(audit_sock, skb, audit_pid,
520 MSG_DONTWAIT); 523 MSG_DONTWAIT);
521 } 524 }
522 if (retval == -EAGAIN && ab->count < 5) { 525 if (retval == -EAGAIN &&
523 ++ab->count; 526 (atomic_read(&audit_backlog)) < audit_backlog_limit) {
524 skb_queue_tail(&ab->sklist, skb); 527 skb_queue_head(&ab->sklist, skb);
525 audit_log_end_irq(ab); 528 audit_log_end_irq(ab);
526 return 1; 529 return 1;
527 } 530 }
@@ -537,8 +540,8 @@ static inline int audit_log_drain(struct audit_buffer *ab)
537 if (!audit_pid) { /* No daemon */ 540 if (!audit_pid) { /* No daemon */
538 int offset = ab->nlh ? NLMSG_SPACE(0) : 0; 541 int offset = ab->nlh ? NLMSG_SPACE(0) : 0;
539 int len = skb->len - offset; 542 int len = skb->len - offset;
540 printk(KERN_ERR "%*.*s\n", 543 skb->data[offset + len] = '\0';
541 len, len, skb->data + offset); 544 printk(KERN_ERR "%s\n", skb->data + offset);
542 } 545 }
543 kfree_skb(skb); 546 kfree_skb(skb);
544 ab->nlh = NULL; 547 ab->nlh = NULL;
@@ -617,7 +620,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx)
617 struct audit_buffer *ab = NULL; 620 struct audit_buffer *ab = NULL;
618 unsigned long flags; 621 unsigned long flags;
619 struct timespec t; 622 struct timespec t;
620 int serial = 0; 623 unsigned int serial;
621 624
622 if (!audit_initialized) 625 if (!audit_initialized)
623 return NULL; 626 return NULL;
@@ -659,15 +662,16 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx)
659 ab->total = 0; 662 ab->total = 0;
660 ab->type = AUDIT_KERNEL; 663 ab->type = AUDIT_KERNEL;
661 ab->pid = 0; 664 ab->pid = 0;
662 ab->count = 0;
663 665
664#ifdef CONFIG_AUDITSYSCALL 666#ifdef CONFIG_AUDITSYSCALL
665 if (ab->ctx) 667 if (ab->ctx)
666 audit_get_stamp(ab->ctx, &t, &serial); 668 audit_get_stamp(ab->ctx, &t, &serial);
667 else 669 else
668#endif 670#endif
671 {
669 t = CURRENT_TIME; 672 t = CURRENT_TIME;
670 673 serial = 0;
674 }
671 audit_log_format(ab, "audit(%lu.%03lu:%u): ", 675 audit_log_format(ab, "audit(%lu.%03lu:%u): ",
672 t.tv_sec, t.tv_nsec/1000000, serial); 676 t.tv_sec, t.tv_nsec/1000000, serial);
673 return ab; 677 return ab;
@@ -717,6 +721,29 @@ void audit_log_format(struct audit_buffer *ab, const char *fmt, ...)
717 va_end(args); 721 va_end(args);
718} 722}
719 723
724void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, size_t len)
725{
726 int i;
727
728 for (i=0; i<len; i++)
729 audit_log_format(ab, "%02x", buf[i]);
730}
731
732void audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
733{
734 const unsigned char *p = string;
735
736 while (*p) {
737 if (*p == '"' || *p == ' ' || *p < 0x20 || *p > 0x7f) {
738 audit_log_hex(ab, string, strlen(string));
739 return;
740 }
741 p++;
742 }
743 audit_log_format(ab, "\"%s\"", string);
744}
745
746
720/* This is a helper-function to print the d_path without using a static 747/* This is a helper-function to print the d_path without using a static
721 * buffer or allocating another buffer in addition to the one in 748 * buffer or allocating another buffer in addition to the one in
722 * audit_buffer. */ 749 * audit_buffer. */
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 6f1931381bc9..37b3ac94bc47 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1,4 +1,4 @@
1/* auditsc.c -- System-call auditing support -*- linux-c -*- 1/* auditsc.c -- System-call auditing support
2 * Handles all system-call specific auditing features. 2 * Handles all system-call specific auditing features.
3 * 3 *
4 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina. 4 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
@@ -123,7 +123,7 @@ struct audit_context {
123 int major; /* syscall number */ 123 int major; /* syscall number */
124 unsigned long argv[4]; /* syscall arguments */ 124 unsigned long argv[4]; /* syscall arguments */
125 int return_valid; /* return code is valid */ 125 int return_valid; /* return code is valid */
126 int return_code;/* syscall return code */ 126 long return_code;/* syscall return code */
127 int auditable; /* 1 if record should be written */ 127 int auditable; /* 1 if record should be written */
128 int name_count; 128 int name_count;
129 struct audit_names names[AUDIT_NAMES]; 129 struct audit_names names[AUDIT_NAMES];
@@ -135,6 +135,7 @@ struct audit_context {
135 uid_t uid, euid, suid, fsuid; 135 uid_t uid, euid, suid, fsuid;
136 gid_t gid, egid, sgid, fsgid; 136 gid_t gid, egid, sgid, fsgid;
137 unsigned long personality; 137 unsigned long personality;
138 int arch;
138 139
139#if AUDIT_DEBUG 140#if AUDIT_DEBUG
140 int put_count; 141 int put_count;
@@ -250,7 +251,8 @@ static int audit_copy_rule(struct audit_rule *d, struct audit_rule *s)
250 return 0; 251 return 0;
251} 252}
252 253
253int audit_receive_filter(int type, int pid, int uid, int seq, void *data) 254int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
255 uid_t loginuid)
254{ 256{
255 u32 flags; 257 u32 flags;
256 struct audit_entry *entry; 258 struct audit_entry *entry;
@@ -285,6 +287,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data)
285 err = audit_add_rule(entry, &audit_entlist); 287 err = audit_add_rule(entry, &audit_entlist);
286 if (!err && (flags & AUDIT_AT_EXIT)) 288 if (!err && (flags & AUDIT_AT_EXIT))
287 err = audit_add_rule(entry, &audit_extlist); 289 err = audit_add_rule(entry, &audit_extlist);
290 audit_log(NULL, "auid %u added an audit rule\n", loginuid);
288 break; 291 break;
289 case AUDIT_DEL: 292 case AUDIT_DEL:
290 flags =((struct audit_rule *)data)->flags; 293 flags =((struct audit_rule *)data)->flags;
@@ -294,6 +297,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data)
294 err = audit_del_rule(data, &audit_entlist); 297 err = audit_del_rule(data, &audit_entlist);
295 if (!err && (flags & AUDIT_AT_EXIT)) 298 if (!err && (flags & AUDIT_AT_EXIT))
296 err = audit_del_rule(data, &audit_extlist); 299 err = audit_del_rule(data, &audit_extlist);
300 audit_log(NULL, "auid %u removed an audit rule\n", loginuid);
297 break; 301 break;
298 default: 302 default:
299 return -EINVAL; 303 return -EINVAL;
@@ -348,6 +352,10 @@ static int audit_filter_rules(struct task_struct *tsk,
348 case AUDIT_PERS: 352 case AUDIT_PERS:
349 result = (tsk->personality == value); 353 result = (tsk->personality == value);
350 break; 354 break;
355 case AUDIT_ARCH:
356 if (ctx)
357 result = (ctx->arch == value);
358 break;
351 359
352 case AUDIT_EXIT: 360 case AUDIT_EXIT:
353 if (ctx && ctx->return_valid) 361 if (ctx && ctx->return_valid)
@@ -355,7 +363,7 @@ static int audit_filter_rules(struct task_struct *tsk,
355 break; 363 break;
356 case AUDIT_SUCCESS: 364 case AUDIT_SUCCESS:
357 if (ctx && ctx->return_valid) 365 if (ctx && ctx->return_valid)
358 result = (ctx->return_code >= 0); 366 result = (ctx->return_valid == AUDITSC_SUCCESS);
359 break; 367 break;
360 case AUDIT_DEVMAJOR: 368 case AUDIT_DEVMAJOR:
361 if (ctx) { 369 if (ctx) {
@@ -648,8 +656,11 @@ static void audit_log_exit(struct audit_context *context)
648 audit_log_format(ab, "syscall=%d", context->major); 656 audit_log_format(ab, "syscall=%d", context->major);
649 if (context->personality != PER_LINUX) 657 if (context->personality != PER_LINUX)
650 audit_log_format(ab, " per=%lx", context->personality); 658 audit_log_format(ab, " per=%lx", context->personality);
659 audit_log_format(ab, " arch=%x", context->arch);
651 if (context->return_valid) 660 if (context->return_valid)
652 audit_log_format(ab, " exit=%d", context->return_code); 661 audit_log_format(ab, " success=%s exit=%ld",
662 (context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
663 context->return_code);
653 audit_log_format(ab, 664 audit_log_format(ab,
654 " a0=%lx a1=%lx a2=%lx a3=%lx items=%d" 665 " a0=%lx a1=%lx a2=%lx a3=%lx items=%d"
655 " pid=%d loginuid=%d uid=%d gid=%d" 666 " pid=%d loginuid=%d uid=%d gid=%d"
@@ -696,9 +707,10 @@ static void audit_log_exit(struct audit_context *context)
696 if (!ab) 707 if (!ab)
697 continue; /* audit_panic has been called */ 708 continue; /* audit_panic has been called */
698 audit_log_format(ab, "item=%d", i); 709 audit_log_format(ab, "item=%d", i);
699 if (context->names[i].name) 710 if (context->names[i].name) {
700 audit_log_format(ab, " name=%s", 711 audit_log_format(ab, " name=");
701 context->names[i].name); 712 audit_log_untrustedstring(ab, context->names[i].name);
713 }
702 if (context->names[i].ino != (unsigned long)-1) 714 if (context->names[i].ino != (unsigned long)-1)
703 audit_log_format(ab, " inode=%lu dev=%02x:%02x mode=%#o" 715 audit_log_format(ab, " inode=%lu dev=%02x:%02x mode=%#o"
704 " uid=%d gid=%d rdev=%02x:%02x", 716 " uid=%d gid=%d rdev=%02x:%02x",
@@ -772,7 +784,7 @@ static inline unsigned int audit_serial(void)
772 * then the record will be written at syscall exit time (otherwise, it 784 * then the record will be written at syscall exit time (otherwise, it
773 * will only be written if another part of the kernel requests that it 785 * will only be written if another part of the kernel requests that it
774 * be written). */ 786 * be written). */
775void audit_syscall_entry(struct task_struct *tsk, int major, 787void audit_syscall_entry(struct task_struct *tsk, int arch, int major,
776 unsigned long a1, unsigned long a2, 788 unsigned long a1, unsigned long a2,
777 unsigned long a3, unsigned long a4) 789 unsigned long a3, unsigned long a4)
778{ 790{
@@ -826,6 +838,7 @@ void audit_syscall_entry(struct task_struct *tsk, int major,
826 if (!audit_enabled) 838 if (!audit_enabled)
827 return; 839 return;
828 840
841 context->arch = arch;
829 context->major = major; 842 context->major = major;
830 context->argv[0] = a1; 843 context->argv[0] = a1;
831 context->argv[1] = a2; 844 context->argv[1] = a2;
@@ -849,13 +862,13 @@ void audit_syscall_entry(struct task_struct *tsk, int major,
849 * filtering, or because some other part of the kernel write an audit 862 * filtering, or because some other part of the kernel write an audit
850 * message), then write out the syscall information. In call cases, 863 * message), then write out the syscall information. In call cases,
851 * free the names stored from getname(). */ 864 * free the names stored from getname(). */
852void audit_syscall_exit(struct task_struct *tsk, int return_code) 865void audit_syscall_exit(struct task_struct *tsk, int valid, long return_code)
853{ 866{
854 struct audit_context *context; 867 struct audit_context *context;
855 868
856 get_task_struct(tsk); 869 get_task_struct(tsk);
857 task_lock(tsk); 870 task_lock(tsk);
858 context = audit_get_context(tsk, 1, return_code); 871 context = audit_get_context(tsk, valid, return_code);
859 task_unlock(tsk); 872 task_unlock(tsk);
860 873
861 /* Not having a context here is ok, since the parent may have 874 /* Not having a context here is ok, since the parent may have
@@ -868,6 +881,7 @@ void audit_syscall_exit(struct task_struct *tsk, int return_code)
868 881
869 context->in_syscall = 0; 882 context->in_syscall = 0;
870 context->auditable = 0; 883 context->auditable = 0;
884
871 if (context->previous) { 885 if (context->previous) {
872 struct audit_context *new_context = context->previous; 886 struct audit_context *new_context = context->previous;
873 context->previous = NULL; 887 context->previous = NULL;
@@ -981,7 +995,7 @@ void audit_inode(const char *name, const struct inode *inode)
981} 995}
982 996
983void audit_get_stamp(struct audit_context *ctx, 997void audit_get_stamp(struct audit_context *ctx,
984 struct timespec *t, int *serial) 998 struct timespec *t, unsigned int *serial)
985{ 999{
986 if (ctx) { 1000 if (ctx) {
987 t->tv_sec = ctx->ctime.tv_sec; 1001 t->tv_sec = ctx->ctime.tv_sec;
@@ -996,20 +1010,21 @@ void audit_get_stamp(struct audit_context *ctx,
996 1010
997extern int audit_set_type(struct audit_buffer *ab, int type); 1011extern int audit_set_type(struct audit_buffer *ab, int type);
998 1012
999int audit_set_loginuid(struct audit_context *ctx, uid_t loginuid) 1013int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
1000{ 1014{
1001 if (ctx) { 1015 if (task->audit_context) {
1002 struct audit_buffer *ab; 1016 struct audit_buffer *ab;
1003 1017
1004 ab = audit_log_start(NULL); 1018 ab = audit_log_start(NULL);
1005 if (ab) { 1019 if (ab) {
1006 audit_log_format(ab, "login pid=%d uid=%u " 1020 audit_log_format(ab, "login pid=%d uid=%u "
1007 "old loginuid=%u new loginuid=%u", 1021 "old loginuid=%u new loginuid=%u",
1008 ctx->pid, ctx->uid, ctx->loginuid, loginuid); 1022 task->pid, task->uid,
1023 task->audit_context->loginuid, loginuid);
1009 audit_set_type(ab, AUDIT_LOGIN); 1024 audit_set_type(ab, AUDIT_LOGIN);
1010 audit_log_end(ab); 1025 audit_log_end(ab);
1011 } 1026 }
1012 ctx->loginuid = loginuid; 1027 task->audit_context->loginuid = loginuid;
1013 } 1028 }
1014 return 0; 1029 return 0;
1015} 1030}
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 4ee392066148..733bf52cef3e 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -49,6 +49,8 @@
49#include <linux/bitops.h> 49#include <linux/bitops.h>
50#include <linux/mm.h> 50#include <linux/mm.h>
51#include <linux/types.h> 51#include <linux/types.h>
52#include <linux/audit.h>
53
52#include <net/sock.h> 54#include <net/sock.h>
53#include <net/scm.h> 55#include <net/scm.h>
54 56
@@ -904,6 +906,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
904 NETLINK_CB(skb).groups = nlk->groups; 906 NETLINK_CB(skb).groups = nlk->groups;
905 NETLINK_CB(skb).dst_pid = dst_pid; 907 NETLINK_CB(skb).dst_pid = dst_pid;
906 NETLINK_CB(skb).dst_groups = dst_groups; 908 NETLINK_CB(skb).dst_groups = dst_groups;
909 NETLINK_CB(skb).loginuid = audit_get_loginuid(current->audit_context);
907 memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); 910 memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
908 911
909 /* What can I do? Netlink is asynchronous, so that 912 /* What can I do? Netlink is asynchronous, so that