aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/tracehook.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/tracehook.h')
-rw-r--r--include/linux/tracehook.h100
1 files changed, 100 insertions, 0 deletions
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
index 967ab473afbc..3ebc58b59766 100644
--- a/include/linux/tracehook.h
+++ b/include/linux/tracehook.h
@@ -110,4 +110,104 @@ static inline void tracehook_report_exit(long *exit_code)
110 ptrace_event(PT_TRACE_EXIT, PTRACE_EVENT_EXIT, *exit_code); 110 ptrace_event(PT_TRACE_EXIT, PTRACE_EVENT_EXIT, *exit_code);
111} 111}
112 112
113/**
114 * tracehook_prepare_clone - prepare for new child to be cloned
115 * @clone_flags: %CLONE_* flags from clone/fork/vfork system call
116 *
117 * This is called before a new user task is to be cloned.
118 * Its return value will be passed to tracehook_finish_clone().
119 *
120 * Called with no locks held.
121 */
122static inline int tracehook_prepare_clone(unsigned clone_flags)
123{
124 if (clone_flags & CLONE_UNTRACED)
125 return 0;
126
127 if (clone_flags & CLONE_VFORK) {
128 if (current->ptrace & PT_TRACE_VFORK)
129 return PTRACE_EVENT_VFORK;
130 } else if ((clone_flags & CSIGNAL) != SIGCHLD) {
131 if (current->ptrace & PT_TRACE_CLONE)
132 return PTRACE_EVENT_CLONE;
133 } else if (current->ptrace & PT_TRACE_FORK)
134 return PTRACE_EVENT_FORK;
135
136 return 0;
137}
138
139/**
140 * tracehook_finish_clone - new child created and being attached
141 * @child: new child task
142 * @clone_flags: %CLONE_* flags from clone/fork/vfork system call
143 * @trace: return value from tracehook_clone_prepare()
144 *
145 * This is called immediately after adding @child to its parent's children list.
146 * The @trace value is that returned by tracehook_prepare_clone().
147 *
148 * Called with current's siglock and write_lock_irq(&tasklist_lock) held.
149 */
150static inline void tracehook_finish_clone(struct task_struct *child,
151 unsigned long clone_flags, int trace)
152{
153 ptrace_init_task(child, (clone_flags & CLONE_PTRACE) || trace);
154}
155
156/**
157 * tracehook_report_clone - in parent, new child is about to start running
158 * @trace: return value from tracehook_clone_prepare()
159 * @regs: parent's user register state
160 * @clone_flags: flags from parent's system call
161 * @pid: new child's PID in the parent's namespace
162 * @child: new child task
163 *
164 * Called after a child is set up, but before it has been started running.
165 * The @trace value is that returned by tracehook_clone_prepare().
166 * This is not a good place to block, because the child has not started yet.
167 * Suspend the child here if desired, and block in tracehook_clone_complete().
168 * This must prevent the child from self-reaping if tracehook_clone_complete()
169 * uses the @child pointer; otherwise it might have died and been released by
170 * the time tracehook_report_clone_complete() is called.
171 *
172 * Called with no locks held, but the child cannot run until this returns.
173 */
174static inline void tracehook_report_clone(int trace, struct pt_regs *regs,
175 unsigned long clone_flags,
176 pid_t pid, struct task_struct *child)
177{
178 if (unlikely(trace)) {
179 /*
180 * The child starts up with an immediate SIGSTOP.
181 */
182 sigaddset(&child->pending.signal, SIGSTOP);
183 set_tsk_thread_flag(child, TIF_SIGPENDING);
184 }
185}
186
187/**
188 * tracehook_report_clone_complete - new child is running
189 * @trace: return value from tracehook_clone_prepare()
190 * @regs: parent's user register state
191 * @clone_flags: flags from parent's system call
192 * @pid: new child's PID in the parent's namespace
193 * @child: child task, already running
194 *
195 * This is called just after the child has started running. This is
196 * just before the clone/fork syscall returns, or blocks for vfork
197 * child completion if @clone_flags has the %CLONE_VFORK bit set.
198 * The @child pointer may be invalid if a self-reaping child died and
199 * tracehook_report_clone() took no action to prevent it from self-reaping.
200 *
201 * Called with no locks held.
202 */
203static inline void tracehook_report_clone_complete(int trace,
204 struct pt_regs *regs,
205 unsigned long clone_flags,
206 pid_t pid,
207 struct task_struct *child)
208{
209 if (unlikely(trace))
210 ptrace_event(0, trace, pid);
211}
212
113#endif /* <linux/tracehook.h> */ 213#endif /* <linux/tracehook.h> */