aboutsummaryrefslogtreecommitdiffstats
path: root/arch
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 /arch
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>
Diffstat (limited to 'arch')
-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
6 files changed, 79 insertions, 48 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))