]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.suse/self-ptrace.patch
Imported linux-2.6.27.39 suse/xen patches.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.suse / self-ptrace.patch
CommitLineData
2cb7cef9
BS
1From: Gerald Schaefer <geraldsc@de.ibm.com>
2Subject: [PATCH] system call notification with self_ptrace
3References: bnc#417299
4
5PTRACE SELF
6
7This patch adds a new functionality to ptrace: system call notification to
8the current process.
9When a process requests self ptrace, with the new request PTRACE_SELF_ON:
10
11 1. the next system call performed by the process will not be executed
12 2. self ptrace will be disabled for the process
13 3. a SIGSYS signal will be sent to the process.
14
15With an appropriate SIGSYS signal handler, the process can access its own
16data structures to
17
18 1. get the system call number from the siginfo structure
19 2. get the system call arguments from the stack
20 3. instrument the system call with other system calls
21 4. emulate the system call with other system calls
22 5. change the arguments of the system call
23 6. perform the system call for good
24 7. change the return value of the system call
25 8. request self ptrace again before returning.
26
27The new request PTRACE_SELF_OFF disables self ptrace.
28
29
30Signed-off-by: Pierre Morel <pmorel@fr.ibm.com>
31Signed-off-by: Volker Sameske <sameske@de.ibm.com>
32
33Acked-by: John Jolly <jjolly@suse.de>
34---
35
36 include/asm-generic/siginfo.h | 6 ++++++
37 include/linux/ptrace.h | 18 ++++++++++++++++++
38 include/linux/sched.h | 1 +
39 kernel/ptrace.c | 32 ++++++++++++++++++++++++++++++++
40 4 files changed, 57 insertions(+)
41
42--- a/include/asm-generic/siginfo.h
43+++ b/include/asm-generic/siginfo.h
44@@ -224,6 +224,12 @@ typedef struct siginfo {
45 #define NSIGPOLL 6
46
47 /*
48+ * SIGSYS si_codes
49+ */
50+#define SYS_SYSCALL (__SI_FAULT|1) /* system call notification */
51+#define NSIGSYS 1
52+
53+/*
54 * sigevent definitions
55 *
56 * It seems likely that SIGEV_THREAD will have to be handled from
57--- a/include/linux/ptrace.h
58+++ b/include/linux/ptrace.h
59@@ -27,6 +27,10 @@
60 #define PTRACE_GETSIGINFO 0x4202
61 #define PTRACE_SETSIGINFO 0x4203
62
63+/* PTRACE SELF requests */
64+#define PTRACE_SELF_ON 0x4281
65+#define PTRACE_SELF_OFF 0x4282
66+
67 /* options set using PTRACE_SETOPTIONS */
68 #define PTRACE_O_TRACESYSGOOD 0x00000001
69 #define PTRACE_O_TRACEFORK 0x00000002
70@@ -78,7 +82,21 @@
71
72 #include <linux/compiler.h> /* For unlikely. */
73 #include <linux/sched.h> /* For struct task_struct. */
74+#include <linux/unistd.h> /* For syscall definitions */
75+
76+#define PTS_INSTRUMENTED 0x00000001
77+#define PTS_SELF 0x00000002
78
79+static inline int is_self_ptracing(unsigned long syscall)
80+{
81+ if (!(current->instrumentation & PTS_SELF))
82+ return 0;
83+ if (syscall == __NR_rt_sigreturn)
84+ return 0;
85+ if (syscall == __NR_ptrace)
86+ return 0;
87+ return 1;
88+}
89
90 extern long arch_ptrace(struct task_struct *child, long request, long addr, long data);
91 extern struct task_struct *ptrace_get_task_struct(pid_t pid);
92--- a/include/linux/sched.h
93+++ b/include/linux/sched.h
94@@ -1308,6 +1308,7 @@ struct task_struct {
95 int latency_record_count;
96 struct latency_record latency_record[LT_SAVECOUNT];
97 #endif
98+ u64 instrumentation;
99 };
100
101 /*
102--- a/kernel/ptrace.c
103+++ b/kernel/ptrace.c
104@@ -554,6 +554,38 @@ SYSCALL_DEFINE4(ptrace, long, request, l
105 * This lock_kernel fixes a subtle race with suid exec
106 */
107 lock_kernel();
108+ if (request == PTRACE_SELF_ON) {
109+ task_lock(current);
110+ if (current->ptrace) {
111+ task_unlock(current);
112+ ret = -EPERM;
113+ goto out;
114+ }
115+ set_thread_flag(TIF_SYSCALL_TRACE);
116+ current->instrumentation |= PTS_INSTRUMENTED|PTS_SELF;
117+ task_unlock(current);
118+ ret = 0;
119+ goto out;
120+ }
121+ if (request == PTRACE_SELF_OFF) {
122+ task_lock(current);
123+ if (current->ptrace) {
124+ task_unlock(current);
125+ ret = -EPERM;
126+ goto out;
127+ }
128+ clear_thread_flag(TIF_SYSCALL_TRACE);
129+ current->instrumentation &= ~PTS_SELF;
130+ task_unlock(current);
131+ ret = 0;
132+ goto out;
133+ }
134+
135+ if (current->instrumentation) {
136+ ret = -EPERM;
137+ goto out;
138+ }
139+
140 if (request == PTRACE_TRACEME) {
141 ret = ptrace_traceme();
142 if (!ret)