aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
author <dwmw2@shinybook.infradead.org>2005-04-29 11:08:28 -0400
committer <dwmw2@shinybook.infradead.org>2005-04-29 11:08:28 -0400
commit2fd6f58ba6efc82ea2c9c2630f7ff5ed9eeaf34a (patch)
tree87cf236a78ad242ae01f1b71c289131e6d1c0662
parentea3834d9fb348fb1144ad3affea22df933eaf62e (diff)
[AUDIT] Don't allow ptrace to fool auditing, log arch of audited syscalls.
We were calling ptrace_notify() after auditing the syscall and arguments, but the debugger could have _changed_ them before the syscall was actually invoked. Reorder the calls to fix that. While we're touching ever call to audit_syscall_entry(), we also make it take an extra argument: the architecture of the syscall which was made, because some architectures allow more than one type of syscall. Also add an explicit success/failure flag to audit_syscall_exit(), for the benefit of architectures which return that in a condition register rather than only returning a single register. Change type of syscall return value to 'long' not 'int'. Signed-off-by: David Woodhouse <dwmw2@infradead.org>
-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/x86_64/kernel/ptrace.c13
-rw-r--r--include/linux/audit.h48
-rw-r--r--kernel/auditsc.c22
8 files changed, 139 insertions, 58 deletions
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index b2f17640ceff..5606ec7a5c2b 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -682,24 +682,18 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit)
682 /* do the secure computing check first */ 682 /* do the secure computing check first */
683 secure_computing(regs->orig_eax); 683 secure_computing(regs->orig_eax);
684 684
685 if (unlikely(current->audit_context)) { 685 if (unlikely(current->audit_context) && entryexit)
686 if (!entryexit) 686 audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax);
687 audit_syscall_entry(current, regs->orig_eax,
688 regs->ebx, regs->ecx,
689 regs->edx, regs->esi);
690 else
691 audit_syscall_exit(current, regs->eax);
692 }
693 687
694 if (!(current->ptrace & PT_PTRACED)) 688 if (!(current->ptrace & PT_PTRACED))
695 return; 689 goto out;
696 690
697 /* Fake a debug trap */ 691 /* Fake a debug trap */
698 if (test_thread_flag(TIF_SINGLESTEP)) 692 if (test_thread_flag(TIF_SINGLESTEP))
699 send_sigtrap(current, regs, 0); 693 send_sigtrap(current, regs, 0);
700 694
701 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 695 if (!test_thread_flag(TIF_SYSCALL_TRACE))
702 return; 696 goto out;
703 697
704 /* the 0x80 provides a way for the tracing parent to distinguish 698 /* the 0x80 provides a way for the tracing parent to distinguish
705 between a syscall stop and SIGTRAP delivery */ 699 between a syscall stop and SIGTRAP delivery */
@@ -714,4 +708,9 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit)
714 send_sig(current->exit_code, current, 1); 708 send_sig(current->exit_code, current, 1);
715 current->exit_code = 0; 709 current->exit_code = 0;
716 } 710 }
711 out:
712 if (unlikely(current->audit_context) && !entryexit)
713 audit_syscall_entry(current, AUDIT_ARCH_I386, regs->orig_eax,
714 regs->ebx, regs->ecx, regs->edx, regs->esi);
715
717} 716}
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index 55789fcd7210..8dde0b16d4c8 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -1595,20 +1595,25 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3,
1595 long arg4, long arg5, long arg6, long arg7, 1595 long arg4, long arg5, long arg6, long arg7,
1596 struct pt_regs regs) 1596 struct pt_regs regs)
1597{ 1597{
1598 long syscall; 1598 if (test_thread_flag(TIF_SYSCALL_TRACE)
1599 && (current->ptrace & PT_PTRACED))
1600 syscall_trace();
1599 1601
1600 if (unlikely(current->audit_context)) { 1602 if (unlikely(current->audit_context)) {
1601 if (IS_IA32_PROCESS(&regs)) 1603 long syscall;
1604 int arch;
1605
1606 if (IS_IA32_PROCESS(&regs)) {
1602 syscall = regs.r1; 1607 syscall = regs.r1;
1603 else 1608 arch = AUDIT_ARCH_I386;
1609 } else {
1604 syscall = regs.r15; 1610 syscall = regs.r15;
1611 arch = AUDIT_ARCH_IA64;
1612 }
1605 1613
1606 audit_syscall_entry(current, syscall, arg0, arg1, arg2, arg3); 1614 audit_syscall_entry(current, arch, syscall, arg0, arg1, arg2, arg3);
1607 } 1615 }
1608 1616
1609 if (test_thread_flag(TIF_SYSCALL_TRACE)
1610 && (current->ptrace & PT_PTRACED))
1611 syscall_trace();
1612} 1617}
1613 1618
1614/* "asmlinkage" so the input arguments are preserved... */ 1619/* "asmlinkage" so the input arguments are preserved... */
@@ -1619,7 +1624,7 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
1619 struct pt_regs regs) 1624 struct pt_regs regs)
1620{ 1625{
1621 if (unlikely(current->audit_context)) 1626 if (unlikely(current->audit_context))
1622 audit_syscall_exit(current, regs.r8); 1627 audit_syscall_exit(current, AUDITSC_RESULT(regs.r10), regs.r8);
1623 1628
1624 if (test_thread_flag(TIF_SYSCALL_TRACE) 1629 if (test_thread_flag(TIF_SYSCALL_TRACE)
1625 && (current->ptrace & PT_PTRACED)) 1630 && (current->ptrace & PT_PTRACED))
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 92f2c39afe27..eaf7be9d0b0a 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -300,25 +300,38 @@ out:
300 return ret; 300 return ret;
301} 301}
302 302
303static inline int audit_arch()
304{
305#ifdef CONFIG_CPU_LITTLE_ENDIAN
306#ifdef CONFIG_MIPS64
307 if (!(current->thread.mflags & MF_32BIT_REGS))
308 return AUDIT_ARCH_MIPSEL64;
309#endif /* MIPS64 */
310 return AUDIT_ARCH_MIPSEL;
311
312#else /* big endian... */
313#ifdef CONFIG_MIPS64
314 if (!(current->thread.mflags & MF_32BIT_REGS))
315 return AUDIT_ARCH_MIPS64;
316#endif /* MIPS64 */
317 return AUDIT_ARCH_MIPS;
318
319#endif /* endian */
320}
321
303/* 322/*
304 * Notification of system call entry/exit 323 * Notification of system call entry/exit
305 * - triggered by current->work.syscall_trace 324 * - triggered by current->work.syscall_trace
306 */ 325 */
307asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) 326asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
308{ 327{
309 if (unlikely(current->audit_context)) { 328 if (unlikely(current->audit_context) && entryexit)
310 if (!entryexit) 329 audit_syscall_exit(current, AUDITSC_RESULT(regs->regs[2]), regs->regs[2]);
311 audit_syscall_entry(current, regs->regs[2],
312 regs->regs[4], regs->regs[5],
313 regs->regs[6], regs->regs[7]);
314 else
315 audit_syscall_exit(current, regs->regs[2]);
316 }
317 330
318 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 331 if (!test_thread_flag(TIF_SYSCALL_TRACE))
319 return; 332 goto out;
320 if (!(current->ptrace & PT_PTRACED)) 333 if (!(current->ptrace & PT_PTRACED))
321 return; 334 goto out;
322 335
323 /* The 0x80 provides a way for the tracing parent to distinguish 336 /* The 0x80 provides a way for the tracing parent to distinguish
324 between a syscall stop and SIGTRAP delivery */ 337 between a syscall stop and SIGTRAP delivery */
@@ -334,4 +347,9 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
334 send_sig(current->exit_code, current, 1); 347 send_sig(current->exit_code, current, 1);
335 current->exit_code = 0; 348 current->exit_code = 0;
336 } 349 }
350 out:
351 if (unlikely(current->audit_context) && !entryexit)
352 audit_syscall_entry(current, audit_arch(), regs->regs[2],
353 regs->regs[4], regs->regs[5],
354 regs->regs[6], regs->regs[7]);
337} 355}
diff --git a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c
index 354a287c67eb..3c76333ec3a9 100644
--- a/arch/ppc64/kernel/ptrace.c
+++ b/arch/ppc64/kernel/ptrace.c
@@ -304,14 +304,17 @@ static void do_syscall_trace(void)
304 304
305void do_syscall_trace_enter(struct pt_regs *regs) 305void do_syscall_trace_enter(struct pt_regs *regs)
306{ 306{
307 if (test_thread_flag(TIF_SYSCALL_TRACE)
308 && (current->ptrace & PT_PTRACED))
309 do_syscall_trace();
310
307 if (unlikely(current->audit_context)) 311 if (unlikely(current->audit_context))
308 audit_syscall_entry(current, regs->gpr[0], 312 audit_syscall_entry(current,
313 test_thread_flag(TIF_32BIT)?AUDIT_ARCH_PPC:AUDIT_ARCH_PPC64,
314 regs->gpr[0],
309 regs->gpr[3], regs->gpr[4], 315 regs->gpr[3], regs->gpr[4],
310 regs->gpr[5], regs->gpr[6]); 316 regs->gpr[5], regs->gpr[6]);
311 317
312 if (test_thread_flag(TIF_SYSCALL_TRACE)
313 && (current->ptrace & PT_PTRACED))
314 do_syscall_trace();
315} 318}
316 319
317void do_syscall_trace_leave(struct pt_regs *regs) 320void do_syscall_trace_leave(struct pt_regs *regs)
@@ -319,7 +322,9 @@ void do_syscall_trace_leave(struct pt_regs *regs)
319 secure_computing(regs->gpr[0]); 322 secure_computing(regs->gpr[0]);
320 323
321 if (unlikely(current->audit_context)) 324 if (unlikely(current->audit_context))
322 audit_syscall_exit(current, regs->result); 325 audit_syscall_exit(current,
326 (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
327 regs->result);
323 328
324 if ((test_thread_flag(TIF_SYSCALL_TRACE) 329 if ((test_thread_flag(TIF_SYSCALL_TRACE)
325 || test_thread_flag(TIF_SINGLESTEP)) 330 || test_thread_flag(TIF_SINGLESTEP))
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 647233c02fc8..2d546c67f7c3 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -711,18 +711,13 @@ out:
711asmlinkage void 711asmlinkage void
712syscall_trace(struct pt_regs *regs, int entryexit) 712syscall_trace(struct pt_regs *regs, int entryexit)
713{ 713{
714 if (unlikely(current->audit_context)) { 714 if (unlikely(current->audit_context) && entryexit)
715 if (!entryexit) 715 audit_syscall_exit(current, AUDITSC_RESULT(regs->gprs[2]), regs->gprs[2]);
716 audit_syscall_entry(current, regs->gprs[2], 716
717 regs->orig_gpr2, regs->gprs[3],
718 regs->gprs[4], regs->gprs[5]);
719 else
720 audit_syscall_exit(current, regs->gprs[2]);
721 }
722 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 717 if (!test_thread_flag(TIF_SYSCALL_TRACE))
723 return; 718 goto out;
724 if (!(current->ptrace & PT_PTRACED)) 719 if (!(current->ptrace & PT_PTRACED))
725 return; 720 goto out;
726 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) 721 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
727 ? 0x80 : 0)); 722 ? 0x80 : 0));
728 723
@@ -735,4 +730,10 @@ syscall_trace(struct pt_regs *regs, int entryexit)
735 send_sig(current->exit_code, current, 1); 730 send_sig(current->exit_code, current, 1);
736 current->exit_code = 0; 731 current->exit_code = 0;
737 } 732 }
733 out:
734 if (unlikely(current->audit_context) && !entryexit)
735 audit_syscall_entry(current,
736 test_thread_flag(TIF_31BIT)?AUDIT_ARCH_S390:AUDIT_ARCH_S390X,
737 regs->gprs[2], regs->orig_gpr2, regs->gprs[3],
738 regs->gprs[4], regs->gprs[5]);
738} 739}
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
index c7011675007d..ecbccbbf5c2a 100644
--- a/arch/x86_64/kernel/ptrace.c
+++ b/arch/x86_64/kernel/ptrace.c
@@ -629,25 +629,28 @@ static void syscall_trace(struct pt_regs *regs)
629 } 629 }
630} 630}
631 631
632#define audit_arch() (test_thread_flag(TIF_IA32) ? AUDIT_ARCH_I386 : AUDIT_ARCH_X86_64)
633
632asmlinkage void syscall_trace_enter(struct pt_regs *regs) 634asmlinkage void syscall_trace_enter(struct pt_regs *regs)
633{ 635{
634 /* do the secure computing check first */ 636 /* do the secure computing check first */
635 secure_computing(regs->orig_rax); 637 secure_computing(regs->orig_rax);
636 638
639 if (test_thread_flag(TIF_SYSCALL_TRACE)
640 && (current->ptrace & PT_PTRACED))
641 syscall_trace(regs);
642
637 if (unlikely(current->audit_context)) 643 if (unlikely(current->audit_context))
638 audit_syscall_entry(current, regs->orig_rax, 644 audit_syscall_entry(current, audit_arch(), regs->orig_rax,
639 regs->rdi, regs->rsi, 645 regs->rdi, regs->rsi,
640 regs->rdx, regs->r10); 646 regs->rdx, regs->r10);
641 647
642 if (test_thread_flag(TIF_SYSCALL_TRACE)
643 && (current->ptrace & PT_PTRACED))
644 syscall_trace(regs);
645} 648}
646 649
647asmlinkage void syscall_trace_leave(struct pt_regs *regs) 650asmlinkage void syscall_trace_leave(struct pt_regs *regs)
648{ 651{
649 if (unlikely(current->audit_context)) 652 if (unlikely(current->audit_context))
650 audit_syscall_exit(current, regs->rax); 653 audit_syscall_exit(current, AUDITSC_RESULT(regs->rax), regs->rax);
651 654
652 if ((test_thread_flag(TIF_SYSCALL_TRACE) 655 if ((test_thread_flag(TIF_SYSCALL_TRACE)
653 || test_thread_flag(TIF_SINGLESTEP)) 656 || test_thread_flag(TIF_SINGLESTEP))
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 9b77992c4888..fad0c1dc21a9 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -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,15 +165,19 @@ 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);
@@ -153,8 +193,8 @@ extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mo
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)
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 00e87ffff13b..77e92592de57 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -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;
@@ -348,6 +349,10 @@ static int audit_filter_rules(struct task_struct *tsk,
348 case AUDIT_PERS: 349 case AUDIT_PERS:
349 result = (tsk->personality == value); 350 result = (tsk->personality == value);
350 break; 351 break;
352 case AUDIT_ARCH:
353 if (ctx)
354 result = (ctx->arch == value);
355 break;
351 356
352 case AUDIT_EXIT: 357 case AUDIT_EXIT:
353 if (ctx && ctx->return_valid) 358 if (ctx && ctx->return_valid)
@@ -355,7 +360,7 @@ static int audit_filter_rules(struct task_struct *tsk,
355 break; 360 break;
356 case AUDIT_SUCCESS: 361 case AUDIT_SUCCESS:
357 if (ctx && ctx->return_valid) 362 if (ctx && ctx->return_valid)
358 result = (ctx->return_code >= 0); 363 result = (ctx->return_valid == AUDITSC_SUCCESS);
359 break; 364 break;
360 case AUDIT_DEVMAJOR: 365 case AUDIT_DEVMAJOR:
361 if (ctx) { 366 if (ctx) {
@@ -648,8 +653,11 @@ static void audit_log_exit(struct audit_context *context)
648 audit_log_format(ab, "syscall=%d", context->major); 653 audit_log_format(ab, "syscall=%d", context->major);
649 if (context->personality != PER_LINUX) 654 if (context->personality != PER_LINUX)
650 audit_log_format(ab, " per=%lx", context->personality); 655 audit_log_format(ab, " per=%lx", context->personality);
656 audit_log_format(ab, " arch=%x", context->arch);
651 if (context->return_valid) 657 if (context->return_valid)
652 audit_log_format(ab, " exit=%d", context->return_code); 658 audit_log_format(ab, " success=%s exit=%ld",
659 (context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
660 context->return_code);
653 audit_log_format(ab, 661 audit_log_format(ab,
654 " a0=%lx a1=%lx a2=%lx a3=%lx items=%d" 662 " a0=%lx a1=%lx a2=%lx a3=%lx items=%d"
655 " pid=%d loginuid=%d uid=%d gid=%d" 663 " pid=%d loginuid=%d uid=%d gid=%d"
@@ -773,7 +781,7 @@ static inline unsigned int audit_serial(void)
773 * then the record will be written at syscall exit time (otherwise, it 781 * then the record will be written at syscall exit time (otherwise, it
774 * will only be written if another part of the kernel requests that it 782 * will only be written if another part of the kernel requests that it
775 * be written). */ 783 * be written). */
776void audit_syscall_entry(struct task_struct *tsk, int major, 784void audit_syscall_entry(struct task_struct *tsk, int arch, int major,
777 unsigned long a1, unsigned long a2, 785 unsigned long a1, unsigned long a2,
778 unsigned long a3, unsigned long a4) 786 unsigned long a3, unsigned long a4)
779{ 787{
@@ -827,6 +835,7 @@ void audit_syscall_entry(struct task_struct *tsk, int major,
827 if (!audit_enabled) 835 if (!audit_enabled)
828 return; 836 return;
829 837
838 context->arch = arch;
830 context->major = major; 839 context->major = major;
831 context->argv[0] = a1; 840 context->argv[0] = a1;
832 context->argv[1] = a2; 841 context->argv[1] = a2;
@@ -850,13 +859,13 @@ void audit_syscall_entry(struct task_struct *tsk, int major,
850 * filtering, or because some other part of the kernel write an audit 859 * filtering, or because some other part of the kernel write an audit
851 * message), then write out the syscall information. In call cases, 860 * message), then write out the syscall information. In call cases,
852 * free the names stored from getname(). */ 861 * free the names stored from getname(). */
853void audit_syscall_exit(struct task_struct *tsk, int return_code) 862void audit_syscall_exit(struct task_struct *tsk, int valid, long return_code)
854{ 863{
855 struct audit_context *context; 864 struct audit_context *context;
856 865
857 get_task_struct(tsk); 866 get_task_struct(tsk);
858 task_lock(tsk); 867 task_lock(tsk);
859 context = audit_get_context(tsk, 1, return_code); 868 context = audit_get_context(tsk, valid, return_code);
860 task_unlock(tsk); 869 task_unlock(tsk);
861 870
862 /* Not having a context here is ok, since the parent may have 871 /* Not having a context here is ok, since the parent may have
@@ -869,6 +878,7 @@ void audit_syscall_exit(struct task_struct *tsk, int return_code)
869 878
870 context->in_syscall = 0; 879 context->in_syscall = 0;
871 context->auditable = 0; 880 context->auditable = 0;
881
872 if (context->previous) { 882 if (context->previous) {
873 struct audit_context *new_context = context->previous; 883 struct audit_context *new_context = context->previous;
874 context->previous = NULL; 884 context->previous = NULL;