diff options
author | Oleg Nesterov <oleg@redhat.com> | 2012-03-23 18:02:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 19:58:40 -0400 |
commit | 15cab952139404d0e593cb1aaab0a3547ac0f95b (patch) | |
tree | 0b8554db2eadd6782774e4448e43fb40dcc11c35 /include/linux/tracehook.h | |
parent | d533df07c20c7b59b0559a3ac38fb45c81ffd6bb (diff) |
ptrace: the killed tracee should not enter the syscall
Another old/known problem. If the tracee is killed after it reports
syscall_entry, it starts the syscall and debugger can't control this.
This confuses the users and this creates the security problems for
ptrace jailers.
Change tracehook_report_syscall_entry() to return non-zero if killed,
this instructs syscall_trace_enter() to abort the syscall.
Reported-by: Chris Evans <scarybeasts@gmail.com>
Tested-by: Indan Zupancic <indan@nul.nu>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Cc: Denys Vlasenko <vda.linux@googlemail.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Pedro Alves <palves@redhat.com>
Cc: Jan Kratochvil <jan.kratochvil@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux/tracehook.h')
-rw-r--r-- | include/linux/tracehook.h | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index a71a2927a6a0..51bd91d911c3 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h | |||
@@ -54,12 +54,12 @@ struct linux_binprm; | |||
54 | /* | 54 | /* |
55 | * ptrace report for syscall entry and exit looks identical. | 55 | * ptrace report for syscall entry and exit looks identical. |
56 | */ | 56 | */ |
57 | static inline void ptrace_report_syscall(struct pt_regs *regs) | 57 | static inline int ptrace_report_syscall(struct pt_regs *regs) |
58 | { | 58 | { |
59 | int ptrace = current->ptrace; | 59 | int ptrace = current->ptrace; |
60 | 60 | ||
61 | if (!(ptrace & PT_PTRACED)) | 61 | if (!(ptrace & PT_PTRACED)) |
62 | return; | 62 | return 0; |
63 | 63 | ||
64 | ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); | 64 | ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); |
65 | 65 | ||
@@ -72,6 +72,8 @@ static inline void ptrace_report_syscall(struct pt_regs *regs) | |||
72 | send_sig(current->exit_code, current, 1); | 72 | send_sig(current->exit_code, current, 1); |
73 | current->exit_code = 0; | 73 | current->exit_code = 0; |
74 | } | 74 | } |
75 | |||
76 | return fatal_signal_pending(current); | ||
75 | } | 77 | } |
76 | 78 | ||
77 | /** | 79 | /** |
@@ -96,8 +98,7 @@ static inline void ptrace_report_syscall(struct pt_regs *regs) | |||
96 | static inline __must_check int tracehook_report_syscall_entry( | 98 | static inline __must_check int tracehook_report_syscall_entry( |
97 | struct pt_regs *regs) | 99 | struct pt_regs *regs) |
98 | { | 100 | { |
99 | ptrace_report_syscall(regs); | 101 | return ptrace_report_syscall(regs); |
100 | return 0; | ||
101 | } | 102 | } |
102 | 103 | ||
103 | /** | 104 | /** |