aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/ptrace.c
diff options
context:
space:
mode:
authorAndrea Arcangeli <andrea@cpushare.com>2005-09-09 16:01:51 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 16:57:30 -0400
commit4c7fc7220f6a3cce9b3f4bd66362176df67df577 (patch)
tree5824a334335dcc283a76ffad6294ed0904364157 /arch/i386/kernel/ptrace.c
parent4d666d7ada2e14d71d463c85b8b5ef2e2e6723f2 (diff)
[PATCH] i386: seccomp fix for auditing/ptrace
This is the same issue as ppc64 before, when returning to userland we shouldn't re-compute the seccomp check or the task could be killed during sigreturn when orig_eax is overwritten by the sigreturn syscall. This was found by Roland. This was harmless from a security standpoint, but some i686 users reported failures with auditing enabled system wide (some distro surprisingly makes it the default) and I reproduced it too by keeping the whole workload under strace -f. Patch is tested and works for me under strace -f. nobody@athlon:~/cpushare> strace -o /tmp/o -f python seccomp_test.py make: Nothing to be done for `seccomp_test'. Starting computing some malicious bytecode init load start stop receive_data failure kill exit_code 0 signal 9 The malicious bytecode has been killed successfully by seccomp Starting computing some safe bytecode init load start stop 174 counts kill exit_code 0 signal 0 The seccomp_test.py completed successfully, thank you for testing. (akpm: collaterally cleaned up a bit of do_syscall_trace() too) Signed-off-by: Andrea Arcangeli <andrea@cpushare.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386/kernel/ptrace.c')
-rw-r--r--arch/i386/kernel/ptrace.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index 340980203b09..7b6368bf8974 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -694,17 +694,22 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
694__attribute__((regparm(3))) 694__attribute__((regparm(3)))
695int do_syscall_trace(struct pt_regs *regs, int entryexit) 695int do_syscall_trace(struct pt_regs *regs, int entryexit)
696{ 696{
697 int is_sysemu = test_thread_flag(TIF_SYSCALL_EMU), ret = 0; 697 int is_sysemu = test_thread_flag(TIF_SYSCALL_EMU);
698 /* With TIF_SYSCALL_EMU set we want to ignore TIF_SINGLESTEP for syscall 698 /*
699 * interception. */ 699 * With TIF_SYSCALL_EMU set we want to ignore TIF_SINGLESTEP for syscall
700 * interception
701 */
700 int is_singlestep = !is_sysemu && test_thread_flag(TIF_SINGLESTEP); 702 int is_singlestep = !is_sysemu && test_thread_flag(TIF_SINGLESTEP);
703 int ret = 0;
701 704
702 /* do the secure computing check first */ 705 /* do the secure computing check first */
703 secure_computing(regs->orig_eax); 706 if (!entryexit)
707 secure_computing(regs->orig_eax);
704 708
705 if (unlikely(current->audit_context)) { 709 if (unlikely(current->audit_context)) {
706 if (entryexit) 710 if (entryexit)
707 audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax); 711 audit_syscall_exit(current, AUDITSC_RESULT(regs->eax),
712 regs->eax);
708 /* Debug traps, when using PTRACE_SINGLESTEP, must be sent only 713 /* Debug traps, when using PTRACE_SINGLESTEP, must be sent only
709 * on the syscall exit path. Normally, when TIF_SYSCALL_AUDIT is 714 * on the syscall exit path. Normally, when TIF_SYSCALL_AUDIT is
710 * not used, entry.S will call us only on syscall exit, not 715 * not used, entry.S will call us only on syscall exit, not
@@ -738,7 +743,7 @@ int do_syscall_trace(struct pt_regs *regs, int entryexit)
738 /* the 0x80 provides a way for the tracing parent to distinguish 743 /* the 0x80 provides a way for the tracing parent to distinguish
739 between a syscall stop and SIGTRAP delivery */ 744 between a syscall stop and SIGTRAP delivery */
740 /* Note that the debugger could change the result of test_thread_flag!*/ 745 /* Note that the debugger could change the result of test_thread_flag!*/
741 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); 746 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80:0));
742 747
743 /* 748 /*
744 * this isn't the same as continuing with a signal, but it will do 749 * this isn't the same as continuing with a signal, but it will do
@@ -750,7 +755,7 @@ int do_syscall_trace(struct pt_regs *regs, int entryexit)
750 current->exit_code = 0; 755 current->exit_code = 0;
751 } 756 }
752 ret = is_sysemu; 757 ret = is_sysemu;
753 out: 758out:
754 if (unlikely(current->audit_context) && !entryexit) 759 if (unlikely(current->audit_context) && !entryexit)
755 audit_syscall_entry(current, AUDIT_ARCH_I386, regs->orig_eax, 760 audit_syscall_entry(current, AUDIT_ARCH_I386, regs->orig_eax,
756 regs->ebx, regs->ecx, regs->edx, regs->esi); 761 regs->ebx, regs->ecx, regs->edx, regs->esi);
@@ -759,6 +764,7 @@ int do_syscall_trace(struct pt_regs *regs, int entryexit)
759 764
760 regs->orig_eax = -1; /* force skip of syscall restarting */ 765 regs->orig_eax = -1; /* force skip of syscall restarting */
761 if (unlikely(current->audit_context)) 766 if (unlikely(current->audit_context))
762 audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax); 767 audit_syscall_exit(current, AUDITSC_RESULT(regs->eax),
768 regs->eax);
763 return 1; 769 return 1;
764} 770}