Commit 22f30168d296dbb54a21ebad44c9d735bca6f67b
Committed by
Linus Torvalds
1 parent
34a35bddb9
Exists in
master
and in
40 other branches
tracehook: comment pasto fixes
Fix some pasto's in comments in the new linux/tracehook.h and asm-generic/syscall.h files. Reported-by: Wenji Huang <wenji.huang@oracle.com> Signed-off-by: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 2 changed files with 2 additions and 2 deletions Inline Diff
include/asm-generic/syscall.h
1 | /* | 1 | /* |
2 | * Access to user system call parameters and results | 2 | * Access to user system call parameters and results |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Red Hat, Inc. All rights reserved. | 4 | * Copyright (C) 2008 Red Hat, Inc. All rights reserved. |
5 | * | 5 | * |
6 | * This copyrighted material is made available to anyone wishing to use, | 6 | * This copyrighted material is made available to anyone wishing to use, |
7 | * modify, copy, or redistribute it subject to the terms and conditions | 7 | * modify, copy, or redistribute it subject to the terms and conditions |
8 | * of the GNU General Public License v.2. | 8 | * of the GNU General Public License v.2. |
9 | * | 9 | * |
10 | * This file is a stub providing documentation for what functions | 10 | * This file is a stub providing documentation for what functions |
11 | * asm-ARCH/syscall.h files need to define. Most arch definitions | 11 | * asm-ARCH/syscall.h files need to define. Most arch definitions |
12 | * will be simple inlines. | 12 | * will be simple inlines. |
13 | * | 13 | * |
14 | * All of these functions expect to be called with no locks, | 14 | * All of these functions expect to be called with no locks, |
15 | * and only when the caller is sure that the task of interest | 15 | * and only when the caller is sure that the task of interest |
16 | * cannot return to user mode while we are looking at it. | 16 | * cannot return to user mode while we are looking at it. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #ifndef _ASM_SYSCALL_H | 19 | #ifndef _ASM_SYSCALL_H |
20 | #define _ASM_SYSCALL_H 1 | 20 | #define _ASM_SYSCALL_H 1 |
21 | 21 | ||
22 | struct task_struct; | 22 | struct task_struct; |
23 | struct pt_regs; | 23 | struct pt_regs; |
24 | 24 | ||
25 | /** | 25 | /** |
26 | * syscall_get_nr - find what system call a task is executing | 26 | * syscall_get_nr - find what system call a task is executing |
27 | * @task: task of interest, must be blocked | 27 | * @task: task of interest, must be blocked |
28 | * @regs: task_pt_regs() of @task | 28 | * @regs: task_pt_regs() of @task |
29 | * | 29 | * |
30 | * If @task is executing a system call or is at system call | 30 | * If @task is executing a system call or is at system call |
31 | * tracing about to attempt one, returns the system call number. | 31 | * tracing about to attempt one, returns the system call number. |
32 | * If @task is not executing a system call, i.e. it's blocked | 32 | * If @task is not executing a system call, i.e. it's blocked |
33 | * inside the kernel for a fault or signal, returns -1. | 33 | * inside the kernel for a fault or signal, returns -1. |
34 | * | 34 | * |
35 | * It's only valid to call this when @task is known to be blocked. | 35 | * It's only valid to call this when @task is known to be blocked. |
36 | */ | 36 | */ |
37 | long syscall_get_nr(struct task_struct *task, struct pt_regs *regs); | 37 | long syscall_get_nr(struct task_struct *task, struct pt_regs *regs); |
38 | 38 | ||
39 | /** | 39 | /** |
40 | * syscall_rollback - roll back registers after an aborted system call | 40 | * syscall_rollback - roll back registers after an aborted system call |
41 | * @task: task of interest, must be in system call exit tracing | 41 | * @task: task of interest, must be in system call exit tracing |
42 | * @regs: task_pt_regs() of @task | 42 | * @regs: task_pt_regs() of @task |
43 | * | 43 | * |
44 | * It's only valid to call this when @task is stopped for system | 44 | * It's only valid to call this when @task is stopped for system |
45 | * call exit tracing (due to TIF_SYSCALL_TRACE or TIF_SYSCALL_AUDIT), | 45 | * call exit tracing (due to TIF_SYSCALL_TRACE or TIF_SYSCALL_AUDIT), |
46 | * after tracehook_report_syscall_entry() returned nonzero to prevent | 46 | * after tracehook_report_syscall_entry() returned nonzero to prevent |
47 | * the system call from taking place. | 47 | * the system call from taking place. |
48 | * | 48 | * |
49 | * This rolls back the register state in @regs so it's as if the | 49 | * This rolls back the register state in @regs so it's as if the |
50 | * system call instruction was a no-op. The registers containing | 50 | * system call instruction was a no-op. The registers containing |
51 | * the system call number and arguments are as they were before the | 51 | * the system call number and arguments are as they were before the |
52 | * system call instruction. This may not be the same as what the | 52 | * system call instruction. This may not be the same as what the |
53 | * register state looked like at system call entry tracing. | 53 | * register state looked like at system call entry tracing. |
54 | */ | 54 | */ |
55 | void syscall_rollback(struct task_struct *task, struct pt_regs *regs); | 55 | void syscall_rollback(struct task_struct *task, struct pt_regs *regs); |
56 | 56 | ||
57 | /** | 57 | /** |
58 | * syscall_get_error - check result of traced system call | 58 | * syscall_get_error - check result of traced system call |
59 | * @task: task of interest, must be blocked | 59 | * @task: task of interest, must be blocked |
60 | * @regs: task_pt_regs() of @task | 60 | * @regs: task_pt_regs() of @task |
61 | * | 61 | * |
62 | * Returns 0 if the system call succeeded, or -ERRORCODE if it failed. | 62 | * Returns 0 if the system call succeeded, or -ERRORCODE if it failed. |
63 | * | 63 | * |
64 | * It's only valid to call this when @task is stopped for tracing on exit | 64 | * It's only valid to call this when @task is stopped for tracing on exit |
65 | * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. | 65 | * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. |
66 | */ | 66 | */ |
67 | long syscall_get_error(struct task_struct *task, struct pt_regs *regs); | 67 | long syscall_get_error(struct task_struct *task, struct pt_regs *regs); |
68 | 68 | ||
69 | /** | 69 | /** |
70 | * syscall_get_return_value - get the return value of a traced system call | 70 | * syscall_get_return_value - get the return value of a traced system call |
71 | * @task: task of interest, must be blocked | 71 | * @task: task of interest, must be blocked |
72 | * @regs: task_pt_regs() of @task | 72 | * @regs: task_pt_regs() of @task |
73 | * | 73 | * |
74 | * Returns the return value of the successful system call. | 74 | * Returns the return value of the successful system call. |
75 | * This value is meaningless if syscall_get_error() returned nonzero. | 75 | * This value is meaningless if syscall_get_error() returned nonzero. |
76 | * | 76 | * |
77 | * It's only valid to call this when @task is stopped for tracing on exit | 77 | * It's only valid to call this when @task is stopped for tracing on exit |
78 | * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. | 78 | * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. |
79 | */ | 79 | */ |
80 | long syscall_get_return_value(struct task_struct *task, struct pt_regs *regs); | 80 | long syscall_get_return_value(struct task_struct *task, struct pt_regs *regs); |
81 | 81 | ||
82 | /** | 82 | /** |
83 | * syscall_set_return_value - change the return value of a traced system call | 83 | * syscall_set_return_value - change the return value of a traced system call |
84 | * @task: task of interest, must be blocked | 84 | * @task: task of interest, must be blocked |
85 | * @regs: task_pt_regs() of @task | 85 | * @regs: task_pt_regs() of @task |
86 | * @error: negative error code, or zero to indicate success | 86 | * @error: negative error code, or zero to indicate success |
87 | * @val: user return value if @error is zero | 87 | * @val: user return value if @error is zero |
88 | * | 88 | * |
89 | * This changes the results of the system call that user mode will see. | 89 | * This changes the results of the system call that user mode will see. |
90 | * If @error is zero, the user sees a successful system call with a | 90 | * If @error is zero, the user sees a successful system call with a |
91 | * return value of @val. If @error is nonzero, it's a negated errno | 91 | * return value of @val. If @error is nonzero, it's a negated errno |
92 | * code; the user sees a failed system call with this errno code. | 92 | * code; the user sees a failed system call with this errno code. |
93 | * | 93 | * |
94 | * It's only valid to call this when @task is stopped for tracing on exit | 94 | * It's only valid to call this when @task is stopped for tracing on exit |
95 | * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. | 95 | * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. |
96 | */ | 96 | */ |
97 | void syscall_set_return_value(struct task_struct *task, struct pt_regs *regs, | 97 | void syscall_set_return_value(struct task_struct *task, struct pt_regs *regs, |
98 | int error, long val); | 98 | int error, long val); |
99 | 99 | ||
100 | /** | 100 | /** |
101 | * syscall_get_arguments - extract system call parameter values | 101 | * syscall_get_arguments - extract system call parameter values |
102 | * @task: task of interest, must be blocked | 102 | * @task: task of interest, must be blocked |
103 | * @regs: task_pt_regs() of @task | 103 | * @regs: task_pt_regs() of @task |
104 | * @i: argument index [0,5] | 104 | * @i: argument index [0,5] |
105 | * @n: number of arguments; n+i must be [1,6]. | 105 | * @n: number of arguments; n+i must be [1,6]. |
106 | * @args: array filled with argument values | 106 | * @args: array filled with argument values |
107 | * | 107 | * |
108 | * Fetches @n arguments to the system call starting with the @i'th argument | 108 | * Fetches @n arguments to the system call starting with the @i'th argument |
109 | * (from 0 through 5). Argument @i is stored in @args[0], and so on. | 109 | * (from 0 through 5). Argument @i is stored in @args[0], and so on. |
110 | * An arch inline version is probably optimal when @i and @n are constants. | 110 | * An arch inline version is probably optimal when @i and @n are constants. |
111 | * | 111 | * |
112 | * It's only valid to call this when @task is stopped for tracing on | 112 | * It's only valid to call this when @task is stopped for tracing on |
113 | * entry to a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. | 113 | * entry to a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. |
114 | * It's invalid to call this with @i + @n > 6; we only support system calls | 114 | * It's invalid to call this with @i + @n > 6; we only support system calls |
115 | * taking up to 6 arguments. | 115 | * taking up to 6 arguments. |
116 | */ | 116 | */ |
117 | void syscall_get_arguments(struct task_struct *task, struct pt_regs *regs, | 117 | void syscall_get_arguments(struct task_struct *task, struct pt_regs *regs, |
118 | unsigned int i, unsigned int n, unsigned long *args); | 118 | unsigned int i, unsigned int n, unsigned long *args); |
119 | 119 | ||
120 | /** | 120 | /** |
121 | * syscall_set_arguments - change system call parameter value | 121 | * syscall_set_arguments - change system call parameter value |
122 | * @task: task of interest, must be in system call entry tracing | 122 | * @task: task of interest, must be in system call entry tracing |
123 | * @regs: task_pt_regs() of @task | 123 | * @regs: task_pt_regs() of @task |
124 | * @i: argument index [0,5] | 124 | * @i: argument index [0,5] |
125 | * @n: number of arguments; n+i must be [1,6]. | 125 | * @n: number of arguments; n+i must be [1,6]. |
126 | * @args: array of argument values to store | 126 | * @args: array of argument values to store |
127 | * | 127 | * |
128 | * Changes @n arguments to the system call starting with the @i'th argument. | 128 | * Changes @n arguments to the system call starting with the @i'th argument. |
129 | * @n'th argument to @val. Argument @i gets value @args[0], and so on. | 129 | * Argument @i gets value @args[0], and so on. |
130 | * An arch inline version is probably optimal when @i and @n are constants. | 130 | * An arch inline version is probably optimal when @i and @n are constants. |
131 | * | 131 | * |
132 | * It's only valid to call this when @task is stopped for tracing on | 132 | * It's only valid to call this when @task is stopped for tracing on |
133 | * entry to a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. | 133 | * entry to a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. |
134 | * It's invalid to call this with @i + @n > 6; we only support system calls | 134 | * It's invalid to call this with @i + @n > 6; we only support system calls |
135 | * taking up to 6 arguments. | 135 | * taking up to 6 arguments. |
136 | */ | 136 | */ |
137 | void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs, | 137 | void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs, |
138 | unsigned int i, unsigned int n, | 138 | unsigned int i, unsigned int n, |
139 | const unsigned long *args); | 139 | const unsigned long *args); |
140 | 140 | ||
141 | #endif /* _ASM_SYSCALL_H */ | 141 | #endif /* _ASM_SYSCALL_H */ |
142 | 142 |
include/linux/tracehook.h
1 | /* | 1 | /* |
2 | * Tracing hooks | 2 | * Tracing hooks |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Red Hat, Inc. All rights reserved. | 4 | * Copyright (C) 2008 Red Hat, Inc. All rights reserved. |
5 | * | 5 | * |
6 | * This copyrighted material is made available to anyone wishing to use, | 6 | * This copyrighted material is made available to anyone wishing to use, |
7 | * modify, copy, or redistribute it subject to the terms and conditions | 7 | * modify, copy, or redistribute it subject to the terms and conditions |
8 | * of the GNU General Public License v.2. | 8 | * of the GNU General Public License v.2. |
9 | * | 9 | * |
10 | * This file defines hook entry points called by core code where | 10 | * This file defines hook entry points called by core code where |
11 | * user tracing/debugging support might need to do something. These | 11 | * user tracing/debugging support might need to do something. These |
12 | * entry points are called tracehook_*(). Each hook declared below | 12 | * entry points are called tracehook_*(). Each hook declared below |
13 | * has a detailed kerneldoc comment giving the context (locking et | 13 | * has a detailed kerneldoc comment giving the context (locking et |
14 | * al) from which it is called, and the meaning of its return value. | 14 | * al) from which it is called, and the meaning of its return value. |
15 | * | 15 | * |
16 | * Each function here typically has only one call site, so it is ok | 16 | * Each function here typically has only one call site, so it is ok |
17 | * to have some nontrivial tracehook_*() inlines. In all cases, the | 17 | * to have some nontrivial tracehook_*() inlines. In all cases, the |
18 | * fast path when no tracing is enabled should be very short. | 18 | * fast path when no tracing is enabled should be very short. |
19 | * | 19 | * |
20 | * The purpose of this file and the tracehook_* layer is to consolidate | 20 | * The purpose of this file and the tracehook_* layer is to consolidate |
21 | * the interface that the kernel core and arch code uses to enable any | 21 | * the interface that the kernel core and arch code uses to enable any |
22 | * user debugging or tracing facility (such as ptrace). The interfaces | 22 | * user debugging or tracing facility (such as ptrace). The interfaces |
23 | * here are carefully documented so that maintainers of core and arch | 23 | * here are carefully documented so that maintainers of core and arch |
24 | * code do not need to think about the implementation details of the | 24 | * code do not need to think about the implementation details of the |
25 | * tracing facilities. Likewise, maintainers of the tracing code do not | 25 | * tracing facilities. Likewise, maintainers of the tracing code do not |
26 | * need to understand all the calling core or arch code in detail, just | 26 | * need to understand all the calling core or arch code in detail, just |
27 | * documented circumstances of each call, such as locking conditions. | 27 | * documented circumstances of each call, such as locking conditions. |
28 | * | 28 | * |
29 | * If the calling core code changes so that locking is different, then | 29 | * If the calling core code changes so that locking is different, then |
30 | * it is ok to change the interface documented here. The maintainer of | 30 | * it is ok to change the interface documented here. The maintainer of |
31 | * core code changing should notify the maintainers of the tracing code | 31 | * core code changing should notify the maintainers of the tracing code |
32 | * that they need to work out the change. | 32 | * that they need to work out the change. |
33 | * | 33 | * |
34 | * Some tracehook_*() inlines take arguments that the current tracing | 34 | * Some tracehook_*() inlines take arguments that the current tracing |
35 | * implementations might not necessarily use. These function signatures | 35 | * implementations might not necessarily use. These function signatures |
36 | * are chosen to pass in all the information that is on hand in the | 36 | * are chosen to pass in all the information that is on hand in the |
37 | * caller and might conceivably be relevant to a tracer, so that the | 37 | * caller and might conceivably be relevant to a tracer, so that the |
38 | * core code won't have to be updated when tracing adds more features. | 38 | * core code won't have to be updated when tracing adds more features. |
39 | * If a call site changes so that some of those parameters are no longer | 39 | * If a call site changes so that some of those parameters are no longer |
40 | * already on hand without extra work, then the tracehook_* interface | 40 | * already on hand without extra work, then the tracehook_* interface |
41 | * can change so there is no make-work burden on the core code. The | 41 | * can change so there is no make-work burden on the core code. The |
42 | * maintainer of core code changing should notify the maintainers of the | 42 | * maintainer of core code changing should notify the maintainers of the |
43 | * tracing code that they need to work out the change. | 43 | * tracing code that they need to work out the change. |
44 | */ | 44 | */ |
45 | 45 | ||
46 | #ifndef _LINUX_TRACEHOOK_H | 46 | #ifndef _LINUX_TRACEHOOK_H |
47 | #define _LINUX_TRACEHOOK_H 1 | 47 | #define _LINUX_TRACEHOOK_H 1 |
48 | 48 | ||
49 | #include <linux/sched.h> | 49 | #include <linux/sched.h> |
50 | #include <linux/ptrace.h> | 50 | #include <linux/ptrace.h> |
51 | #include <linux/security.h> | 51 | #include <linux/security.h> |
52 | struct linux_binprm; | 52 | struct linux_binprm; |
53 | 53 | ||
54 | /** | 54 | /** |
55 | * tracehook_expect_breakpoints - guess if task memory might be touched | 55 | * tracehook_expect_breakpoints - guess if task memory might be touched |
56 | * @task: current task, making a new mapping | 56 | * @task: current task, making a new mapping |
57 | * | 57 | * |
58 | * Return nonzero if @task is expected to want breakpoint insertion in | 58 | * Return nonzero if @task is expected to want breakpoint insertion in |
59 | * its memory at some point. A zero return is no guarantee it won't | 59 | * its memory at some point. A zero return is no guarantee it won't |
60 | * be done, but this is a hint that it's known to be likely. | 60 | * be done, but this is a hint that it's known to be likely. |
61 | * | 61 | * |
62 | * May be called with @task->mm->mmap_sem held for writing. | 62 | * May be called with @task->mm->mmap_sem held for writing. |
63 | */ | 63 | */ |
64 | static inline int tracehook_expect_breakpoints(struct task_struct *task) | 64 | static inline int tracehook_expect_breakpoints(struct task_struct *task) |
65 | { | 65 | { |
66 | return (task_ptrace(task) & PT_PTRACED) != 0; | 66 | return (task_ptrace(task) & PT_PTRACED) != 0; |
67 | } | 67 | } |
68 | 68 | ||
69 | /* | 69 | /* |
70 | * ptrace report for syscall entry and exit looks identical. | 70 | * ptrace report for syscall entry and exit looks identical. |
71 | */ | 71 | */ |
72 | static inline void ptrace_report_syscall(struct pt_regs *regs) | 72 | static inline void ptrace_report_syscall(struct pt_regs *regs) |
73 | { | 73 | { |
74 | int ptrace = task_ptrace(current); | 74 | int ptrace = task_ptrace(current); |
75 | 75 | ||
76 | if (!(ptrace & PT_PTRACED)) | 76 | if (!(ptrace & PT_PTRACED)) |
77 | return; | 77 | return; |
78 | 78 | ||
79 | ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); | 79 | ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); |
80 | 80 | ||
81 | /* | 81 | /* |
82 | * this isn't the same as continuing with a signal, but it will do | 82 | * this isn't the same as continuing with a signal, but it will do |
83 | * for normal use. strace only continues with a signal if the | 83 | * for normal use. strace only continues with a signal if the |
84 | * stopping signal is not SIGTRAP. -brl | 84 | * stopping signal is not SIGTRAP. -brl |
85 | */ | 85 | */ |
86 | if (current->exit_code) { | 86 | if (current->exit_code) { |
87 | send_sig(current->exit_code, current, 1); | 87 | send_sig(current->exit_code, current, 1); |
88 | current->exit_code = 0; | 88 | current->exit_code = 0; |
89 | } | 89 | } |
90 | } | 90 | } |
91 | 91 | ||
92 | /** | 92 | /** |
93 | * tracehook_report_syscall_entry - task is about to attempt a system call | 93 | * tracehook_report_syscall_entry - task is about to attempt a system call |
94 | * @regs: user register state of current task | 94 | * @regs: user register state of current task |
95 | * | 95 | * |
96 | * This will be called if %TIF_SYSCALL_TRACE has been set, when the | 96 | * This will be called if %TIF_SYSCALL_TRACE has been set, when the |
97 | * current task has just entered the kernel for a system call. | 97 | * current task has just entered the kernel for a system call. |
98 | * Full user register state is available here. Changing the values | 98 | * Full user register state is available here. Changing the values |
99 | * in @regs can affect the system call number and arguments to be tried. | 99 | * in @regs can affect the system call number and arguments to be tried. |
100 | * It is safe to block here, preventing the system call from beginning. | 100 | * It is safe to block here, preventing the system call from beginning. |
101 | * | 101 | * |
102 | * Returns zero normally, or nonzero if the calling arch code should abort | 102 | * Returns zero normally, or nonzero if the calling arch code should abort |
103 | * the system call. That must prevent normal entry so no system call is | 103 | * the system call. That must prevent normal entry so no system call is |
104 | * made. If @task ever returns to user mode after this, its register state | 104 | * made. If @task ever returns to user mode after this, its register state |
105 | * is unspecified, but should be something harmless like an %ENOSYS error | 105 | * is unspecified, but should be something harmless like an %ENOSYS error |
106 | * return. It should preserve enough information so that syscall_rollback() | 106 | * return. It should preserve enough information so that syscall_rollback() |
107 | * can work (see asm-generic/syscall.h). | 107 | * can work (see asm-generic/syscall.h). |
108 | * | 108 | * |
109 | * Called without locks, just after entering kernel mode. | 109 | * Called without locks, just after entering kernel mode. |
110 | */ | 110 | */ |
111 | static inline __must_check int tracehook_report_syscall_entry( | 111 | static inline __must_check int tracehook_report_syscall_entry( |
112 | struct pt_regs *regs) | 112 | struct pt_regs *regs) |
113 | { | 113 | { |
114 | ptrace_report_syscall(regs); | 114 | ptrace_report_syscall(regs); |
115 | return 0; | 115 | return 0; |
116 | } | 116 | } |
117 | 117 | ||
118 | /** | 118 | /** |
119 | * tracehook_report_syscall_exit - task has just finished a system call | 119 | * tracehook_report_syscall_exit - task has just finished a system call |
120 | * @regs: user register state of current task | 120 | * @regs: user register state of current task |
121 | * @step: nonzero if simulating single-step or block-step | 121 | * @step: nonzero if simulating single-step or block-step |
122 | * | 122 | * |
123 | * This will be called if %TIF_SYSCALL_TRACE has been set, when the | 123 | * This will be called if %TIF_SYSCALL_TRACE has been set, when the |
124 | * current task has just finished an attempted system call. Full | 124 | * current task has just finished an attempted system call. Full |
125 | * user register state is available here. It is safe to block here, | 125 | * user register state is available here. It is safe to block here, |
126 | * preventing signals from being processed. | 126 | * preventing signals from being processed. |
127 | * | 127 | * |
128 | * If @step is nonzero, this report is also in lieu of the normal | 128 | * If @step is nonzero, this report is also in lieu of the normal |
129 | * trap that would follow the system call instruction because | 129 | * trap that would follow the system call instruction because |
130 | * user_enable_block_step() or user_enable_single_step() was used. | 130 | * user_enable_block_step() or user_enable_single_step() was used. |
131 | * In this case, %TIF_SYSCALL_TRACE might not be set. | 131 | * In this case, %TIF_SYSCALL_TRACE might not be set. |
132 | * | 132 | * |
133 | * Called without locks, just before checking for pending signals. | 133 | * Called without locks, just before checking for pending signals. |
134 | */ | 134 | */ |
135 | static inline void tracehook_report_syscall_exit(struct pt_regs *regs, int step) | 135 | static inline void tracehook_report_syscall_exit(struct pt_regs *regs, int step) |
136 | { | 136 | { |
137 | ptrace_report_syscall(regs); | 137 | ptrace_report_syscall(regs); |
138 | } | 138 | } |
139 | 139 | ||
140 | /** | 140 | /** |
141 | * tracehook_unsafe_exec - check for exec declared unsafe due to tracing | 141 | * tracehook_unsafe_exec - check for exec declared unsafe due to tracing |
142 | * @task: current task doing exec | 142 | * @task: current task doing exec |
143 | * | 143 | * |
144 | * Return %LSM_UNSAFE_* bits applied to an exec because of tracing. | 144 | * Return %LSM_UNSAFE_* bits applied to an exec because of tracing. |
145 | * | 145 | * |
146 | * Called with task_lock() held on @task. | 146 | * Called with task_lock() held on @task. |
147 | */ | 147 | */ |
148 | static inline int tracehook_unsafe_exec(struct task_struct *task) | 148 | static inline int tracehook_unsafe_exec(struct task_struct *task) |
149 | { | 149 | { |
150 | int unsafe = 0; | 150 | int unsafe = 0; |
151 | int ptrace = task_ptrace(task); | 151 | int ptrace = task_ptrace(task); |
152 | if (ptrace & PT_PTRACED) { | 152 | if (ptrace & PT_PTRACED) { |
153 | if (ptrace & PT_PTRACE_CAP) | 153 | if (ptrace & PT_PTRACE_CAP) |
154 | unsafe |= LSM_UNSAFE_PTRACE_CAP; | 154 | unsafe |= LSM_UNSAFE_PTRACE_CAP; |
155 | else | 155 | else |
156 | unsafe |= LSM_UNSAFE_PTRACE; | 156 | unsafe |= LSM_UNSAFE_PTRACE; |
157 | } | 157 | } |
158 | return unsafe; | 158 | return unsafe; |
159 | } | 159 | } |
160 | 160 | ||
161 | /** | 161 | /** |
162 | * tracehook_tracer_task - return the task that is tracing the given task | 162 | * tracehook_tracer_task - return the task that is tracing the given task |
163 | * @tsk: task to consider | 163 | * @tsk: task to consider |
164 | * | 164 | * |
165 | * Returns NULL if noone is tracing @task, or the &struct task_struct | 165 | * Returns NULL if noone is tracing @task, or the &struct task_struct |
166 | * pointer to its tracer. | 166 | * pointer to its tracer. |
167 | * | 167 | * |
168 | * Must called under rcu_read_lock(). The pointer returned might be kept | 168 | * Must called under rcu_read_lock(). The pointer returned might be kept |
169 | * live only by RCU. During exec, this may be called with task_lock() | 169 | * live only by RCU. During exec, this may be called with task_lock() |
170 | * held on @task, still held from when tracehook_unsafe_exec() was called. | 170 | * held on @task, still held from when tracehook_unsafe_exec() was called. |
171 | */ | 171 | */ |
172 | static inline struct task_struct *tracehook_tracer_task(struct task_struct *tsk) | 172 | static inline struct task_struct *tracehook_tracer_task(struct task_struct *tsk) |
173 | { | 173 | { |
174 | if (task_ptrace(tsk) & PT_PTRACED) | 174 | if (task_ptrace(tsk) & PT_PTRACED) |
175 | return rcu_dereference(tsk->parent); | 175 | return rcu_dereference(tsk->parent); |
176 | return NULL; | 176 | return NULL; |
177 | } | 177 | } |
178 | 178 | ||
179 | /** | 179 | /** |
180 | * tracehook_report_exec - a successful exec was completed | 180 | * tracehook_report_exec - a successful exec was completed |
181 | * @fmt: &struct linux_binfmt that performed the exec | 181 | * @fmt: &struct linux_binfmt that performed the exec |
182 | * @bprm: &struct linux_binprm containing exec details | 182 | * @bprm: &struct linux_binprm containing exec details |
183 | * @regs: user-mode register state | 183 | * @regs: user-mode register state |
184 | * | 184 | * |
185 | * An exec just completed, we are shortly going to return to user mode. | 185 | * An exec just completed, we are shortly going to return to user mode. |
186 | * The freshly initialized register state can be seen and changed in @regs. | 186 | * The freshly initialized register state can be seen and changed in @regs. |
187 | * The name, file and other pointers in @bprm are still on hand to be | 187 | * The name, file and other pointers in @bprm are still on hand to be |
188 | * inspected, but will be freed as soon as this returns. | 188 | * inspected, but will be freed as soon as this returns. |
189 | * | 189 | * |
190 | * Called with no locks, but with some kernel resources held live | 190 | * Called with no locks, but with some kernel resources held live |
191 | * and a reference on @fmt->module. | 191 | * and a reference on @fmt->module. |
192 | */ | 192 | */ |
193 | static inline void tracehook_report_exec(struct linux_binfmt *fmt, | 193 | static inline void tracehook_report_exec(struct linux_binfmt *fmt, |
194 | struct linux_binprm *bprm, | 194 | struct linux_binprm *bprm, |
195 | struct pt_regs *regs) | 195 | struct pt_regs *regs) |
196 | { | 196 | { |
197 | if (!ptrace_event(PT_TRACE_EXEC, PTRACE_EVENT_EXEC, 0) && | 197 | if (!ptrace_event(PT_TRACE_EXEC, PTRACE_EVENT_EXEC, 0) && |
198 | unlikely(task_ptrace(current) & PT_PTRACED)) | 198 | unlikely(task_ptrace(current) & PT_PTRACED)) |
199 | send_sig(SIGTRAP, current, 0); | 199 | send_sig(SIGTRAP, current, 0); |
200 | } | 200 | } |
201 | 201 | ||
202 | /** | 202 | /** |
203 | * tracehook_report_exit - task has begun to exit | 203 | * tracehook_report_exit - task has begun to exit |
204 | * @exit_code: pointer to value destined for @current->exit_code | 204 | * @exit_code: pointer to value destined for @current->exit_code |
205 | * | 205 | * |
206 | * @exit_code points to the value passed to do_exit(), which tracing | 206 | * @exit_code points to the value passed to do_exit(), which tracing |
207 | * might change here. This is almost the first thing in do_exit(), | 207 | * might change here. This is almost the first thing in do_exit(), |
208 | * before freeing any resources or setting the %PF_EXITING flag. | 208 | * before freeing any resources or setting the %PF_EXITING flag. |
209 | * | 209 | * |
210 | * Called with no locks held. | 210 | * Called with no locks held. |
211 | */ | 211 | */ |
212 | static inline void tracehook_report_exit(long *exit_code) | 212 | static inline void tracehook_report_exit(long *exit_code) |
213 | { | 213 | { |
214 | ptrace_event(PT_TRACE_EXIT, PTRACE_EVENT_EXIT, *exit_code); | 214 | ptrace_event(PT_TRACE_EXIT, PTRACE_EVENT_EXIT, *exit_code); |
215 | } | 215 | } |
216 | 216 | ||
217 | /** | 217 | /** |
218 | * tracehook_prepare_clone - prepare for new child to be cloned | 218 | * tracehook_prepare_clone - prepare for new child to be cloned |
219 | * @clone_flags: %CLONE_* flags from clone/fork/vfork system call | 219 | * @clone_flags: %CLONE_* flags from clone/fork/vfork system call |
220 | * | 220 | * |
221 | * This is called before a new user task is to be cloned. | 221 | * This is called before a new user task is to be cloned. |
222 | * Its return value will be passed to tracehook_finish_clone(). | 222 | * Its return value will be passed to tracehook_finish_clone(). |
223 | * | 223 | * |
224 | * Called with no locks held. | 224 | * Called with no locks held. |
225 | */ | 225 | */ |
226 | static inline int tracehook_prepare_clone(unsigned clone_flags) | 226 | static inline int tracehook_prepare_clone(unsigned clone_flags) |
227 | { | 227 | { |
228 | if (clone_flags & CLONE_UNTRACED) | 228 | if (clone_flags & CLONE_UNTRACED) |
229 | return 0; | 229 | return 0; |
230 | 230 | ||
231 | if (clone_flags & CLONE_VFORK) { | 231 | if (clone_flags & CLONE_VFORK) { |
232 | if (current->ptrace & PT_TRACE_VFORK) | 232 | if (current->ptrace & PT_TRACE_VFORK) |
233 | return PTRACE_EVENT_VFORK; | 233 | return PTRACE_EVENT_VFORK; |
234 | } else if ((clone_flags & CSIGNAL) != SIGCHLD) { | 234 | } else if ((clone_flags & CSIGNAL) != SIGCHLD) { |
235 | if (current->ptrace & PT_TRACE_CLONE) | 235 | if (current->ptrace & PT_TRACE_CLONE) |
236 | return PTRACE_EVENT_CLONE; | 236 | return PTRACE_EVENT_CLONE; |
237 | } else if (current->ptrace & PT_TRACE_FORK) | 237 | } else if (current->ptrace & PT_TRACE_FORK) |
238 | return PTRACE_EVENT_FORK; | 238 | return PTRACE_EVENT_FORK; |
239 | 239 | ||
240 | return 0; | 240 | return 0; |
241 | } | 241 | } |
242 | 242 | ||
243 | /** | 243 | /** |
244 | * tracehook_finish_clone - new child created and being attached | 244 | * tracehook_finish_clone - new child created and being attached |
245 | * @child: new child task | 245 | * @child: new child task |
246 | * @clone_flags: %CLONE_* flags from clone/fork/vfork system call | 246 | * @clone_flags: %CLONE_* flags from clone/fork/vfork system call |
247 | * @trace: return value from tracehook_prepare_clone() | 247 | * @trace: return value from tracehook_prepare_clone() |
248 | * | 248 | * |
249 | * This is called immediately after adding @child to its parent's children list. | 249 | * This is called immediately after adding @child to its parent's children list. |
250 | * The @trace value is that returned by tracehook_prepare_clone(). | 250 | * The @trace value is that returned by tracehook_prepare_clone(). |
251 | * | 251 | * |
252 | * Called with current's siglock and write_lock_irq(&tasklist_lock) held. | 252 | * Called with current's siglock and write_lock_irq(&tasklist_lock) held. |
253 | */ | 253 | */ |
254 | static inline void tracehook_finish_clone(struct task_struct *child, | 254 | static inline void tracehook_finish_clone(struct task_struct *child, |
255 | unsigned long clone_flags, int trace) | 255 | unsigned long clone_flags, int trace) |
256 | { | 256 | { |
257 | ptrace_init_task(child, (clone_flags & CLONE_PTRACE) || trace); | 257 | ptrace_init_task(child, (clone_flags & CLONE_PTRACE) || trace); |
258 | } | 258 | } |
259 | 259 | ||
260 | /** | 260 | /** |
261 | * tracehook_report_clone - in parent, new child is about to start running | 261 | * tracehook_report_clone - in parent, new child is about to start running |
262 | * @trace: return value from tracehook_prepare_clone() | 262 | * @trace: return value from tracehook_prepare_clone() |
263 | * @regs: parent's user register state | 263 | * @regs: parent's user register state |
264 | * @clone_flags: flags from parent's system call | 264 | * @clone_flags: flags from parent's system call |
265 | * @pid: new child's PID in the parent's namespace | 265 | * @pid: new child's PID in the parent's namespace |
266 | * @child: new child task | 266 | * @child: new child task |
267 | * | 267 | * |
268 | * Called after a child is set up, but before it has been started | 268 | * Called after a child is set up, but before it has been started |
269 | * running. @trace is the value returned by tracehook_prepare_clone(). | 269 | * running. @trace is the value returned by tracehook_prepare_clone(). |
270 | * This is not a good place to block, because the child has not started | 270 | * This is not a good place to block, because the child has not started |
271 | * yet. Suspend the child here if desired, and then block in | 271 | * yet. Suspend the child here if desired, and then block in |
272 | * tracehook_report_clone_complete(). This must prevent the child from | 272 | * tracehook_report_clone_complete(). This must prevent the child from |
273 | * self-reaping if tracehook_report_clone_complete() uses the @child | 273 | * self-reaping if tracehook_report_clone_complete() uses the @child |
274 | * pointer; otherwise it might have died and been released by the time | 274 | * pointer; otherwise it might have died and been released by the time |
275 | * tracehook_report_report_clone_complete() is called. | 275 | * tracehook_report_clone_complete() is called. |
276 | * | 276 | * |
277 | * Called with no locks held, but the child cannot run until this returns. | 277 | * Called with no locks held, but the child cannot run until this returns. |
278 | */ | 278 | */ |
279 | static inline void tracehook_report_clone(int trace, struct pt_regs *regs, | 279 | static inline void tracehook_report_clone(int trace, struct pt_regs *regs, |
280 | unsigned long clone_flags, | 280 | unsigned long clone_flags, |
281 | pid_t pid, struct task_struct *child) | 281 | pid_t pid, struct task_struct *child) |
282 | { | 282 | { |
283 | if (unlikely(trace) || unlikely(clone_flags & CLONE_PTRACE)) { | 283 | if (unlikely(trace) || unlikely(clone_flags & CLONE_PTRACE)) { |
284 | /* | 284 | /* |
285 | * The child starts up with an immediate SIGSTOP. | 285 | * The child starts up with an immediate SIGSTOP. |
286 | */ | 286 | */ |
287 | sigaddset(&child->pending.signal, SIGSTOP); | 287 | sigaddset(&child->pending.signal, SIGSTOP); |
288 | set_tsk_thread_flag(child, TIF_SIGPENDING); | 288 | set_tsk_thread_flag(child, TIF_SIGPENDING); |
289 | } | 289 | } |
290 | } | 290 | } |
291 | 291 | ||
292 | /** | 292 | /** |
293 | * tracehook_report_clone_complete - new child is running | 293 | * tracehook_report_clone_complete - new child is running |
294 | * @trace: return value from tracehook_prepare_clone() | 294 | * @trace: return value from tracehook_prepare_clone() |
295 | * @regs: parent's user register state | 295 | * @regs: parent's user register state |
296 | * @clone_flags: flags from parent's system call | 296 | * @clone_flags: flags from parent's system call |
297 | * @pid: new child's PID in the parent's namespace | 297 | * @pid: new child's PID in the parent's namespace |
298 | * @child: child task, already running | 298 | * @child: child task, already running |
299 | * | 299 | * |
300 | * This is called just after the child has started running. This is | 300 | * This is called just after the child has started running. This is |
301 | * just before the clone/fork syscall returns, or blocks for vfork | 301 | * just before the clone/fork syscall returns, or blocks for vfork |
302 | * child completion if @clone_flags has the %CLONE_VFORK bit set. | 302 | * child completion if @clone_flags has the %CLONE_VFORK bit set. |
303 | * The @child pointer may be invalid if a self-reaping child died and | 303 | * The @child pointer may be invalid if a self-reaping child died and |
304 | * tracehook_report_clone() took no action to prevent it from self-reaping. | 304 | * tracehook_report_clone() took no action to prevent it from self-reaping. |
305 | * | 305 | * |
306 | * Called with no locks held. | 306 | * Called with no locks held. |
307 | */ | 307 | */ |
308 | static inline void tracehook_report_clone_complete(int trace, | 308 | static inline void tracehook_report_clone_complete(int trace, |
309 | struct pt_regs *regs, | 309 | struct pt_regs *regs, |
310 | unsigned long clone_flags, | 310 | unsigned long clone_flags, |
311 | pid_t pid, | 311 | pid_t pid, |
312 | struct task_struct *child) | 312 | struct task_struct *child) |
313 | { | 313 | { |
314 | if (unlikely(trace)) | 314 | if (unlikely(trace)) |
315 | ptrace_event(0, trace, pid); | 315 | ptrace_event(0, trace, pid); |
316 | } | 316 | } |
317 | 317 | ||
318 | /** | 318 | /** |
319 | * tracehook_report_vfork_done - vfork parent's child has exited or exec'd | 319 | * tracehook_report_vfork_done - vfork parent's child has exited or exec'd |
320 | * @child: child task, already running | 320 | * @child: child task, already running |
321 | * @pid: new child's PID in the parent's namespace | 321 | * @pid: new child's PID in the parent's namespace |
322 | * | 322 | * |
323 | * Called after a %CLONE_VFORK parent has waited for the child to complete. | 323 | * Called after a %CLONE_VFORK parent has waited for the child to complete. |
324 | * The clone/vfork system call will return immediately after this. | 324 | * The clone/vfork system call will return immediately after this. |
325 | * The @child pointer may be invalid if a self-reaping child died and | 325 | * The @child pointer may be invalid if a self-reaping child died and |
326 | * tracehook_report_clone() took no action to prevent it from self-reaping. | 326 | * tracehook_report_clone() took no action to prevent it from self-reaping. |
327 | * | 327 | * |
328 | * Called with no locks held. | 328 | * Called with no locks held. |
329 | */ | 329 | */ |
330 | static inline void tracehook_report_vfork_done(struct task_struct *child, | 330 | static inline void tracehook_report_vfork_done(struct task_struct *child, |
331 | pid_t pid) | 331 | pid_t pid) |
332 | { | 332 | { |
333 | ptrace_event(PT_TRACE_VFORK_DONE, PTRACE_EVENT_VFORK_DONE, pid); | 333 | ptrace_event(PT_TRACE_VFORK_DONE, PTRACE_EVENT_VFORK_DONE, pid); |
334 | } | 334 | } |
335 | 335 | ||
336 | /** | 336 | /** |
337 | * tracehook_prepare_release_task - task is being reaped, clean up tracing | 337 | * tracehook_prepare_release_task - task is being reaped, clean up tracing |
338 | * @task: task in %EXIT_DEAD state | 338 | * @task: task in %EXIT_DEAD state |
339 | * | 339 | * |
340 | * This is called in release_task() just before @task gets finally reaped | 340 | * This is called in release_task() just before @task gets finally reaped |
341 | * and freed. This would be the ideal place to remove and clean up any | 341 | * and freed. This would be the ideal place to remove and clean up any |
342 | * tracing-related state for @task. | 342 | * tracing-related state for @task. |
343 | * | 343 | * |
344 | * Called with no locks held. | 344 | * Called with no locks held. |
345 | */ | 345 | */ |
346 | static inline void tracehook_prepare_release_task(struct task_struct *task) | 346 | static inline void tracehook_prepare_release_task(struct task_struct *task) |
347 | { | 347 | { |
348 | } | 348 | } |
349 | 349 | ||
350 | /** | 350 | /** |
351 | * tracehook_finish_release_task - final tracing clean-up | 351 | * tracehook_finish_release_task - final tracing clean-up |
352 | * @task: task in %EXIT_DEAD state | 352 | * @task: task in %EXIT_DEAD state |
353 | * | 353 | * |
354 | * This is called in release_task() when @task is being in the middle of | 354 | * This is called in release_task() when @task is being in the middle of |
355 | * being reaped. After this, there must be no tracing entanglements. | 355 | * being reaped. After this, there must be no tracing entanglements. |
356 | * | 356 | * |
357 | * Called with write_lock_irq(&tasklist_lock) held. | 357 | * Called with write_lock_irq(&tasklist_lock) held. |
358 | */ | 358 | */ |
359 | static inline void tracehook_finish_release_task(struct task_struct *task) | 359 | static inline void tracehook_finish_release_task(struct task_struct *task) |
360 | { | 360 | { |
361 | ptrace_release_task(task); | 361 | ptrace_release_task(task); |
362 | } | 362 | } |
363 | 363 | ||
364 | /** | 364 | /** |
365 | * tracehook_signal_handler - signal handler setup is complete | 365 | * tracehook_signal_handler - signal handler setup is complete |
366 | * @sig: number of signal being delivered | 366 | * @sig: number of signal being delivered |
367 | * @info: siginfo_t of signal being delivered | 367 | * @info: siginfo_t of signal being delivered |
368 | * @ka: sigaction setting that chose the handler | 368 | * @ka: sigaction setting that chose the handler |
369 | * @regs: user register state | 369 | * @regs: user register state |
370 | * @stepping: nonzero if debugger single-step or block-step in use | 370 | * @stepping: nonzero if debugger single-step or block-step in use |
371 | * | 371 | * |
372 | * Called by the arch code after a signal handler has been set up. | 372 | * Called by the arch code after a signal handler has been set up. |
373 | * Register and stack state reflects the user handler about to run. | 373 | * Register and stack state reflects the user handler about to run. |
374 | * Signal mask changes have already been made. | 374 | * Signal mask changes have already been made. |
375 | * | 375 | * |
376 | * Called without locks, shortly before returning to user mode | 376 | * Called without locks, shortly before returning to user mode |
377 | * (or handling more signals). | 377 | * (or handling more signals). |
378 | */ | 378 | */ |
379 | static inline void tracehook_signal_handler(int sig, siginfo_t *info, | 379 | static inline void tracehook_signal_handler(int sig, siginfo_t *info, |
380 | const struct k_sigaction *ka, | 380 | const struct k_sigaction *ka, |
381 | struct pt_regs *regs, int stepping) | 381 | struct pt_regs *regs, int stepping) |
382 | { | 382 | { |
383 | if (stepping) | 383 | if (stepping) |
384 | ptrace_notify(SIGTRAP); | 384 | ptrace_notify(SIGTRAP); |
385 | } | 385 | } |
386 | 386 | ||
387 | /** | 387 | /** |
388 | * tracehook_consider_ignored_signal - suppress short-circuit of ignored signal | 388 | * tracehook_consider_ignored_signal - suppress short-circuit of ignored signal |
389 | * @task: task receiving the signal | 389 | * @task: task receiving the signal |
390 | * @sig: signal number being sent | 390 | * @sig: signal number being sent |
391 | * @handler: %SIG_IGN or %SIG_DFL | 391 | * @handler: %SIG_IGN or %SIG_DFL |
392 | * | 392 | * |
393 | * Return zero iff tracing doesn't care to examine this ignored signal, | 393 | * Return zero iff tracing doesn't care to examine this ignored signal, |
394 | * so it can short-circuit normal delivery and never even get queued. | 394 | * so it can short-circuit normal delivery and never even get queued. |
395 | * Either @handler is %SIG_DFL and @sig's default is ignore, or it's %SIG_IGN. | 395 | * Either @handler is %SIG_DFL and @sig's default is ignore, or it's %SIG_IGN. |
396 | * | 396 | * |
397 | * Called with @task->sighand->siglock held. | 397 | * Called with @task->sighand->siglock held. |
398 | */ | 398 | */ |
399 | static inline int tracehook_consider_ignored_signal(struct task_struct *task, | 399 | static inline int tracehook_consider_ignored_signal(struct task_struct *task, |
400 | int sig, | 400 | int sig, |
401 | void __user *handler) | 401 | void __user *handler) |
402 | { | 402 | { |
403 | return (task_ptrace(task) & PT_PTRACED) != 0; | 403 | return (task_ptrace(task) & PT_PTRACED) != 0; |
404 | } | 404 | } |
405 | 405 | ||
406 | /** | 406 | /** |
407 | * tracehook_consider_fatal_signal - suppress special handling of fatal signal | 407 | * tracehook_consider_fatal_signal - suppress special handling of fatal signal |
408 | * @task: task receiving the signal | 408 | * @task: task receiving the signal |
409 | * @sig: signal number being sent | 409 | * @sig: signal number being sent |
410 | * @handler: %SIG_DFL or %SIG_IGN | 410 | * @handler: %SIG_DFL or %SIG_IGN |
411 | * | 411 | * |
412 | * Return nonzero to prevent special handling of this termination signal. | 412 | * Return nonzero to prevent special handling of this termination signal. |
413 | * Normally @handler is %SIG_DFL. It can be %SIG_IGN if @sig is ignored, | 413 | * Normally @handler is %SIG_DFL. It can be %SIG_IGN if @sig is ignored, |
414 | * in which case force_sig() is about to reset it to %SIG_DFL. | 414 | * in which case force_sig() is about to reset it to %SIG_DFL. |
415 | * When this returns zero, this signal might cause a quick termination | 415 | * When this returns zero, this signal might cause a quick termination |
416 | * that does not give the debugger a chance to intercept the signal. | 416 | * that does not give the debugger a chance to intercept the signal. |
417 | * | 417 | * |
418 | * Called with or without @task->sighand->siglock held. | 418 | * Called with or without @task->sighand->siglock held. |
419 | */ | 419 | */ |
420 | static inline int tracehook_consider_fatal_signal(struct task_struct *task, | 420 | static inline int tracehook_consider_fatal_signal(struct task_struct *task, |
421 | int sig, | 421 | int sig, |
422 | void __user *handler) | 422 | void __user *handler) |
423 | { | 423 | { |
424 | return (task_ptrace(task) & PT_PTRACED) != 0; | 424 | return (task_ptrace(task) & PT_PTRACED) != 0; |
425 | } | 425 | } |
426 | 426 | ||
427 | /** | 427 | /** |
428 | * tracehook_force_sigpending - let tracing force signal_pending(current) on | 428 | * tracehook_force_sigpending - let tracing force signal_pending(current) on |
429 | * | 429 | * |
430 | * Called when recomputing our signal_pending() flag. Return nonzero | 430 | * Called when recomputing our signal_pending() flag. Return nonzero |
431 | * to force the signal_pending() flag on, so that tracehook_get_signal() | 431 | * to force the signal_pending() flag on, so that tracehook_get_signal() |
432 | * will be called before the next return to user mode. | 432 | * will be called before the next return to user mode. |
433 | * | 433 | * |
434 | * Called with @current->sighand->siglock held. | 434 | * Called with @current->sighand->siglock held. |
435 | */ | 435 | */ |
436 | static inline int tracehook_force_sigpending(void) | 436 | static inline int tracehook_force_sigpending(void) |
437 | { | 437 | { |
438 | return 0; | 438 | return 0; |
439 | } | 439 | } |
440 | 440 | ||
441 | /** | 441 | /** |
442 | * tracehook_get_signal - deliver synthetic signal to traced task | 442 | * tracehook_get_signal - deliver synthetic signal to traced task |
443 | * @task: @current | 443 | * @task: @current |
444 | * @regs: task_pt_regs(@current) | 444 | * @regs: task_pt_regs(@current) |
445 | * @info: details of synthetic signal | 445 | * @info: details of synthetic signal |
446 | * @return_ka: sigaction for synthetic signal | 446 | * @return_ka: sigaction for synthetic signal |
447 | * | 447 | * |
448 | * Return zero to check for a real pending signal normally. | 448 | * Return zero to check for a real pending signal normally. |
449 | * Return -1 after releasing the siglock to repeat the check. | 449 | * Return -1 after releasing the siglock to repeat the check. |
450 | * Return a signal number to induce an artifical signal delivery, | 450 | * Return a signal number to induce an artifical signal delivery, |
451 | * setting *@info and *@return_ka to specify its details and behavior. | 451 | * setting *@info and *@return_ka to specify its details and behavior. |
452 | * | 452 | * |
453 | * The @return_ka->sa_handler value controls the disposition of the | 453 | * The @return_ka->sa_handler value controls the disposition of the |
454 | * signal, no matter the signal number. For %SIG_DFL, the return value | 454 | * signal, no matter the signal number. For %SIG_DFL, the return value |
455 | * is a representative signal to indicate the behavior (e.g. %SIGTERM | 455 | * is a representative signal to indicate the behavior (e.g. %SIGTERM |
456 | * for death, %SIGQUIT for core dump, %SIGSTOP for job control stop, | 456 | * for death, %SIGQUIT for core dump, %SIGSTOP for job control stop, |
457 | * %SIGTSTP for stop unless in an orphaned pgrp), but the signal number | 457 | * %SIGTSTP for stop unless in an orphaned pgrp), but the signal number |
458 | * reported will be @info->si_signo instead. | 458 | * reported will be @info->si_signo instead. |
459 | * | 459 | * |
460 | * Called with @task->sighand->siglock held, before dequeuing pending signals. | 460 | * Called with @task->sighand->siglock held, before dequeuing pending signals. |
461 | */ | 461 | */ |
462 | static inline int tracehook_get_signal(struct task_struct *task, | 462 | static inline int tracehook_get_signal(struct task_struct *task, |
463 | struct pt_regs *regs, | 463 | struct pt_regs *regs, |
464 | siginfo_t *info, | 464 | siginfo_t *info, |
465 | struct k_sigaction *return_ka) | 465 | struct k_sigaction *return_ka) |
466 | { | 466 | { |
467 | return 0; | 467 | return 0; |
468 | } | 468 | } |
469 | 469 | ||
470 | /** | 470 | /** |
471 | * tracehook_notify_jctl - report about job control stop/continue | 471 | * tracehook_notify_jctl - report about job control stop/continue |
472 | * @notify: nonzero if this is the last thread in the group to stop | 472 | * @notify: nonzero if this is the last thread in the group to stop |
473 | * @why: %CLD_STOPPED or %CLD_CONTINUED | 473 | * @why: %CLD_STOPPED or %CLD_CONTINUED |
474 | * | 474 | * |
475 | * This is called when we might call do_notify_parent_cldstop(). | 475 | * This is called when we might call do_notify_parent_cldstop(). |
476 | * It's called when about to stop for job control; we are already in | 476 | * It's called when about to stop for job control; we are already in |
477 | * %TASK_STOPPED state, about to call schedule(). It's also called when | 477 | * %TASK_STOPPED state, about to call schedule(). It's also called when |
478 | * a delayed %CLD_STOPPED or %CLD_CONTINUED report is ready to be made. | 478 | * a delayed %CLD_STOPPED or %CLD_CONTINUED report is ready to be made. |
479 | * | 479 | * |
480 | * Return nonzero to generate a %SIGCHLD with @why, which is | 480 | * Return nonzero to generate a %SIGCHLD with @why, which is |
481 | * normal if @notify is nonzero. | 481 | * normal if @notify is nonzero. |
482 | * | 482 | * |
483 | * Called with no locks held. | 483 | * Called with no locks held. |
484 | */ | 484 | */ |
485 | static inline int tracehook_notify_jctl(int notify, int why) | 485 | static inline int tracehook_notify_jctl(int notify, int why) |
486 | { | 486 | { |
487 | return notify || (current->ptrace & PT_PTRACED); | 487 | return notify || (current->ptrace & PT_PTRACED); |
488 | } | 488 | } |
489 | 489 | ||
490 | #define DEATH_REAP -1 | 490 | #define DEATH_REAP -1 |
491 | #define DEATH_DELAYED_GROUP_LEADER -2 | 491 | #define DEATH_DELAYED_GROUP_LEADER -2 |
492 | 492 | ||
493 | /** | 493 | /** |
494 | * tracehook_notify_death - task is dead, ready to notify parent | 494 | * tracehook_notify_death - task is dead, ready to notify parent |
495 | * @task: @current task now exiting | 495 | * @task: @current task now exiting |
496 | * @death_cookie: value to pass to tracehook_report_death() | 496 | * @death_cookie: value to pass to tracehook_report_death() |
497 | * @group_dead: nonzero if this was the last thread in the group to die | 497 | * @group_dead: nonzero if this was the last thread in the group to die |
498 | * | 498 | * |
499 | * A return value >= 0 means call do_notify_parent() with that signal | 499 | * A return value >= 0 means call do_notify_parent() with that signal |
500 | * number. Negative return value can be %DEATH_REAP to self-reap right | 500 | * number. Negative return value can be %DEATH_REAP to self-reap right |
501 | * now, or %DEATH_DELAYED_GROUP_LEADER to a zombie without notifying our | 501 | * now, or %DEATH_DELAYED_GROUP_LEADER to a zombie without notifying our |
502 | * parent. Note that a return value of 0 means a do_notify_parent() call | 502 | * parent. Note that a return value of 0 means a do_notify_parent() call |
503 | * that sends no signal, but still wakes up a parent blocked in wait*(). | 503 | * that sends no signal, but still wakes up a parent blocked in wait*(). |
504 | * | 504 | * |
505 | * Called with write_lock_irq(&tasklist_lock) held. | 505 | * Called with write_lock_irq(&tasklist_lock) held. |
506 | */ | 506 | */ |
507 | static inline int tracehook_notify_death(struct task_struct *task, | 507 | static inline int tracehook_notify_death(struct task_struct *task, |
508 | void **death_cookie, int group_dead) | 508 | void **death_cookie, int group_dead) |
509 | { | 509 | { |
510 | if (task->exit_signal == -1) | 510 | if (task->exit_signal == -1) |
511 | return task->ptrace ? SIGCHLD : DEATH_REAP; | 511 | return task->ptrace ? SIGCHLD : DEATH_REAP; |
512 | 512 | ||
513 | /* | 513 | /* |
514 | * If something other than our normal parent is ptracing us, then | 514 | * If something other than our normal parent is ptracing us, then |
515 | * send it a SIGCHLD instead of honoring exit_signal. exit_signal | 515 | * send it a SIGCHLD instead of honoring exit_signal. exit_signal |
516 | * only has special meaning to our real parent. | 516 | * only has special meaning to our real parent. |
517 | */ | 517 | */ |
518 | if (thread_group_empty(task) && !ptrace_reparented(task)) | 518 | if (thread_group_empty(task) && !ptrace_reparented(task)) |
519 | return task->exit_signal; | 519 | return task->exit_signal; |
520 | 520 | ||
521 | return task->ptrace ? SIGCHLD : DEATH_DELAYED_GROUP_LEADER; | 521 | return task->ptrace ? SIGCHLD : DEATH_DELAYED_GROUP_LEADER; |
522 | } | 522 | } |
523 | 523 | ||
524 | /** | 524 | /** |
525 | * tracehook_report_death - task is dead and ready to be reaped | 525 | * tracehook_report_death - task is dead and ready to be reaped |
526 | * @task: @current task now exiting | 526 | * @task: @current task now exiting |
527 | * @signal: return value from tracheook_notify_death() | 527 | * @signal: return value from tracheook_notify_death() |
528 | * @death_cookie: value passed back from tracehook_notify_death() | 528 | * @death_cookie: value passed back from tracehook_notify_death() |
529 | * @group_dead: nonzero if this was the last thread in the group to die | 529 | * @group_dead: nonzero if this was the last thread in the group to die |
530 | * | 530 | * |
531 | * Thread has just become a zombie or is about to self-reap. If positive, | 531 | * Thread has just become a zombie or is about to self-reap. If positive, |
532 | * @signal is the signal number just sent to the parent (usually %SIGCHLD). | 532 | * @signal is the signal number just sent to the parent (usually %SIGCHLD). |
533 | * If @signal is %DEATH_REAP, this thread will self-reap. If @signal is | 533 | * If @signal is %DEATH_REAP, this thread will self-reap. If @signal is |
534 | * %DEATH_DELAYED_GROUP_LEADER, this is a delayed_group_leader() zombie. | 534 | * %DEATH_DELAYED_GROUP_LEADER, this is a delayed_group_leader() zombie. |
535 | * The @death_cookie was passed back by tracehook_notify_death(). | 535 | * The @death_cookie was passed back by tracehook_notify_death(). |
536 | * | 536 | * |
537 | * If normal reaping is not inhibited, @task->exit_state might be changing | 537 | * If normal reaping is not inhibited, @task->exit_state might be changing |
538 | * in parallel. | 538 | * in parallel. |
539 | * | 539 | * |
540 | * Called without locks. | 540 | * Called without locks. |
541 | */ | 541 | */ |
542 | static inline void tracehook_report_death(struct task_struct *task, | 542 | static inline void tracehook_report_death(struct task_struct *task, |
543 | int signal, void *death_cookie, | 543 | int signal, void *death_cookie, |
544 | int group_dead) | 544 | int group_dead) |
545 | { | 545 | { |
546 | } | 546 | } |
547 | 547 | ||
548 | #ifdef TIF_NOTIFY_RESUME | 548 | #ifdef TIF_NOTIFY_RESUME |
549 | /** | 549 | /** |
550 | * set_notify_resume - cause tracehook_notify_resume() to be called | 550 | * set_notify_resume - cause tracehook_notify_resume() to be called |
551 | * @task: task that will call tracehook_notify_resume() | 551 | * @task: task that will call tracehook_notify_resume() |
552 | * | 552 | * |
553 | * Calling this arranges that @task will call tracehook_notify_resume() | 553 | * Calling this arranges that @task will call tracehook_notify_resume() |
554 | * before returning to user mode. If it's already running in user mode, | 554 | * before returning to user mode. If it's already running in user mode, |
555 | * it will enter the kernel and call tracehook_notify_resume() soon. | 555 | * it will enter the kernel and call tracehook_notify_resume() soon. |
556 | * If it's blocked, it will not be woken. | 556 | * If it's blocked, it will not be woken. |
557 | */ | 557 | */ |
558 | static inline void set_notify_resume(struct task_struct *task) | 558 | static inline void set_notify_resume(struct task_struct *task) |
559 | { | 559 | { |
560 | if (!test_and_set_tsk_thread_flag(task, TIF_NOTIFY_RESUME)) | 560 | if (!test_and_set_tsk_thread_flag(task, TIF_NOTIFY_RESUME)) |
561 | kick_process(task); | 561 | kick_process(task); |
562 | } | 562 | } |
563 | 563 | ||
564 | /** | 564 | /** |
565 | * tracehook_notify_resume - report when about to return to user mode | 565 | * tracehook_notify_resume - report when about to return to user mode |
566 | * @regs: user-mode registers of @current task | 566 | * @regs: user-mode registers of @current task |
567 | * | 567 | * |
568 | * This is called when %TIF_NOTIFY_RESUME has been set. Now we are | 568 | * This is called when %TIF_NOTIFY_RESUME has been set. Now we are |
569 | * about to return to user mode, and the user state in @regs can be | 569 | * about to return to user mode, and the user state in @regs can be |
570 | * inspected or adjusted. The caller in arch code has cleared | 570 | * inspected or adjusted. The caller in arch code has cleared |
571 | * %TIF_NOTIFY_RESUME before the call. If the flag gets set again | 571 | * %TIF_NOTIFY_RESUME before the call. If the flag gets set again |
572 | * asynchronously, this will be called again before we return to | 572 | * asynchronously, this will be called again before we return to |
573 | * user mode. | 573 | * user mode. |
574 | * | 574 | * |
575 | * Called without locks. | 575 | * Called without locks. |
576 | */ | 576 | */ |
577 | static inline void tracehook_notify_resume(struct pt_regs *regs) | 577 | static inline void tracehook_notify_resume(struct pt_regs *regs) |
578 | { | 578 | { |
579 | } | 579 | } |
580 | #endif /* TIF_NOTIFY_RESUME */ | 580 | #endif /* TIF_NOTIFY_RESUME */ |
581 | 581 | ||
582 | #endif /* <linux/tracehook.h> */ | 582 | #endif /* <linux/tracehook.h> */ |
583 | 583 |