diff options
-rw-r--r-- | arch/i386/kernel/ptrace.c | 19 | ||||
-rw-r--r-- | arch/ia64/kernel/ptrace.c | 21 | ||||
-rw-r--r-- | arch/mips/kernel/ptrace.c | 38 | ||||
-rw-r--r-- | arch/ppc64/kernel/ptrace.c | 15 | ||||
-rw-r--r-- | arch/s390/kernel/ptrace.c | 21 | ||||
-rw-r--r-- | arch/x86_64/kernel/ptrace.c | 13 | ||||
-rw-r--r-- | include/linux/audit.h | 48 | ||||
-rw-r--r-- | kernel/auditsc.c | 22 |
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(®s)) | 1603 | long syscall; |
1604 | int arch; | ||
1605 | |||
1606 | if (IS_IA32_PROCESS(®s)) { | ||
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 | ||
303 | static 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 | */ |
307 | asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) | 326 | asmlinkage 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 | ||
305 | void do_syscall_trace_enter(struct pt_regs *regs) | 305 | void 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 | ||
317 | void do_syscall_trace_leave(struct pt_regs *regs) | 320 | void 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: | |||
711 | asmlinkage void | 711 | asmlinkage void |
712 | syscall_trace(struct pt_regs *regs, int entryexit) | 712 | syscall_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 | |||
632 | asmlinkage void syscall_trace_enter(struct pt_regs *regs) | 634 | asmlinkage 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 | ||
647 | asmlinkage void syscall_trace_leave(struct pt_regs *regs) | 650 | asmlinkage 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__ |
100 | struct audit_message { | 136 | struct audit_message { |
101 | struct nlmsghdr nlh; | 137 | struct nlmsghdr nlh; |
@@ -129,15 +165,19 @@ struct audit_buffer; | |||
129 | struct audit_context; | 165 | struct audit_context; |
130 | struct inode; | 166 | struct 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 */ |
135 | extern int audit_alloc(struct task_struct *task); | 175 | extern int audit_alloc(struct task_struct *task); |
136 | extern void audit_free(struct task_struct *task); | 176 | extern void audit_free(struct task_struct *task); |
137 | extern void audit_syscall_entry(struct task_struct *task, | 177 | extern 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); |
140 | extern void audit_syscall_exit(struct task_struct *task, int return_code); | 180 | extern void audit_syscall_exit(struct task_struct *task, int failed, long return_code); |
141 | extern void audit_getname(const char *name); | 181 | extern void audit_getname(const char *name); |
142 | extern void audit_putname(const char *name); | 182 | extern void audit_putname(const char *name); |
143 | extern void audit_inode(const char *name, const struct inode *inode); | 183 | extern 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). */ |
776 | void audit_syscall_entry(struct task_struct *tsk, int major, | 784 | void 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(). */ |
853 | void audit_syscall_exit(struct task_struct *tsk, int return_code) | 862 | void 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; |