tracehook: exec
[linux-2.6.git] / include / linux / tracehook.h
1 /*
2  * Tracing hooks
3  *
4  * Copyright (C) 2008 Red Hat, Inc.  All rights reserved.
5  *
6  * This copyrighted material is made available to anyone wishing to use,
7  * modify, copy, or redistribute it subject to the terms and conditions
8  * of the GNU General Public License v.2.
9  *
10  * This file defines hook entry points called by core code where
11  * user tracing/debugging support might need to do something.  These
12  * entry points are called tracehook_*().  Each hook declared below
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.
15  *
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
18  * fast path when no tracing is enabled should be very short.
19  *
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
22  * user debugging or tracing facility (such as ptrace).  The interfaces
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
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
27  * documented circumstances of each call, such as locking conditions.
28  *
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
31  * core code changing should notify the maintainers of the tracing code
32  * that they need to work out the change.
33  *
34  * Some tracehook_*() inlines take arguments that the current tracing
35  * implementations might not necessarily use.  These function signatures
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
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
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
42  * maintainer of core code changing should notify the maintainers of the
43  * tracing code that they need to work out the change.
44  */
45
46 #ifndef _LINUX_TRACEHOOK_H
47 #define _LINUX_TRACEHOOK_H      1
48
49 #include <linux/sched.h>
50 #include <linux/ptrace.h>
51 #include <linux/security.h>
52 struct linux_binprm;
53
54 /**
55  * tracehook_unsafe_exec - check for exec declared unsafe due to tracing
56  * @task:               current task doing exec
57  *
58  * Return %LSM_UNSAFE_* bits applied to an exec because of tracing.
59  *
60  * Called with task_lock() held on @task.
61  */
62 static inline int tracehook_unsafe_exec(struct task_struct *task)
63 {
64         int unsafe = 0;
65         int ptrace = task_ptrace(task);
66         if (ptrace & PT_PTRACED) {
67                 if (ptrace & PT_PTRACE_CAP)
68                         unsafe |= LSM_UNSAFE_PTRACE_CAP;
69                 else
70                         unsafe |= LSM_UNSAFE_PTRACE;
71         }
72         return unsafe;
73 }
74
75 /**
76  * tracehook_report_exec - a successful exec was completed
77  * @fmt:                &struct linux_binfmt that performed the exec
78  * @bprm:               &struct linux_binprm containing exec details
79  * @regs:               user-mode register state
80  *
81  * An exec just completed, we are shortly going to return to user mode.
82  * The freshly initialized register state can be seen and changed in @regs.
83  * The name, file and other pointers in @bprm are still on hand to be
84  * inspected, but will be freed as soon as this returns.
85  *
86  * Called with no locks, but with some kernel resources held live
87  * and a reference on @fmt->module.
88  */
89 static inline void tracehook_report_exec(struct linux_binfmt *fmt,
90                                          struct linux_binprm *bprm,
91                                          struct pt_regs *regs)
92 {
93         if (!ptrace_event(PT_TRACE_EXEC, PTRACE_EVENT_EXEC, 0) &&
94             unlikely(task_ptrace(current) & PT_PTRACED))
95                 send_sig(SIGTRAP, current, 0);
96 }
97
98 #endif  /* <linux/tracehook.h> */