Commit 4abf986960ecda6a87fc2f795aacf888a2f0127e
Committed by
Linus Torvalds
1 parent
c4b5ed250e
ptrace: change signature of sys_ptrace() and friends
Since userspace API of ptrace syscall defines @addr and @data as void pointers, it would be more appropriate to define them as unsigned long in kernel. Therefore related functions are changed also. 'unsigned long' is typically used in other places in kernel as an opaque data type and that using this helps cleaning up a lot of warnings from sparse. Suggested-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Namhyung Kim <namhyung@gmail.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Acked-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 3 changed files with 18 additions and 10 deletions Inline Diff
include/linux/ptrace.h
1 | #ifndef _LINUX_PTRACE_H | 1 | #ifndef _LINUX_PTRACE_H |
2 | #define _LINUX_PTRACE_H | 2 | #define _LINUX_PTRACE_H |
3 | /* ptrace.h */ | 3 | /* ptrace.h */ |
4 | /* structs and defines to help the user use the ptrace system call. */ | 4 | /* structs and defines to help the user use the ptrace system call. */ |
5 | 5 | ||
6 | /* has the defines to get at the registers. */ | 6 | /* has the defines to get at the registers. */ |
7 | 7 | ||
8 | #define PTRACE_TRACEME 0 | 8 | #define PTRACE_TRACEME 0 |
9 | #define PTRACE_PEEKTEXT 1 | 9 | #define PTRACE_PEEKTEXT 1 |
10 | #define PTRACE_PEEKDATA 2 | 10 | #define PTRACE_PEEKDATA 2 |
11 | #define PTRACE_PEEKUSR 3 | 11 | #define PTRACE_PEEKUSR 3 |
12 | #define PTRACE_POKETEXT 4 | 12 | #define PTRACE_POKETEXT 4 |
13 | #define PTRACE_POKEDATA 5 | 13 | #define PTRACE_POKEDATA 5 |
14 | #define PTRACE_POKEUSR 6 | 14 | #define PTRACE_POKEUSR 6 |
15 | #define PTRACE_CONT 7 | 15 | #define PTRACE_CONT 7 |
16 | #define PTRACE_KILL 8 | 16 | #define PTRACE_KILL 8 |
17 | #define PTRACE_SINGLESTEP 9 | 17 | #define PTRACE_SINGLESTEP 9 |
18 | 18 | ||
19 | #define PTRACE_ATTACH 16 | 19 | #define PTRACE_ATTACH 16 |
20 | #define PTRACE_DETACH 17 | 20 | #define PTRACE_DETACH 17 |
21 | 21 | ||
22 | #define PTRACE_SYSCALL 24 | 22 | #define PTRACE_SYSCALL 24 |
23 | 23 | ||
24 | /* 0x4200-0x4300 are reserved for architecture-independent additions. */ | 24 | /* 0x4200-0x4300 are reserved for architecture-independent additions. */ |
25 | #define PTRACE_SETOPTIONS 0x4200 | 25 | #define PTRACE_SETOPTIONS 0x4200 |
26 | #define PTRACE_GETEVENTMSG 0x4201 | 26 | #define PTRACE_GETEVENTMSG 0x4201 |
27 | #define PTRACE_GETSIGINFO 0x4202 | 27 | #define PTRACE_GETSIGINFO 0x4202 |
28 | #define PTRACE_SETSIGINFO 0x4203 | 28 | #define PTRACE_SETSIGINFO 0x4203 |
29 | 29 | ||
30 | /* | 30 | /* |
31 | * Generic ptrace interface that exports the architecture specific regsets | 31 | * Generic ptrace interface that exports the architecture specific regsets |
32 | * using the corresponding NT_* types (which are also used in the core dump). | 32 | * using the corresponding NT_* types (which are also used in the core dump). |
33 | * Please note that the NT_PRSTATUS note type in a core dump contains a full | 33 | * Please note that the NT_PRSTATUS note type in a core dump contains a full |
34 | * 'struct elf_prstatus'. But the user_regset for NT_PRSTATUS contains just the | 34 | * 'struct elf_prstatus'. But the user_regset for NT_PRSTATUS contains just the |
35 | * elf_gregset_t that is the pr_reg field of 'struct elf_prstatus'. For all the | 35 | * elf_gregset_t that is the pr_reg field of 'struct elf_prstatus'. For all the |
36 | * other user_regset flavors, the user_regset layout and the ELF core dump note | 36 | * other user_regset flavors, the user_regset layout and the ELF core dump note |
37 | * payload are exactly the same layout. | 37 | * payload are exactly the same layout. |
38 | * | 38 | * |
39 | * This interface usage is as follows: | 39 | * This interface usage is as follows: |
40 | * struct iovec iov = { buf, len}; | 40 | * struct iovec iov = { buf, len}; |
41 | * | 41 | * |
42 | * ret = ptrace(PTRACE_GETREGSET/PTRACE_SETREGSET, pid, NT_XXX_TYPE, &iov); | 42 | * ret = ptrace(PTRACE_GETREGSET/PTRACE_SETREGSET, pid, NT_XXX_TYPE, &iov); |
43 | * | 43 | * |
44 | * On the successful completion, iov.len will be updated by the kernel, | 44 | * On the successful completion, iov.len will be updated by the kernel, |
45 | * specifying how much the kernel has written/read to/from the user's iov.buf. | 45 | * specifying how much the kernel has written/read to/from the user's iov.buf. |
46 | */ | 46 | */ |
47 | #define PTRACE_GETREGSET 0x4204 | 47 | #define PTRACE_GETREGSET 0x4204 |
48 | #define PTRACE_SETREGSET 0x4205 | 48 | #define PTRACE_SETREGSET 0x4205 |
49 | 49 | ||
50 | /* options set using PTRACE_SETOPTIONS */ | 50 | /* options set using PTRACE_SETOPTIONS */ |
51 | #define PTRACE_O_TRACESYSGOOD 0x00000001 | 51 | #define PTRACE_O_TRACESYSGOOD 0x00000001 |
52 | #define PTRACE_O_TRACEFORK 0x00000002 | 52 | #define PTRACE_O_TRACEFORK 0x00000002 |
53 | #define PTRACE_O_TRACEVFORK 0x00000004 | 53 | #define PTRACE_O_TRACEVFORK 0x00000004 |
54 | #define PTRACE_O_TRACECLONE 0x00000008 | 54 | #define PTRACE_O_TRACECLONE 0x00000008 |
55 | #define PTRACE_O_TRACEEXEC 0x00000010 | 55 | #define PTRACE_O_TRACEEXEC 0x00000010 |
56 | #define PTRACE_O_TRACEVFORKDONE 0x00000020 | 56 | #define PTRACE_O_TRACEVFORKDONE 0x00000020 |
57 | #define PTRACE_O_TRACEEXIT 0x00000040 | 57 | #define PTRACE_O_TRACEEXIT 0x00000040 |
58 | 58 | ||
59 | #define PTRACE_O_MASK 0x0000007f | 59 | #define PTRACE_O_MASK 0x0000007f |
60 | 60 | ||
61 | /* Wait extended result codes for the above trace options. */ | 61 | /* Wait extended result codes for the above trace options. */ |
62 | #define PTRACE_EVENT_FORK 1 | 62 | #define PTRACE_EVENT_FORK 1 |
63 | #define PTRACE_EVENT_VFORK 2 | 63 | #define PTRACE_EVENT_VFORK 2 |
64 | #define PTRACE_EVENT_CLONE 3 | 64 | #define PTRACE_EVENT_CLONE 3 |
65 | #define PTRACE_EVENT_EXEC 4 | 65 | #define PTRACE_EVENT_EXEC 4 |
66 | #define PTRACE_EVENT_VFORK_DONE 5 | 66 | #define PTRACE_EVENT_VFORK_DONE 5 |
67 | #define PTRACE_EVENT_EXIT 6 | 67 | #define PTRACE_EVENT_EXIT 6 |
68 | 68 | ||
69 | #include <asm/ptrace.h> | 69 | #include <asm/ptrace.h> |
70 | 70 | ||
71 | #ifdef __KERNEL__ | 71 | #ifdef __KERNEL__ |
72 | /* | 72 | /* |
73 | * Ptrace flags | 73 | * Ptrace flags |
74 | * | 74 | * |
75 | * The owner ship rules for task->ptrace which holds the ptrace | 75 | * The owner ship rules for task->ptrace which holds the ptrace |
76 | * flags is simple. When a task is running it owns it's task->ptrace | 76 | * flags is simple. When a task is running it owns it's task->ptrace |
77 | * flags. When the a task is stopped the ptracer owns task->ptrace. | 77 | * flags. When the a task is stopped the ptracer owns task->ptrace. |
78 | */ | 78 | */ |
79 | 79 | ||
80 | #define PT_PTRACED 0x00000001 | 80 | #define PT_PTRACED 0x00000001 |
81 | #define PT_DTRACE 0x00000002 /* delayed trace (used on m68k, i386) */ | 81 | #define PT_DTRACE 0x00000002 /* delayed trace (used on m68k, i386) */ |
82 | #define PT_TRACESYSGOOD 0x00000004 | 82 | #define PT_TRACESYSGOOD 0x00000004 |
83 | #define PT_PTRACE_CAP 0x00000008 /* ptracer can follow suid-exec */ | 83 | #define PT_PTRACE_CAP 0x00000008 /* ptracer can follow suid-exec */ |
84 | #define PT_TRACE_FORK 0x00000010 | 84 | #define PT_TRACE_FORK 0x00000010 |
85 | #define PT_TRACE_VFORK 0x00000020 | 85 | #define PT_TRACE_VFORK 0x00000020 |
86 | #define PT_TRACE_CLONE 0x00000040 | 86 | #define PT_TRACE_CLONE 0x00000040 |
87 | #define PT_TRACE_EXEC 0x00000080 | 87 | #define PT_TRACE_EXEC 0x00000080 |
88 | #define PT_TRACE_VFORK_DONE 0x00000100 | 88 | #define PT_TRACE_VFORK_DONE 0x00000100 |
89 | #define PT_TRACE_EXIT 0x00000200 | 89 | #define PT_TRACE_EXIT 0x00000200 |
90 | 90 | ||
91 | #define PT_TRACE_MASK 0x000003f4 | 91 | #define PT_TRACE_MASK 0x000003f4 |
92 | 92 | ||
93 | /* single stepping state bits (used on ARM and PA-RISC) */ | 93 | /* single stepping state bits (used on ARM and PA-RISC) */ |
94 | #define PT_SINGLESTEP_BIT 31 | 94 | #define PT_SINGLESTEP_BIT 31 |
95 | #define PT_SINGLESTEP (1<<PT_SINGLESTEP_BIT) | 95 | #define PT_SINGLESTEP (1<<PT_SINGLESTEP_BIT) |
96 | #define PT_BLOCKSTEP_BIT 30 | 96 | #define PT_BLOCKSTEP_BIT 30 |
97 | #define PT_BLOCKSTEP (1<<PT_BLOCKSTEP_BIT) | 97 | #define PT_BLOCKSTEP (1<<PT_BLOCKSTEP_BIT) |
98 | 98 | ||
99 | #include <linux/compiler.h> /* For unlikely. */ | 99 | #include <linux/compiler.h> /* For unlikely. */ |
100 | #include <linux/sched.h> /* For struct task_struct. */ | 100 | #include <linux/sched.h> /* For struct task_struct. */ |
101 | 101 | ||
102 | 102 | ||
103 | extern long arch_ptrace(struct task_struct *child, long request, long addr, long data); | 103 | extern long arch_ptrace(struct task_struct *child, long request, long addr, long data); |
104 | extern int ptrace_traceme(void); | 104 | extern int ptrace_traceme(void); |
105 | extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len); | 105 | extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len); |
106 | extern int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len); | 106 | extern int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len); |
107 | extern int ptrace_attach(struct task_struct *tsk); | 107 | extern int ptrace_attach(struct task_struct *tsk); |
108 | extern int ptrace_detach(struct task_struct *, unsigned int); | 108 | extern int ptrace_detach(struct task_struct *, unsigned int); |
109 | extern void ptrace_disable(struct task_struct *); | 109 | extern void ptrace_disable(struct task_struct *); |
110 | extern int ptrace_check_attach(struct task_struct *task, int kill); | 110 | extern int ptrace_check_attach(struct task_struct *task, int kill); |
111 | extern int ptrace_request(struct task_struct *child, long request, long addr, long data); | 111 | extern int ptrace_request(struct task_struct *child, long request, |
112 | unsigned long addr, unsigned long data); | ||
112 | extern void ptrace_notify(int exit_code); | 113 | extern void ptrace_notify(int exit_code); |
113 | extern void __ptrace_link(struct task_struct *child, | 114 | extern void __ptrace_link(struct task_struct *child, |
114 | struct task_struct *new_parent); | 115 | struct task_struct *new_parent); |
115 | extern void __ptrace_unlink(struct task_struct *child); | 116 | extern void __ptrace_unlink(struct task_struct *child); |
116 | extern void exit_ptrace(struct task_struct *tracer); | 117 | extern void exit_ptrace(struct task_struct *tracer); |
117 | #define PTRACE_MODE_READ 1 | 118 | #define PTRACE_MODE_READ 1 |
118 | #define PTRACE_MODE_ATTACH 2 | 119 | #define PTRACE_MODE_ATTACH 2 |
119 | /* Returns 0 on success, -errno on denial. */ | 120 | /* Returns 0 on success, -errno on denial. */ |
120 | extern int __ptrace_may_access(struct task_struct *task, unsigned int mode); | 121 | extern int __ptrace_may_access(struct task_struct *task, unsigned int mode); |
121 | /* Returns true on success, false on denial. */ | 122 | /* Returns true on success, false on denial. */ |
122 | extern bool ptrace_may_access(struct task_struct *task, unsigned int mode); | 123 | extern bool ptrace_may_access(struct task_struct *task, unsigned int mode); |
123 | 124 | ||
124 | static inline int ptrace_reparented(struct task_struct *child) | 125 | static inline int ptrace_reparented(struct task_struct *child) |
125 | { | 126 | { |
126 | return child->real_parent != child->parent; | 127 | return child->real_parent != child->parent; |
127 | } | 128 | } |
128 | 129 | ||
129 | static inline void ptrace_unlink(struct task_struct *child) | 130 | static inline void ptrace_unlink(struct task_struct *child) |
130 | { | 131 | { |
131 | if (unlikely(child->ptrace)) | 132 | if (unlikely(child->ptrace)) |
132 | __ptrace_unlink(child); | 133 | __ptrace_unlink(child); |
133 | } | 134 | } |
134 | 135 | ||
135 | int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data); | 136 | int generic_ptrace_peekdata(struct task_struct *tsk, unsigned long addr, |
136 | int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data); | 137 | unsigned long data); |
138 | int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr, | ||
139 | unsigned long data); | ||
137 | 140 | ||
138 | /** | 141 | /** |
139 | * task_ptrace - return %PT_* flags that apply to a task | 142 | * task_ptrace - return %PT_* flags that apply to a task |
140 | * @task: pointer to &task_struct in question | 143 | * @task: pointer to &task_struct in question |
141 | * | 144 | * |
142 | * Returns the %PT_* flags that apply to @task. | 145 | * Returns the %PT_* flags that apply to @task. |
143 | */ | 146 | */ |
144 | static inline int task_ptrace(struct task_struct *task) | 147 | static inline int task_ptrace(struct task_struct *task) |
145 | { | 148 | { |
146 | return task->ptrace; | 149 | return task->ptrace; |
147 | } | 150 | } |
148 | 151 | ||
149 | /** | 152 | /** |
150 | * ptrace_event - possibly stop for a ptrace event notification | 153 | * ptrace_event - possibly stop for a ptrace event notification |
151 | * @mask: %PT_* bit to check in @current->ptrace | 154 | * @mask: %PT_* bit to check in @current->ptrace |
152 | * @event: %PTRACE_EVENT_* value to report if @mask is set | 155 | * @event: %PTRACE_EVENT_* value to report if @mask is set |
153 | * @message: value for %PTRACE_GETEVENTMSG to return | 156 | * @message: value for %PTRACE_GETEVENTMSG to return |
154 | * | 157 | * |
155 | * This checks the @mask bit to see if ptrace wants stops for this event. | 158 | * This checks the @mask bit to see if ptrace wants stops for this event. |
156 | * If so we stop, reporting @event and @message to the ptrace parent. | 159 | * If so we stop, reporting @event and @message to the ptrace parent. |
157 | * | 160 | * |
158 | * Returns nonzero if we did a ptrace notification, zero if not. | 161 | * Returns nonzero if we did a ptrace notification, zero if not. |
159 | * | 162 | * |
160 | * Called without locks. | 163 | * Called without locks. |
161 | */ | 164 | */ |
162 | static inline int ptrace_event(int mask, int event, unsigned long message) | 165 | static inline int ptrace_event(int mask, int event, unsigned long message) |
163 | { | 166 | { |
164 | if (mask && likely(!(current->ptrace & mask))) | 167 | if (mask && likely(!(current->ptrace & mask))) |
165 | return 0; | 168 | return 0; |
166 | current->ptrace_message = message; | 169 | current->ptrace_message = message; |
167 | ptrace_notify((event << 8) | SIGTRAP); | 170 | ptrace_notify((event << 8) | SIGTRAP); |
168 | return 1; | 171 | return 1; |
169 | } | 172 | } |
170 | 173 | ||
171 | /** | 174 | /** |
172 | * ptrace_init_task - initialize ptrace state for a new child | 175 | * ptrace_init_task - initialize ptrace state for a new child |
173 | * @child: new child task | 176 | * @child: new child task |
174 | * @ptrace: true if child should be ptrace'd by parent's tracer | 177 | * @ptrace: true if child should be ptrace'd by parent's tracer |
175 | * | 178 | * |
176 | * This is called immediately after adding @child to its parent's children | 179 | * This is called immediately after adding @child to its parent's children |
177 | * list. @ptrace is false in the normal case, and true to ptrace @child. | 180 | * list. @ptrace is false in the normal case, and true to ptrace @child. |
178 | * | 181 | * |
179 | * Called with current's siglock and write_lock_irq(&tasklist_lock) held. | 182 | * Called with current's siglock and write_lock_irq(&tasklist_lock) held. |
180 | */ | 183 | */ |
181 | static inline void ptrace_init_task(struct task_struct *child, bool ptrace) | 184 | static inline void ptrace_init_task(struct task_struct *child, bool ptrace) |
182 | { | 185 | { |
183 | INIT_LIST_HEAD(&child->ptrace_entry); | 186 | INIT_LIST_HEAD(&child->ptrace_entry); |
184 | INIT_LIST_HEAD(&child->ptraced); | 187 | INIT_LIST_HEAD(&child->ptraced); |
185 | child->parent = child->real_parent; | 188 | child->parent = child->real_parent; |
186 | child->ptrace = 0; | 189 | child->ptrace = 0; |
187 | if (unlikely(ptrace) && (current->ptrace & PT_PTRACED)) { | 190 | if (unlikely(ptrace) && (current->ptrace & PT_PTRACED)) { |
188 | child->ptrace = current->ptrace; | 191 | child->ptrace = current->ptrace; |
189 | __ptrace_link(child, current->parent); | 192 | __ptrace_link(child, current->parent); |
190 | } | 193 | } |
191 | } | 194 | } |
192 | 195 | ||
193 | /** | 196 | /** |
194 | * ptrace_release_task - final ptrace-related cleanup of a zombie being reaped | 197 | * ptrace_release_task - final ptrace-related cleanup of a zombie being reaped |
195 | * @task: task in %EXIT_DEAD state | 198 | * @task: task in %EXIT_DEAD state |
196 | * | 199 | * |
197 | * Called with write_lock(&tasklist_lock) held. | 200 | * Called with write_lock(&tasklist_lock) held. |
198 | */ | 201 | */ |
199 | static inline void ptrace_release_task(struct task_struct *task) | 202 | static inline void ptrace_release_task(struct task_struct *task) |
200 | { | 203 | { |
201 | BUG_ON(!list_empty(&task->ptraced)); | 204 | BUG_ON(!list_empty(&task->ptraced)); |
202 | ptrace_unlink(task); | 205 | ptrace_unlink(task); |
203 | BUG_ON(!list_empty(&task->ptrace_entry)); | 206 | BUG_ON(!list_empty(&task->ptrace_entry)); |
204 | } | 207 | } |
205 | 208 | ||
206 | #ifndef force_successful_syscall_return | 209 | #ifndef force_successful_syscall_return |
207 | /* | 210 | /* |
208 | * System call handlers that, upon successful completion, need to return a | 211 | * System call handlers that, upon successful completion, need to return a |
209 | * negative value should call force_successful_syscall_return() right before | 212 | * negative value should call force_successful_syscall_return() right before |
210 | * returning. On architectures where the syscall convention provides for a | 213 | * returning. On architectures where the syscall convention provides for a |
211 | * separate error flag (e.g., alpha, ia64, ppc{,64}, sparc{,64}, possibly | 214 | * separate error flag (e.g., alpha, ia64, ppc{,64}, sparc{,64}, possibly |
212 | * others), this macro can be used to ensure that the error flag will not get | 215 | * others), this macro can be used to ensure that the error flag will not get |
213 | * set. On architectures which do not support a separate error flag, the macro | 216 | * set. On architectures which do not support a separate error flag, the macro |
214 | * is a no-op and the spurious error condition needs to be filtered out by some | 217 | * is a no-op and the spurious error condition needs to be filtered out by some |
215 | * other means (e.g., in user-level, by passing an extra argument to the | 218 | * other means (e.g., in user-level, by passing an extra argument to the |
216 | * syscall handler, or something along those lines). | 219 | * syscall handler, or something along those lines). |
217 | */ | 220 | */ |
218 | #define force_successful_syscall_return() do { } while (0) | 221 | #define force_successful_syscall_return() do { } while (0) |
219 | #endif | 222 | #endif |
220 | 223 | ||
221 | /* | 224 | /* |
222 | * <asm/ptrace.h> should define the following things inside #ifdef __KERNEL__. | 225 | * <asm/ptrace.h> should define the following things inside #ifdef __KERNEL__. |
223 | * | 226 | * |
224 | * These do-nothing inlines are used when the arch does not | 227 | * These do-nothing inlines are used when the arch does not |
225 | * implement single-step. The kerneldoc comments are here | 228 | * implement single-step. The kerneldoc comments are here |
226 | * to document the interface for all arch definitions. | 229 | * to document the interface for all arch definitions. |
227 | */ | 230 | */ |
228 | 231 | ||
229 | #ifndef arch_has_single_step | 232 | #ifndef arch_has_single_step |
230 | /** | 233 | /** |
231 | * arch_has_single_step - does this CPU support user-mode single-step? | 234 | * arch_has_single_step - does this CPU support user-mode single-step? |
232 | * | 235 | * |
233 | * If this is defined, then there must be function declarations or | 236 | * If this is defined, then there must be function declarations or |
234 | * inlines for user_enable_single_step() and user_disable_single_step(). | 237 | * inlines for user_enable_single_step() and user_disable_single_step(). |
235 | * arch_has_single_step() should evaluate to nonzero iff the machine | 238 | * arch_has_single_step() should evaluate to nonzero iff the machine |
236 | * supports instruction single-step for user mode. | 239 | * supports instruction single-step for user mode. |
237 | * It can be a constant or it can test a CPU feature bit. | 240 | * It can be a constant or it can test a CPU feature bit. |
238 | */ | 241 | */ |
239 | #define arch_has_single_step() (0) | 242 | #define arch_has_single_step() (0) |
240 | 243 | ||
241 | /** | 244 | /** |
242 | * user_enable_single_step - single-step in user-mode task | 245 | * user_enable_single_step - single-step in user-mode task |
243 | * @task: either current or a task stopped in %TASK_TRACED | 246 | * @task: either current or a task stopped in %TASK_TRACED |
244 | * | 247 | * |
245 | * This can only be called when arch_has_single_step() has returned nonzero. | 248 | * This can only be called when arch_has_single_step() has returned nonzero. |
246 | * Set @task so that when it returns to user mode, it will trap after the | 249 | * Set @task so that when it returns to user mode, it will trap after the |
247 | * next single instruction executes. If arch_has_block_step() is defined, | 250 | * next single instruction executes. If arch_has_block_step() is defined, |
248 | * this must clear the effects of user_enable_block_step() too. | 251 | * this must clear the effects of user_enable_block_step() too. |
249 | */ | 252 | */ |
250 | static inline void user_enable_single_step(struct task_struct *task) | 253 | static inline void user_enable_single_step(struct task_struct *task) |
251 | { | 254 | { |
252 | BUG(); /* This can never be called. */ | 255 | BUG(); /* This can never be called. */ |
253 | } | 256 | } |
254 | 257 | ||
255 | /** | 258 | /** |
256 | * user_disable_single_step - cancel user-mode single-step | 259 | * user_disable_single_step - cancel user-mode single-step |
257 | * @task: either current or a task stopped in %TASK_TRACED | 260 | * @task: either current or a task stopped in %TASK_TRACED |
258 | * | 261 | * |
259 | * Clear @task of the effects of user_enable_single_step() and | 262 | * Clear @task of the effects of user_enable_single_step() and |
260 | * user_enable_block_step(). This can be called whether or not either | 263 | * user_enable_block_step(). This can be called whether or not either |
261 | * of those was ever called on @task, and even if arch_has_single_step() | 264 | * of those was ever called on @task, and even if arch_has_single_step() |
262 | * returned zero. | 265 | * returned zero. |
263 | */ | 266 | */ |
264 | static inline void user_disable_single_step(struct task_struct *task) | 267 | static inline void user_disable_single_step(struct task_struct *task) |
265 | { | 268 | { |
266 | } | 269 | } |
267 | #else | 270 | #else |
268 | extern void user_enable_single_step(struct task_struct *); | 271 | extern void user_enable_single_step(struct task_struct *); |
269 | extern void user_disable_single_step(struct task_struct *); | 272 | extern void user_disable_single_step(struct task_struct *); |
270 | #endif /* arch_has_single_step */ | 273 | #endif /* arch_has_single_step */ |
271 | 274 | ||
272 | #ifndef arch_has_block_step | 275 | #ifndef arch_has_block_step |
273 | /** | 276 | /** |
274 | * arch_has_block_step - does this CPU support user-mode block-step? | 277 | * arch_has_block_step - does this CPU support user-mode block-step? |
275 | * | 278 | * |
276 | * If this is defined, then there must be a function declaration or inline | 279 | * If this is defined, then there must be a function declaration or inline |
277 | * for user_enable_block_step(), and arch_has_single_step() must be defined | 280 | * for user_enable_block_step(), and arch_has_single_step() must be defined |
278 | * too. arch_has_block_step() should evaluate to nonzero iff the machine | 281 | * too. arch_has_block_step() should evaluate to nonzero iff the machine |
279 | * supports step-until-branch for user mode. It can be a constant or it | 282 | * supports step-until-branch for user mode. It can be a constant or it |
280 | * can test a CPU feature bit. | 283 | * can test a CPU feature bit. |
281 | */ | 284 | */ |
282 | #define arch_has_block_step() (0) | 285 | #define arch_has_block_step() (0) |
283 | 286 | ||
284 | /** | 287 | /** |
285 | * user_enable_block_step - step until branch in user-mode task | 288 | * user_enable_block_step - step until branch in user-mode task |
286 | * @task: either current or a task stopped in %TASK_TRACED | 289 | * @task: either current or a task stopped in %TASK_TRACED |
287 | * | 290 | * |
288 | * This can only be called when arch_has_block_step() has returned nonzero, | 291 | * This can only be called when arch_has_block_step() has returned nonzero, |
289 | * and will never be called when single-instruction stepping is being used. | 292 | * and will never be called when single-instruction stepping is being used. |
290 | * Set @task so that when it returns to user mode, it will trap after the | 293 | * Set @task so that when it returns to user mode, it will trap after the |
291 | * next branch or trap taken. | 294 | * next branch or trap taken. |
292 | */ | 295 | */ |
293 | static inline void user_enable_block_step(struct task_struct *task) | 296 | static inline void user_enable_block_step(struct task_struct *task) |
294 | { | 297 | { |
295 | BUG(); /* This can never be called. */ | 298 | BUG(); /* This can never be called. */ |
296 | } | 299 | } |
297 | #else | 300 | #else |
298 | extern void user_enable_block_step(struct task_struct *); | 301 | extern void user_enable_block_step(struct task_struct *); |
299 | #endif /* arch_has_block_step */ | 302 | #endif /* arch_has_block_step */ |
300 | 303 | ||
301 | #ifdef ARCH_HAS_USER_SINGLE_STEP_INFO | 304 | #ifdef ARCH_HAS_USER_SINGLE_STEP_INFO |
302 | extern void user_single_step_siginfo(struct task_struct *tsk, | 305 | extern void user_single_step_siginfo(struct task_struct *tsk, |
303 | struct pt_regs *regs, siginfo_t *info); | 306 | struct pt_regs *regs, siginfo_t *info); |
304 | #else | 307 | #else |
305 | static inline void user_single_step_siginfo(struct task_struct *tsk, | 308 | static inline void user_single_step_siginfo(struct task_struct *tsk, |
306 | struct pt_regs *regs, siginfo_t *info) | 309 | struct pt_regs *regs, siginfo_t *info) |
307 | { | 310 | { |
308 | memset(info, 0, sizeof(*info)); | 311 | memset(info, 0, sizeof(*info)); |
309 | info->si_signo = SIGTRAP; | 312 | info->si_signo = SIGTRAP; |
310 | } | 313 | } |
311 | #endif | 314 | #endif |
312 | 315 | ||
313 | #ifndef arch_ptrace_stop_needed | 316 | #ifndef arch_ptrace_stop_needed |
314 | /** | 317 | /** |
315 | * arch_ptrace_stop_needed - Decide whether arch_ptrace_stop() should be called | 318 | * arch_ptrace_stop_needed - Decide whether arch_ptrace_stop() should be called |
316 | * @code: current->exit_code value ptrace will stop with | 319 | * @code: current->exit_code value ptrace will stop with |
317 | * @info: siginfo_t pointer (or %NULL) for signal ptrace will stop with | 320 | * @info: siginfo_t pointer (or %NULL) for signal ptrace will stop with |
318 | * | 321 | * |
319 | * This is called with the siglock held, to decide whether or not it's | 322 | * This is called with the siglock held, to decide whether or not it's |
320 | * necessary to release the siglock and call arch_ptrace_stop() with the | 323 | * necessary to release the siglock and call arch_ptrace_stop() with the |
321 | * same @code and @info arguments. It can be defined to a constant if | 324 | * same @code and @info arguments. It can be defined to a constant if |
322 | * arch_ptrace_stop() is never required, or always is. On machines where | 325 | * arch_ptrace_stop() is never required, or always is. On machines where |
323 | * this makes sense, it should be defined to a quick test to optimize out | 326 | * this makes sense, it should be defined to a quick test to optimize out |
324 | * calling arch_ptrace_stop() when it would be superfluous. For example, | 327 | * calling arch_ptrace_stop() when it would be superfluous. For example, |
325 | * if the thread has not been back to user mode since the last stop, the | 328 | * if the thread has not been back to user mode since the last stop, the |
326 | * thread state might indicate that nothing needs to be done. | 329 | * thread state might indicate that nothing needs to be done. |
327 | */ | 330 | */ |
328 | #define arch_ptrace_stop_needed(code, info) (0) | 331 | #define arch_ptrace_stop_needed(code, info) (0) |
329 | #endif | 332 | #endif |
330 | 333 | ||
331 | #ifndef arch_ptrace_stop | 334 | #ifndef arch_ptrace_stop |
332 | /** | 335 | /** |
333 | * arch_ptrace_stop - Do machine-specific work before stopping for ptrace | 336 | * arch_ptrace_stop - Do machine-specific work before stopping for ptrace |
334 | * @code: current->exit_code value ptrace will stop with | 337 | * @code: current->exit_code value ptrace will stop with |
335 | * @info: siginfo_t pointer (or %NULL) for signal ptrace will stop with | 338 | * @info: siginfo_t pointer (or %NULL) for signal ptrace will stop with |
336 | * | 339 | * |
337 | * This is called with no locks held when arch_ptrace_stop_needed() has | 340 | * This is called with no locks held when arch_ptrace_stop_needed() has |
338 | * just returned nonzero. It is allowed to block, e.g. for user memory | 341 | * just returned nonzero. It is allowed to block, e.g. for user memory |
339 | * access. The arch can have machine-specific work to be done before | 342 | * access. The arch can have machine-specific work to be done before |
340 | * ptrace stops. On ia64, register backing store gets written back to user | 343 | * ptrace stops. On ia64, register backing store gets written back to user |
341 | * memory here. Since this can be costly (requires dropping the siglock), | 344 | * memory here. Since this can be costly (requires dropping the siglock), |
342 | * we only do it when the arch requires it for this particular stop, as | 345 | * we only do it when the arch requires it for this particular stop, as |
343 | * indicated by arch_ptrace_stop_needed(). | 346 | * indicated by arch_ptrace_stop_needed(). |
344 | */ | 347 | */ |
345 | #define arch_ptrace_stop(code, info) do { } while (0) | 348 | #define arch_ptrace_stop(code, info) do { } while (0) |
346 | #endif | 349 | #endif |
347 | 350 | ||
348 | extern int task_current_syscall(struct task_struct *target, long *callno, | 351 | extern int task_current_syscall(struct task_struct *target, long *callno, |
349 | unsigned long args[6], unsigned int maxargs, | 352 | unsigned long args[6], unsigned int maxargs, |
350 | unsigned long *sp, unsigned long *pc); | 353 | unsigned long *sp, unsigned long *pc); |
351 | 354 | ||
352 | #endif | 355 | #endif |
353 | 356 | ||
354 | #endif | 357 | #endif |
355 | 358 |
include/linux/syscalls.h
1 | /* | 1 | /* |
2 | * syscalls.h - Linux syscall interfaces (non-arch-specific) | 2 | * syscalls.h - Linux syscall interfaces (non-arch-specific) |
3 | * | 3 | * |
4 | * Copyright (c) 2004 Randy Dunlap | 4 | * Copyright (c) 2004 Randy Dunlap |
5 | * Copyright (c) 2004 Open Source Development Labs | 5 | * Copyright (c) 2004 Open Source Development Labs |
6 | * | 6 | * |
7 | * This file is released under the GPLv2. | 7 | * This file is released under the GPLv2. |
8 | * See the file COPYING for more details. | 8 | * See the file COPYING for more details. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #ifndef _LINUX_SYSCALLS_H | 11 | #ifndef _LINUX_SYSCALLS_H |
12 | #define _LINUX_SYSCALLS_H | 12 | #define _LINUX_SYSCALLS_H |
13 | 13 | ||
14 | struct epoll_event; | 14 | struct epoll_event; |
15 | struct iattr; | 15 | struct iattr; |
16 | struct inode; | 16 | struct inode; |
17 | struct iocb; | 17 | struct iocb; |
18 | struct io_event; | 18 | struct io_event; |
19 | struct iovec; | 19 | struct iovec; |
20 | struct itimerspec; | 20 | struct itimerspec; |
21 | struct itimerval; | 21 | struct itimerval; |
22 | struct kexec_segment; | 22 | struct kexec_segment; |
23 | struct linux_dirent; | 23 | struct linux_dirent; |
24 | struct linux_dirent64; | 24 | struct linux_dirent64; |
25 | struct list_head; | 25 | struct list_head; |
26 | struct mmap_arg_struct; | 26 | struct mmap_arg_struct; |
27 | struct msgbuf; | 27 | struct msgbuf; |
28 | struct msghdr; | 28 | struct msghdr; |
29 | struct mmsghdr; | 29 | struct mmsghdr; |
30 | struct msqid_ds; | 30 | struct msqid_ds; |
31 | struct new_utsname; | 31 | struct new_utsname; |
32 | struct nfsctl_arg; | 32 | struct nfsctl_arg; |
33 | struct __old_kernel_stat; | 33 | struct __old_kernel_stat; |
34 | struct oldold_utsname; | 34 | struct oldold_utsname; |
35 | struct old_utsname; | 35 | struct old_utsname; |
36 | struct pollfd; | 36 | struct pollfd; |
37 | struct rlimit; | 37 | struct rlimit; |
38 | struct rlimit64; | 38 | struct rlimit64; |
39 | struct rusage; | 39 | struct rusage; |
40 | struct sched_param; | 40 | struct sched_param; |
41 | struct sel_arg_struct; | 41 | struct sel_arg_struct; |
42 | struct semaphore; | 42 | struct semaphore; |
43 | struct sembuf; | 43 | struct sembuf; |
44 | struct shmid_ds; | 44 | struct shmid_ds; |
45 | struct sockaddr; | 45 | struct sockaddr; |
46 | struct stat; | 46 | struct stat; |
47 | struct stat64; | 47 | struct stat64; |
48 | struct statfs; | 48 | struct statfs; |
49 | struct statfs64; | 49 | struct statfs64; |
50 | struct __sysctl_args; | 50 | struct __sysctl_args; |
51 | struct sysinfo; | 51 | struct sysinfo; |
52 | struct timespec; | 52 | struct timespec; |
53 | struct timeval; | 53 | struct timeval; |
54 | struct timex; | 54 | struct timex; |
55 | struct timezone; | 55 | struct timezone; |
56 | struct tms; | 56 | struct tms; |
57 | struct utimbuf; | 57 | struct utimbuf; |
58 | struct mq_attr; | 58 | struct mq_attr; |
59 | struct compat_stat; | 59 | struct compat_stat; |
60 | struct compat_timeval; | 60 | struct compat_timeval; |
61 | struct robust_list_head; | 61 | struct robust_list_head; |
62 | struct getcpu_cache; | 62 | struct getcpu_cache; |
63 | struct old_linux_dirent; | 63 | struct old_linux_dirent; |
64 | struct perf_event_attr; | 64 | struct perf_event_attr; |
65 | 65 | ||
66 | #include <linux/types.h> | 66 | #include <linux/types.h> |
67 | #include <linux/aio_abi.h> | 67 | #include <linux/aio_abi.h> |
68 | #include <linux/capability.h> | 68 | #include <linux/capability.h> |
69 | #include <linux/list.h> | 69 | #include <linux/list.h> |
70 | #include <linux/sem.h> | 70 | #include <linux/sem.h> |
71 | #include <asm/siginfo.h> | 71 | #include <asm/siginfo.h> |
72 | #include <asm/signal.h> | 72 | #include <asm/signal.h> |
73 | #include <linux/unistd.h> | 73 | #include <linux/unistd.h> |
74 | #include <linux/quota.h> | 74 | #include <linux/quota.h> |
75 | #include <linux/key.h> | 75 | #include <linux/key.h> |
76 | #include <trace/syscall.h> | 76 | #include <trace/syscall.h> |
77 | 77 | ||
78 | #define __SC_DECL1(t1, a1) t1 a1 | 78 | #define __SC_DECL1(t1, a1) t1 a1 |
79 | #define __SC_DECL2(t2, a2, ...) t2 a2, __SC_DECL1(__VA_ARGS__) | 79 | #define __SC_DECL2(t2, a2, ...) t2 a2, __SC_DECL1(__VA_ARGS__) |
80 | #define __SC_DECL3(t3, a3, ...) t3 a3, __SC_DECL2(__VA_ARGS__) | 80 | #define __SC_DECL3(t3, a3, ...) t3 a3, __SC_DECL2(__VA_ARGS__) |
81 | #define __SC_DECL4(t4, a4, ...) t4 a4, __SC_DECL3(__VA_ARGS__) | 81 | #define __SC_DECL4(t4, a4, ...) t4 a4, __SC_DECL3(__VA_ARGS__) |
82 | #define __SC_DECL5(t5, a5, ...) t5 a5, __SC_DECL4(__VA_ARGS__) | 82 | #define __SC_DECL5(t5, a5, ...) t5 a5, __SC_DECL4(__VA_ARGS__) |
83 | #define __SC_DECL6(t6, a6, ...) t6 a6, __SC_DECL5(__VA_ARGS__) | 83 | #define __SC_DECL6(t6, a6, ...) t6 a6, __SC_DECL5(__VA_ARGS__) |
84 | 84 | ||
85 | #define __SC_LONG1(t1, a1) long a1 | 85 | #define __SC_LONG1(t1, a1) long a1 |
86 | #define __SC_LONG2(t2, a2, ...) long a2, __SC_LONG1(__VA_ARGS__) | 86 | #define __SC_LONG2(t2, a2, ...) long a2, __SC_LONG1(__VA_ARGS__) |
87 | #define __SC_LONG3(t3, a3, ...) long a3, __SC_LONG2(__VA_ARGS__) | 87 | #define __SC_LONG3(t3, a3, ...) long a3, __SC_LONG2(__VA_ARGS__) |
88 | #define __SC_LONG4(t4, a4, ...) long a4, __SC_LONG3(__VA_ARGS__) | 88 | #define __SC_LONG4(t4, a4, ...) long a4, __SC_LONG3(__VA_ARGS__) |
89 | #define __SC_LONG5(t5, a5, ...) long a5, __SC_LONG4(__VA_ARGS__) | 89 | #define __SC_LONG5(t5, a5, ...) long a5, __SC_LONG4(__VA_ARGS__) |
90 | #define __SC_LONG6(t6, a6, ...) long a6, __SC_LONG5(__VA_ARGS__) | 90 | #define __SC_LONG6(t6, a6, ...) long a6, __SC_LONG5(__VA_ARGS__) |
91 | 91 | ||
92 | #define __SC_CAST1(t1, a1) (t1) a1 | 92 | #define __SC_CAST1(t1, a1) (t1) a1 |
93 | #define __SC_CAST2(t2, a2, ...) (t2) a2, __SC_CAST1(__VA_ARGS__) | 93 | #define __SC_CAST2(t2, a2, ...) (t2) a2, __SC_CAST1(__VA_ARGS__) |
94 | #define __SC_CAST3(t3, a3, ...) (t3) a3, __SC_CAST2(__VA_ARGS__) | 94 | #define __SC_CAST3(t3, a3, ...) (t3) a3, __SC_CAST2(__VA_ARGS__) |
95 | #define __SC_CAST4(t4, a4, ...) (t4) a4, __SC_CAST3(__VA_ARGS__) | 95 | #define __SC_CAST4(t4, a4, ...) (t4) a4, __SC_CAST3(__VA_ARGS__) |
96 | #define __SC_CAST5(t5, a5, ...) (t5) a5, __SC_CAST4(__VA_ARGS__) | 96 | #define __SC_CAST5(t5, a5, ...) (t5) a5, __SC_CAST4(__VA_ARGS__) |
97 | #define __SC_CAST6(t6, a6, ...) (t6) a6, __SC_CAST5(__VA_ARGS__) | 97 | #define __SC_CAST6(t6, a6, ...) (t6) a6, __SC_CAST5(__VA_ARGS__) |
98 | 98 | ||
99 | #define __SC_TEST(type) BUILD_BUG_ON(sizeof(type) > sizeof(long)) | 99 | #define __SC_TEST(type) BUILD_BUG_ON(sizeof(type) > sizeof(long)) |
100 | #define __SC_TEST1(t1, a1) __SC_TEST(t1) | 100 | #define __SC_TEST1(t1, a1) __SC_TEST(t1) |
101 | #define __SC_TEST2(t2, a2, ...) __SC_TEST(t2); __SC_TEST1(__VA_ARGS__) | 101 | #define __SC_TEST2(t2, a2, ...) __SC_TEST(t2); __SC_TEST1(__VA_ARGS__) |
102 | #define __SC_TEST3(t3, a3, ...) __SC_TEST(t3); __SC_TEST2(__VA_ARGS__) | 102 | #define __SC_TEST3(t3, a3, ...) __SC_TEST(t3); __SC_TEST2(__VA_ARGS__) |
103 | #define __SC_TEST4(t4, a4, ...) __SC_TEST(t4); __SC_TEST3(__VA_ARGS__) | 103 | #define __SC_TEST4(t4, a4, ...) __SC_TEST(t4); __SC_TEST3(__VA_ARGS__) |
104 | #define __SC_TEST5(t5, a5, ...) __SC_TEST(t5); __SC_TEST4(__VA_ARGS__) | 104 | #define __SC_TEST5(t5, a5, ...) __SC_TEST(t5); __SC_TEST4(__VA_ARGS__) |
105 | #define __SC_TEST6(t6, a6, ...) __SC_TEST(t6); __SC_TEST5(__VA_ARGS__) | 105 | #define __SC_TEST6(t6, a6, ...) __SC_TEST(t6); __SC_TEST5(__VA_ARGS__) |
106 | 106 | ||
107 | #ifdef CONFIG_FTRACE_SYSCALLS | 107 | #ifdef CONFIG_FTRACE_SYSCALLS |
108 | #define __SC_STR_ADECL1(t, a) #a | 108 | #define __SC_STR_ADECL1(t, a) #a |
109 | #define __SC_STR_ADECL2(t, a, ...) #a, __SC_STR_ADECL1(__VA_ARGS__) | 109 | #define __SC_STR_ADECL2(t, a, ...) #a, __SC_STR_ADECL1(__VA_ARGS__) |
110 | #define __SC_STR_ADECL3(t, a, ...) #a, __SC_STR_ADECL2(__VA_ARGS__) | 110 | #define __SC_STR_ADECL3(t, a, ...) #a, __SC_STR_ADECL2(__VA_ARGS__) |
111 | #define __SC_STR_ADECL4(t, a, ...) #a, __SC_STR_ADECL3(__VA_ARGS__) | 111 | #define __SC_STR_ADECL4(t, a, ...) #a, __SC_STR_ADECL3(__VA_ARGS__) |
112 | #define __SC_STR_ADECL5(t, a, ...) #a, __SC_STR_ADECL4(__VA_ARGS__) | 112 | #define __SC_STR_ADECL5(t, a, ...) #a, __SC_STR_ADECL4(__VA_ARGS__) |
113 | #define __SC_STR_ADECL6(t, a, ...) #a, __SC_STR_ADECL5(__VA_ARGS__) | 113 | #define __SC_STR_ADECL6(t, a, ...) #a, __SC_STR_ADECL5(__VA_ARGS__) |
114 | 114 | ||
115 | #define __SC_STR_TDECL1(t, a) #t | 115 | #define __SC_STR_TDECL1(t, a) #t |
116 | #define __SC_STR_TDECL2(t, a, ...) #t, __SC_STR_TDECL1(__VA_ARGS__) | 116 | #define __SC_STR_TDECL2(t, a, ...) #t, __SC_STR_TDECL1(__VA_ARGS__) |
117 | #define __SC_STR_TDECL3(t, a, ...) #t, __SC_STR_TDECL2(__VA_ARGS__) | 117 | #define __SC_STR_TDECL3(t, a, ...) #t, __SC_STR_TDECL2(__VA_ARGS__) |
118 | #define __SC_STR_TDECL4(t, a, ...) #t, __SC_STR_TDECL3(__VA_ARGS__) | 118 | #define __SC_STR_TDECL4(t, a, ...) #t, __SC_STR_TDECL3(__VA_ARGS__) |
119 | #define __SC_STR_TDECL5(t, a, ...) #t, __SC_STR_TDECL4(__VA_ARGS__) | 119 | #define __SC_STR_TDECL5(t, a, ...) #t, __SC_STR_TDECL4(__VA_ARGS__) |
120 | #define __SC_STR_TDECL6(t, a, ...) #t, __SC_STR_TDECL5(__VA_ARGS__) | 120 | #define __SC_STR_TDECL6(t, a, ...) #t, __SC_STR_TDECL5(__VA_ARGS__) |
121 | 121 | ||
122 | extern struct ftrace_event_class event_class_syscall_enter; | 122 | extern struct ftrace_event_class event_class_syscall_enter; |
123 | extern struct ftrace_event_class event_class_syscall_exit; | 123 | extern struct ftrace_event_class event_class_syscall_exit; |
124 | extern struct trace_event_functions enter_syscall_print_funcs; | 124 | extern struct trace_event_functions enter_syscall_print_funcs; |
125 | extern struct trace_event_functions exit_syscall_print_funcs; | 125 | extern struct trace_event_functions exit_syscall_print_funcs; |
126 | 126 | ||
127 | #define SYSCALL_TRACE_ENTER_EVENT(sname) \ | 127 | #define SYSCALL_TRACE_ENTER_EVENT(sname) \ |
128 | static struct syscall_metadata \ | 128 | static struct syscall_metadata \ |
129 | __attribute__((__aligned__(4))) __syscall_meta_##sname; \ | 129 | __attribute__((__aligned__(4))) __syscall_meta_##sname; \ |
130 | static struct ftrace_event_call \ | 130 | static struct ftrace_event_call \ |
131 | __attribute__((__aligned__(4))) event_enter_##sname; \ | 131 | __attribute__((__aligned__(4))) event_enter_##sname; \ |
132 | static struct ftrace_event_call __used \ | 132 | static struct ftrace_event_call __used \ |
133 | __attribute__((__aligned__(4))) \ | 133 | __attribute__((__aligned__(4))) \ |
134 | __attribute__((section("_ftrace_events"))) \ | 134 | __attribute__((section("_ftrace_events"))) \ |
135 | event_enter_##sname = { \ | 135 | event_enter_##sname = { \ |
136 | .name = "sys_enter"#sname, \ | 136 | .name = "sys_enter"#sname, \ |
137 | .class = &event_class_syscall_enter, \ | 137 | .class = &event_class_syscall_enter, \ |
138 | .event.funcs = &enter_syscall_print_funcs, \ | 138 | .event.funcs = &enter_syscall_print_funcs, \ |
139 | .data = (void *)&__syscall_meta_##sname,\ | 139 | .data = (void *)&__syscall_meta_##sname,\ |
140 | } | 140 | } |
141 | 141 | ||
142 | #define SYSCALL_TRACE_EXIT_EVENT(sname) \ | 142 | #define SYSCALL_TRACE_EXIT_EVENT(sname) \ |
143 | static struct syscall_metadata \ | 143 | static struct syscall_metadata \ |
144 | __attribute__((__aligned__(4))) __syscall_meta_##sname; \ | 144 | __attribute__((__aligned__(4))) __syscall_meta_##sname; \ |
145 | static struct ftrace_event_call \ | 145 | static struct ftrace_event_call \ |
146 | __attribute__((__aligned__(4))) event_exit_##sname; \ | 146 | __attribute__((__aligned__(4))) event_exit_##sname; \ |
147 | static struct ftrace_event_call __used \ | 147 | static struct ftrace_event_call __used \ |
148 | __attribute__((__aligned__(4))) \ | 148 | __attribute__((__aligned__(4))) \ |
149 | __attribute__((section("_ftrace_events"))) \ | 149 | __attribute__((section("_ftrace_events"))) \ |
150 | event_exit_##sname = { \ | 150 | event_exit_##sname = { \ |
151 | .name = "sys_exit"#sname, \ | 151 | .name = "sys_exit"#sname, \ |
152 | .class = &event_class_syscall_exit, \ | 152 | .class = &event_class_syscall_exit, \ |
153 | .event.funcs = &exit_syscall_print_funcs, \ | 153 | .event.funcs = &exit_syscall_print_funcs, \ |
154 | .data = (void *)&__syscall_meta_##sname,\ | 154 | .data = (void *)&__syscall_meta_##sname,\ |
155 | } | 155 | } |
156 | 156 | ||
157 | #define SYSCALL_METADATA(sname, nb) \ | 157 | #define SYSCALL_METADATA(sname, nb) \ |
158 | SYSCALL_TRACE_ENTER_EVENT(sname); \ | 158 | SYSCALL_TRACE_ENTER_EVENT(sname); \ |
159 | SYSCALL_TRACE_EXIT_EVENT(sname); \ | 159 | SYSCALL_TRACE_EXIT_EVENT(sname); \ |
160 | static struct syscall_metadata __used \ | 160 | static struct syscall_metadata __used \ |
161 | __attribute__((__aligned__(4))) \ | 161 | __attribute__((__aligned__(4))) \ |
162 | __attribute__((section("__syscalls_metadata"))) \ | 162 | __attribute__((section("__syscalls_metadata"))) \ |
163 | __syscall_meta_##sname = { \ | 163 | __syscall_meta_##sname = { \ |
164 | .name = "sys"#sname, \ | 164 | .name = "sys"#sname, \ |
165 | .nb_args = nb, \ | 165 | .nb_args = nb, \ |
166 | .types = types_##sname, \ | 166 | .types = types_##sname, \ |
167 | .args = args_##sname, \ | 167 | .args = args_##sname, \ |
168 | .enter_event = &event_enter_##sname, \ | 168 | .enter_event = &event_enter_##sname, \ |
169 | .exit_event = &event_exit_##sname, \ | 169 | .exit_event = &event_exit_##sname, \ |
170 | .enter_fields = LIST_HEAD_INIT(__syscall_meta_##sname.enter_fields), \ | 170 | .enter_fields = LIST_HEAD_INIT(__syscall_meta_##sname.enter_fields), \ |
171 | }; | 171 | }; |
172 | 172 | ||
173 | #define SYSCALL_DEFINE0(sname) \ | 173 | #define SYSCALL_DEFINE0(sname) \ |
174 | SYSCALL_TRACE_ENTER_EVENT(_##sname); \ | 174 | SYSCALL_TRACE_ENTER_EVENT(_##sname); \ |
175 | SYSCALL_TRACE_EXIT_EVENT(_##sname); \ | 175 | SYSCALL_TRACE_EXIT_EVENT(_##sname); \ |
176 | static struct syscall_metadata __used \ | 176 | static struct syscall_metadata __used \ |
177 | __attribute__((__aligned__(4))) \ | 177 | __attribute__((__aligned__(4))) \ |
178 | __attribute__((section("__syscalls_metadata"))) \ | 178 | __attribute__((section("__syscalls_metadata"))) \ |
179 | __syscall_meta__##sname = { \ | 179 | __syscall_meta__##sname = { \ |
180 | .name = "sys_"#sname, \ | 180 | .name = "sys_"#sname, \ |
181 | .nb_args = 0, \ | 181 | .nb_args = 0, \ |
182 | .enter_event = &event_enter__##sname, \ | 182 | .enter_event = &event_enter__##sname, \ |
183 | .exit_event = &event_exit__##sname, \ | 183 | .exit_event = &event_exit__##sname, \ |
184 | .enter_fields = LIST_HEAD_INIT(__syscall_meta__##sname.enter_fields), \ | 184 | .enter_fields = LIST_HEAD_INIT(__syscall_meta__##sname.enter_fields), \ |
185 | }; \ | 185 | }; \ |
186 | asmlinkage long sys_##sname(void) | 186 | asmlinkage long sys_##sname(void) |
187 | #else | 187 | #else |
188 | #define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void) | 188 | #define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void) |
189 | #endif | 189 | #endif |
190 | 190 | ||
191 | #define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__) | 191 | #define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__) |
192 | #define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__) | 192 | #define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__) |
193 | #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__) | 193 | #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__) |
194 | #define SYSCALL_DEFINE4(name, ...) SYSCALL_DEFINEx(4, _##name, __VA_ARGS__) | 194 | #define SYSCALL_DEFINE4(name, ...) SYSCALL_DEFINEx(4, _##name, __VA_ARGS__) |
195 | #define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__) | 195 | #define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__) |
196 | #define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__) | 196 | #define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__) |
197 | 197 | ||
198 | #ifdef CONFIG_PPC64 | 198 | #ifdef CONFIG_PPC64 |
199 | #define SYSCALL_ALIAS(alias, name) \ | 199 | #define SYSCALL_ALIAS(alias, name) \ |
200 | asm ("\t.globl " #alias "\n\t.set " #alias ", " #name "\n" \ | 200 | asm ("\t.globl " #alias "\n\t.set " #alias ", " #name "\n" \ |
201 | "\t.globl ." #alias "\n\t.set ." #alias ", ." #name) | 201 | "\t.globl ." #alias "\n\t.set ." #alias ", ." #name) |
202 | #else | 202 | #else |
203 | #if defined(CONFIG_ALPHA) || defined(CONFIG_MIPS) | 203 | #if defined(CONFIG_ALPHA) || defined(CONFIG_MIPS) |
204 | #define SYSCALL_ALIAS(alias, name) \ | 204 | #define SYSCALL_ALIAS(alias, name) \ |
205 | asm ( #alias " = " #name "\n\t.globl " #alias) | 205 | asm ( #alias " = " #name "\n\t.globl " #alias) |
206 | #else | 206 | #else |
207 | #define SYSCALL_ALIAS(alias, name) \ | 207 | #define SYSCALL_ALIAS(alias, name) \ |
208 | asm ("\t.globl " #alias "\n\t.set " #alias ", " #name) | 208 | asm ("\t.globl " #alias "\n\t.set " #alias ", " #name) |
209 | #endif | 209 | #endif |
210 | #endif | 210 | #endif |
211 | 211 | ||
212 | #ifdef CONFIG_FTRACE_SYSCALLS | 212 | #ifdef CONFIG_FTRACE_SYSCALLS |
213 | #define SYSCALL_DEFINEx(x, sname, ...) \ | 213 | #define SYSCALL_DEFINEx(x, sname, ...) \ |
214 | static const char *types_##sname[] = { \ | 214 | static const char *types_##sname[] = { \ |
215 | __SC_STR_TDECL##x(__VA_ARGS__) \ | 215 | __SC_STR_TDECL##x(__VA_ARGS__) \ |
216 | }; \ | 216 | }; \ |
217 | static const char *args_##sname[] = { \ | 217 | static const char *args_##sname[] = { \ |
218 | __SC_STR_ADECL##x(__VA_ARGS__) \ | 218 | __SC_STR_ADECL##x(__VA_ARGS__) \ |
219 | }; \ | 219 | }; \ |
220 | SYSCALL_METADATA(sname, x); \ | 220 | SYSCALL_METADATA(sname, x); \ |
221 | __SYSCALL_DEFINEx(x, sname, __VA_ARGS__) | 221 | __SYSCALL_DEFINEx(x, sname, __VA_ARGS__) |
222 | #else | 222 | #else |
223 | #define SYSCALL_DEFINEx(x, sname, ...) \ | 223 | #define SYSCALL_DEFINEx(x, sname, ...) \ |
224 | __SYSCALL_DEFINEx(x, sname, __VA_ARGS__) | 224 | __SYSCALL_DEFINEx(x, sname, __VA_ARGS__) |
225 | #endif | 225 | #endif |
226 | 226 | ||
227 | #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS | 227 | #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS |
228 | 228 | ||
229 | #define SYSCALL_DEFINE(name) static inline long SYSC_##name | 229 | #define SYSCALL_DEFINE(name) static inline long SYSC_##name |
230 | 230 | ||
231 | #define __SYSCALL_DEFINEx(x, name, ...) \ | 231 | #define __SYSCALL_DEFINEx(x, name, ...) \ |
232 | asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__)); \ | 232 | asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__)); \ |
233 | static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__)); \ | 233 | static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__)); \ |
234 | asmlinkage long SyS##name(__SC_LONG##x(__VA_ARGS__)) \ | 234 | asmlinkage long SyS##name(__SC_LONG##x(__VA_ARGS__)) \ |
235 | { \ | 235 | { \ |
236 | __SC_TEST##x(__VA_ARGS__); \ | 236 | __SC_TEST##x(__VA_ARGS__); \ |
237 | return (long) SYSC##name(__SC_CAST##x(__VA_ARGS__)); \ | 237 | return (long) SYSC##name(__SC_CAST##x(__VA_ARGS__)); \ |
238 | } \ | 238 | } \ |
239 | SYSCALL_ALIAS(sys##name, SyS##name); \ | 239 | SYSCALL_ALIAS(sys##name, SyS##name); \ |
240 | static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__)) | 240 | static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__)) |
241 | 241 | ||
242 | #else /* CONFIG_HAVE_SYSCALL_WRAPPERS */ | 242 | #else /* CONFIG_HAVE_SYSCALL_WRAPPERS */ |
243 | 243 | ||
244 | #define SYSCALL_DEFINE(name) asmlinkage long sys_##name | 244 | #define SYSCALL_DEFINE(name) asmlinkage long sys_##name |
245 | #define __SYSCALL_DEFINEx(x, name, ...) \ | 245 | #define __SYSCALL_DEFINEx(x, name, ...) \ |
246 | asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__)) | 246 | asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__)) |
247 | 247 | ||
248 | #endif /* CONFIG_HAVE_SYSCALL_WRAPPERS */ | 248 | #endif /* CONFIG_HAVE_SYSCALL_WRAPPERS */ |
249 | 249 | ||
250 | asmlinkage long sys_time(time_t __user *tloc); | 250 | asmlinkage long sys_time(time_t __user *tloc); |
251 | asmlinkage long sys_stime(time_t __user *tptr); | 251 | asmlinkage long sys_stime(time_t __user *tptr); |
252 | asmlinkage long sys_gettimeofday(struct timeval __user *tv, | 252 | asmlinkage long sys_gettimeofday(struct timeval __user *tv, |
253 | struct timezone __user *tz); | 253 | struct timezone __user *tz); |
254 | asmlinkage long sys_settimeofday(struct timeval __user *tv, | 254 | asmlinkage long sys_settimeofday(struct timeval __user *tv, |
255 | struct timezone __user *tz); | 255 | struct timezone __user *tz); |
256 | asmlinkage long sys_adjtimex(struct timex __user *txc_p); | 256 | asmlinkage long sys_adjtimex(struct timex __user *txc_p); |
257 | 257 | ||
258 | asmlinkage long sys_times(struct tms __user *tbuf); | 258 | asmlinkage long sys_times(struct tms __user *tbuf); |
259 | 259 | ||
260 | asmlinkage long sys_gettid(void); | 260 | asmlinkage long sys_gettid(void); |
261 | asmlinkage long sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp); | 261 | asmlinkage long sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp); |
262 | asmlinkage long sys_alarm(unsigned int seconds); | 262 | asmlinkage long sys_alarm(unsigned int seconds); |
263 | asmlinkage long sys_getpid(void); | 263 | asmlinkage long sys_getpid(void); |
264 | asmlinkage long sys_getppid(void); | 264 | asmlinkage long sys_getppid(void); |
265 | asmlinkage long sys_getuid(void); | 265 | asmlinkage long sys_getuid(void); |
266 | asmlinkage long sys_geteuid(void); | 266 | asmlinkage long sys_geteuid(void); |
267 | asmlinkage long sys_getgid(void); | 267 | asmlinkage long sys_getgid(void); |
268 | asmlinkage long sys_getegid(void); | 268 | asmlinkage long sys_getegid(void); |
269 | asmlinkage long sys_getresuid(uid_t __user *ruid, uid_t __user *euid, uid_t __user *suid); | 269 | asmlinkage long sys_getresuid(uid_t __user *ruid, uid_t __user *euid, uid_t __user *suid); |
270 | asmlinkage long sys_getresgid(gid_t __user *rgid, gid_t __user *egid, gid_t __user *sgid); | 270 | asmlinkage long sys_getresgid(gid_t __user *rgid, gid_t __user *egid, gid_t __user *sgid); |
271 | asmlinkage long sys_getpgid(pid_t pid); | 271 | asmlinkage long sys_getpgid(pid_t pid); |
272 | asmlinkage long sys_getpgrp(void); | 272 | asmlinkage long sys_getpgrp(void); |
273 | asmlinkage long sys_getsid(pid_t pid); | 273 | asmlinkage long sys_getsid(pid_t pid); |
274 | asmlinkage long sys_getgroups(int gidsetsize, gid_t __user *grouplist); | 274 | asmlinkage long sys_getgroups(int gidsetsize, gid_t __user *grouplist); |
275 | 275 | ||
276 | asmlinkage long sys_setregid(gid_t rgid, gid_t egid); | 276 | asmlinkage long sys_setregid(gid_t rgid, gid_t egid); |
277 | asmlinkage long sys_setgid(gid_t gid); | 277 | asmlinkage long sys_setgid(gid_t gid); |
278 | asmlinkage long sys_setreuid(uid_t ruid, uid_t euid); | 278 | asmlinkage long sys_setreuid(uid_t ruid, uid_t euid); |
279 | asmlinkage long sys_setuid(uid_t uid); | 279 | asmlinkage long sys_setuid(uid_t uid); |
280 | asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid); | 280 | asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid); |
281 | asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid); | 281 | asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid); |
282 | asmlinkage long sys_setfsuid(uid_t uid); | 282 | asmlinkage long sys_setfsuid(uid_t uid); |
283 | asmlinkage long sys_setfsgid(gid_t gid); | 283 | asmlinkage long sys_setfsgid(gid_t gid); |
284 | asmlinkage long sys_setpgid(pid_t pid, pid_t pgid); | 284 | asmlinkage long sys_setpgid(pid_t pid, pid_t pgid); |
285 | asmlinkage long sys_setsid(void); | 285 | asmlinkage long sys_setsid(void); |
286 | asmlinkage long sys_setgroups(int gidsetsize, gid_t __user *grouplist); | 286 | asmlinkage long sys_setgroups(int gidsetsize, gid_t __user *grouplist); |
287 | 287 | ||
288 | asmlinkage long sys_acct(const char __user *name); | 288 | asmlinkage long sys_acct(const char __user *name); |
289 | asmlinkage long sys_capget(cap_user_header_t header, | 289 | asmlinkage long sys_capget(cap_user_header_t header, |
290 | cap_user_data_t dataptr); | 290 | cap_user_data_t dataptr); |
291 | asmlinkage long sys_capset(cap_user_header_t header, | 291 | asmlinkage long sys_capset(cap_user_header_t header, |
292 | const cap_user_data_t data); | 292 | const cap_user_data_t data); |
293 | asmlinkage long sys_personality(unsigned int personality); | 293 | asmlinkage long sys_personality(unsigned int personality); |
294 | 294 | ||
295 | asmlinkage long sys_sigpending(old_sigset_t __user *set); | 295 | asmlinkage long sys_sigpending(old_sigset_t __user *set); |
296 | asmlinkage long sys_sigprocmask(int how, old_sigset_t __user *set, | 296 | asmlinkage long sys_sigprocmask(int how, old_sigset_t __user *set, |
297 | old_sigset_t __user *oset); | 297 | old_sigset_t __user *oset); |
298 | asmlinkage long sys_getitimer(int which, struct itimerval __user *value); | 298 | asmlinkage long sys_getitimer(int which, struct itimerval __user *value); |
299 | asmlinkage long sys_setitimer(int which, | 299 | asmlinkage long sys_setitimer(int which, |
300 | struct itimerval __user *value, | 300 | struct itimerval __user *value, |
301 | struct itimerval __user *ovalue); | 301 | struct itimerval __user *ovalue); |
302 | asmlinkage long sys_timer_create(clockid_t which_clock, | 302 | asmlinkage long sys_timer_create(clockid_t which_clock, |
303 | struct sigevent __user *timer_event_spec, | 303 | struct sigevent __user *timer_event_spec, |
304 | timer_t __user * created_timer_id); | 304 | timer_t __user * created_timer_id); |
305 | asmlinkage long sys_timer_gettime(timer_t timer_id, | 305 | asmlinkage long sys_timer_gettime(timer_t timer_id, |
306 | struct itimerspec __user *setting); | 306 | struct itimerspec __user *setting); |
307 | asmlinkage long sys_timer_getoverrun(timer_t timer_id); | 307 | asmlinkage long sys_timer_getoverrun(timer_t timer_id); |
308 | asmlinkage long sys_timer_settime(timer_t timer_id, int flags, | 308 | asmlinkage long sys_timer_settime(timer_t timer_id, int flags, |
309 | const struct itimerspec __user *new_setting, | 309 | const struct itimerspec __user *new_setting, |
310 | struct itimerspec __user *old_setting); | 310 | struct itimerspec __user *old_setting); |
311 | asmlinkage long sys_timer_delete(timer_t timer_id); | 311 | asmlinkage long sys_timer_delete(timer_t timer_id); |
312 | asmlinkage long sys_clock_settime(clockid_t which_clock, | 312 | asmlinkage long sys_clock_settime(clockid_t which_clock, |
313 | const struct timespec __user *tp); | 313 | const struct timespec __user *tp); |
314 | asmlinkage long sys_clock_gettime(clockid_t which_clock, | 314 | asmlinkage long sys_clock_gettime(clockid_t which_clock, |
315 | struct timespec __user *tp); | 315 | struct timespec __user *tp); |
316 | asmlinkage long sys_clock_getres(clockid_t which_clock, | 316 | asmlinkage long sys_clock_getres(clockid_t which_clock, |
317 | struct timespec __user *tp); | 317 | struct timespec __user *tp); |
318 | asmlinkage long sys_clock_nanosleep(clockid_t which_clock, int flags, | 318 | asmlinkage long sys_clock_nanosleep(clockid_t which_clock, int flags, |
319 | const struct timespec __user *rqtp, | 319 | const struct timespec __user *rqtp, |
320 | struct timespec __user *rmtp); | 320 | struct timespec __user *rmtp); |
321 | 321 | ||
322 | asmlinkage long sys_nice(int increment); | 322 | asmlinkage long sys_nice(int increment); |
323 | asmlinkage long sys_sched_setscheduler(pid_t pid, int policy, | 323 | asmlinkage long sys_sched_setscheduler(pid_t pid, int policy, |
324 | struct sched_param __user *param); | 324 | struct sched_param __user *param); |
325 | asmlinkage long sys_sched_setparam(pid_t pid, | 325 | asmlinkage long sys_sched_setparam(pid_t pid, |
326 | struct sched_param __user *param); | 326 | struct sched_param __user *param); |
327 | asmlinkage long sys_sched_getscheduler(pid_t pid); | 327 | asmlinkage long sys_sched_getscheduler(pid_t pid); |
328 | asmlinkage long sys_sched_getparam(pid_t pid, | 328 | asmlinkage long sys_sched_getparam(pid_t pid, |
329 | struct sched_param __user *param); | 329 | struct sched_param __user *param); |
330 | asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len, | 330 | asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len, |
331 | unsigned long __user *user_mask_ptr); | 331 | unsigned long __user *user_mask_ptr); |
332 | asmlinkage long sys_sched_getaffinity(pid_t pid, unsigned int len, | 332 | asmlinkage long sys_sched_getaffinity(pid_t pid, unsigned int len, |
333 | unsigned long __user *user_mask_ptr); | 333 | unsigned long __user *user_mask_ptr); |
334 | asmlinkage long sys_sched_yield(void); | 334 | asmlinkage long sys_sched_yield(void); |
335 | asmlinkage long sys_sched_get_priority_max(int policy); | 335 | asmlinkage long sys_sched_get_priority_max(int policy); |
336 | asmlinkage long sys_sched_get_priority_min(int policy); | 336 | asmlinkage long sys_sched_get_priority_min(int policy); |
337 | asmlinkage long sys_sched_rr_get_interval(pid_t pid, | 337 | asmlinkage long sys_sched_rr_get_interval(pid_t pid, |
338 | struct timespec __user *interval); | 338 | struct timespec __user *interval); |
339 | asmlinkage long sys_setpriority(int which, int who, int niceval); | 339 | asmlinkage long sys_setpriority(int which, int who, int niceval); |
340 | asmlinkage long sys_getpriority(int which, int who); | 340 | asmlinkage long sys_getpriority(int which, int who); |
341 | 341 | ||
342 | asmlinkage long sys_shutdown(int, int); | 342 | asmlinkage long sys_shutdown(int, int); |
343 | asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, | 343 | asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, |
344 | void __user *arg); | 344 | void __user *arg); |
345 | asmlinkage long sys_restart_syscall(void); | 345 | asmlinkage long sys_restart_syscall(void); |
346 | asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments, | 346 | asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments, |
347 | struct kexec_segment __user *segments, | 347 | struct kexec_segment __user *segments, |
348 | unsigned long flags); | 348 | unsigned long flags); |
349 | 349 | ||
350 | asmlinkage long sys_exit(int error_code); | 350 | asmlinkage long sys_exit(int error_code); |
351 | asmlinkage long sys_exit_group(int error_code); | 351 | asmlinkage long sys_exit_group(int error_code); |
352 | asmlinkage long sys_wait4(pid_t pid, int __user *stat_addr, | 352 | asmlinkage long sys_wait4(pid_t pid, int __user *stat_addr, |
353 | int options, struct rusage __user *ru); | 353 | int options, struct rusage __user *ru); |
354 | asmlinkage long sys_waitid(int which, pid_t pid, | 354 | asmlinkage long sys_waitid(int which, pid_t pid, |
355 | struct siginfo __user *infop, | 355 | struct siginfo __user *infop, |
356 | int options, struct rusage __user *ru); | 356 | int options, struct rusage __user *ru); |
357 | asmlinkage long sys_waitpid(pid_t pid, int __user *stat_addr, int options); | 357 | asmlinkage long sys_waitpid(pid_t pid, int __user *stat_addr, int options); |
358 | asmlinkage long sys_set_tid_address(int __user *tidptr); | 358 | asmlinkage long sys_set_tid_address(int __user *tidptr); |
359 | asmlinkage long sys_futex(u32 __user *uaddr, int op, u32 val, | 359 | asmlinkage long sys_futex(u32 __user *uaddr, int op, u32 val, |
360 | struct timespec __user *utime, u32 __user *uaddr2, | 360 | struct timespec __user *utime, u32 __user *uaddr2, |
361 | u32 val3); | 361 | u32 val3); |
362 | 362 | ||
363 | asmlinkage long sys_init_module(void __user *umod, unsigned long len, | 363 | asmlinkage long sys_init_module(void __user *umod, unsigned long len, |
364 | const char __user *uargs); | 364 | const char __user *uargs); |
365 | asmlinkage long sys_delete_module(const char __user *name_user, | 365 | asmlinkage long sys_delete_module(const char __user *name_user, |
366 | unsigned int flags); | 366 | unsigned int flags); |
367 | 367 | ||
368 | asmlinkage long sys_rt_sigprocmask(int how, sigset_t __user *set, | 368 | asmlinkage long sys_rt_sigprocmask(int how, sigset_t __user *set, |
369 | sigset_t __user *oset, size_t sigsetsize); | 369 | sigset_t __user *oset, size_t sigsetsize); |
370 | asmlinkage long sys_rt_sigpending(sigset_t __user *set, size_t sigsetsize); | 370 | asmlinkage long sys_rt_sigpending(sigset_t __user *set, size_t sigsetsize); |
371 | asmlinkage long sys_rt_sigtimedwait(const sigset_t __user *uthese, | 371 | asmlinkage long sys_rt_sigtimedwait(const sigset_t __user *uthese, |
372 | siginfo_t __user *uinfo, | 372 | siginfo_t __user *uinfo, |
373 | const struct timespec __user *uts, | 373 | const struct timespec __user *uts, |
374 | size_t sigsetsize); | 374 | size_t sigsetsize); |
375 | asmlinkage long sys_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, | 375 | asmlinkage long sys_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, |
376 | siginfo_t __user *uinfo); | 376 | siginfo_t __user *uinfo); |
377 | asmlinkage long sys_kill(int pid, int sig); | 377 | asmlinkage long sys_kill(int pid, int sig); |
378 | asmlinkage long sys_tgkill(int tgid, int pid, int sig); | 378 | asmlinkage long sys_tgkill(int tgid, int pid, int sig); |
379 | asmlinkage long sys_tkill(int pid, int sig); | 379 | asmlinkage long sys_tkill(int pid, int sig); |
380 | asmlinkage long sys_rt_sigqueueinfo(int pid, int sig, siginfo_t __user *uinfo); | 380 | asmlinkage long sys_rt_sigqueueinfo(int pid, int sig, siginfo_t __user *uinfo); |
381 | asmlinkage long sys_sgetmask(void); | 381 | asmlinkage long sys_sgetmask(void); |
382 | asmlinkage long sys_ssetmask(int newmask); | 382 | asmlinkage long sys_ssetmask(int newmask); |
383 | asmlinkage long sys_signal(int sig, __sighandler_t handler); | 383 | asmlinkage long sys_signal(int sig, __sighandler_t handler); |
384 | asmlinkage long sys_pause(void); | 384 | asmlinkage long sys_pause(void); |
385 | 385 | ||
386 | asmlinkage long sys_sync(void); | 386 | asmlinkage long sys_sync(void); |
387 | asmlinkage long sys_fsync(unsigned int fd); | 387 | asmlinkage long sys_fsync(unsigned int fd); |
388 | asmlinkage long sys_fdatasync(unsigned int fd); | 388 | asmlinkage long sys_fdatasync(unsigned int fd); |
389 | asmlinkage long sys_bdflush(int func, long data); | 389 | asmlinkage long sys_bdflush(int func, long data); |
390 | asmlinkage long sys_mount(char __user *dev_name, char __user *dir_name, | 390 | asmlinkage long sys_mount(char __user *dev_name, char __user *dir_name, |
391 | char __user *type, unsigned long flags, | 391 | char __user *type, unsigned long flags, |
392 | void __user *data); | 392 | void __user *data); |
393 | asmlinkage long sys_umount(char __user *name, int flags); | 393 | asmlinkage long sys_umount(char __user *name, int flags); |
394 | asmlinkage long sys_oldumount(char __user *name); | 394 | asmlinkage long sys_oldumount(char __user *name); |
395 | asmlinkage long sys_truncate(const char __user *path, long length); | 395 | asmlinkage long sys_truncate(const char __user *path, long length); |
396 | asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length); | 396 | asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length); |
397 | asmlinkage long sys_stat(const char __user *filename, | 397 | asmlinkage long sys_stat(const char __user *filename, |
398 | struct __old_kernel_stat __user *statbuf); | 398 | struct __old_kernel_stat __user *statbuf); |
399 | asmlinkage long sys_statfs(const char __user * path, | 399 | asmlinkage long sys_statfs(const char __user * path, |
400 | struct statfs __user *buf); | 400 | struct statfs __user *buf); |
401 | asmlinkage long sys_statfs64(const char __user *path, size_t sz, | 401 | asmlinkage long sys_statfs64(const char __user *path, size_t sz, |
402 | struct statfs64 __user *buf); | 402 | struct statfs64 __user *buf); |
403 | asmlinkage long sys_fstatfs(unsigned int fd, struct statfs __user *buf); | 403 | asmlinkage long sys_fstatfs(unsigned int fd, struct statfs __user *buf); |
404 | asmlinkage long sys_fstatfs64(unsigned int fd, size_t sz, | 404 | asmlinkage long sys_fstatfs64(unsigned int fd, size_t sz, |
405 | struct statfs64 __user *buf); | 405 | struct statfs64 __user *buf); |
406 | asmlinkage long sys_lstat(const char __user *filename, | 406 | asmlinkage long sys_lstat(const char __user *filename, |
407 | struct __old_kernel_stat __user *statbuf); | 407 | struct __old_kernel_stat __user *statbuf); |
408 | asmlinkage long sys_fstat(unsigned int fd, | 408 | asmlinkage long sys_fstat(unsigned int fd, |
409 | struct __old_kernel_stat __user *statbuf); | 409 | struct __old_kernel_stat __user *statbuf); |
410 | asmlinkage long sys_newstat(const char __user *filename, | 410 | asmlinkage long sys_newstat(const char __user *filename, |
411 | struct stat __user *statbuf); | 411 | struct stat __user *statbuf); |
412 | asmlinkage long sys_newlstat(const char __user *filename, | 412 | asmlinkage long sys_newlstat(const char __user *filename, |
413 | struct stat __user *statbuf); | 413 | struct stat __user *statbuf); |
414 | asmlinkage long sys_newfstat(unsigned int fd, struct stat __user *statbuf); | 414 | asmlinkage long sys_newfstat(unsigned int fd, struct stat __user *statbuf); |
415 | asmlinkage long sys_ustat(unsigned dev, struct ustat __user *ubuf); | 415 | asmlinkage long sys_ustat(unsigned dev, struct ustat __user *ubuf); |
416 | #if BITS_PER_LONG == 32 | 416 | #if BITS_PER_LONG == 32 |
417 | asmlinkage long sys_stat64(const char __user *filename, | 417 | asmlinkage long sys_stat64(const char __user *filename, |
418 | struct stat64 __user *statbuf); | 418 | struct stat64 __user *statbuf); |
419 | asmlinkage long sys_fstat64(unsigned long fd, struct stat64 __user *statbuf); | 419 | asmlinkage long sys_fstat64(unsigned long fd, struct stat64 __user *statbuf); |
420 | asmlinkage long sys_lstat64(const char __user *filename, | 420 | asmlinkage long sys_lstat64(const char __user *filename, |
421 | struct stat64 __user *statbuf); | 421 | struct stat64 __user *statbuf); |
422 | asmlinkage long sys_truncate64(const char __user *path, loff_t length); | 422 | asmlinkage long sys_truncate64(const char __user *path, loff_t length); |
423 | asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length); | 423 | asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length); |
424 | #endif | 424 | #endif |
425 | 425 | ||
426 | asmlinkage long sys_setxattr(const char __user *path, const char __user *name, | 426 | asmlinkage long sys_setxattr(const char __user *path, const char __user *name, |
427 | const void __user *value, size_t size, int flags); | 427 | const void __user *value, size_t size, int flags); |
428 | asmlinkage long sys_lsetxattr(const char __user *path, const char __user *name, | 428 | asmlinkage long sys_lsetxattr(const char __user *path, const char __user *name, |
429 | const void __user *value, size_t size, int flags); | 429 | const void __user *value, size_t size, int flags); |
430 | asmlinkage long sys_fsetxattr(int fd, const char __user *name, | 430 | asmlinkage long sys_fsetxattr(int fd, const char __user *name, |
431 | const void __user *value, size_t size, int flags); | 431 | const void __user *value, size_t size, int flags); |
432 | asmlinkage long sys_getxattr(const char __user *path, const char __user *name, | 432 | asmlinkage long sys_getxattr(const char __user *path, const char __user *name, |
433 | void __user *value, size_t size); | 433 | void __user *value, size_t size); |
434 | asmlinkage long sys_lgetxattr(const char __user *path, const char __user *name, | 434 | asmlinkage long sys_lgetxattr(const char __user *path, const char __user *name, |
435 | void __user *value, size_t size); | 435 | void __user *value, size_t size); |
436 | asmlinkage long sys_fgetxattr(int fd, const char __user *name, | 436 | asmlinkage long sys_fgetxattr(int fd, const char __user *name, |
437 | void __user *value, size_t size); | 437 | void __user *value, size_t size); |
438 | asmlinkage long sys_listxattr(const char __user *path, char __user *list, | 438 | asmlinkage long sys_listxattr(const char __user *path, char __user *list, |
439 | size_t size); | 439 | size_t size); |
440 | asmlinkage long sys_llistxattr(const char __user *path, char __user *list, | 440 | asmlinkage long sys_llistxattr(const char __user *path, char __user *list, |
441 | size_t size); | 441 | size_t size); |
442 | asmlinkage long sys_flistxattr(int fd, char __user *list, size_t size); | 442 | asmlinkage long sys_flistxattr(int fd, char __user *list, size_t size); |
443 | asmlinkage long sys_removexattr(const char __user *path, | 443 | asmlinkage long sys_removexattr(const char __user *path, |
444 | const char __user *name); | 444 | const char __user *name); |
445 | asmlinkage long sys_lremovexattr(const char __user *path, | 445 | asmlinkage long sys_lremovexattr(const char __user *path, |
446 | const char __user *name); | 446 | const char __user *name); |
447 | asmlinkage long sys_fremovexattr(int fd, const char __user *name); | 447 | asmlinkage long sys_fremovexattr(int fd, const char __user *name); |
448 | 448 | ||
449 | asmlinkage long sys_brk(unsigned long brk); | 449 | asmlinkage long sys_brk(unsigned long brk); |
450 | asmlinkage long sys_mprotect(unsigned long start, size_t len, | 450 | asmlinkage long sys_mprotect(unsigned long start, size_t len, |
451 | unsigned long prot); | 451 | unsigned long prot); |
452 | asmlinkage long sys_mremap(unsigned long addr, | 452 | asmlinkage long sys_mremap(unsigned long addr, |
453 | unsigned long old_len, unsigned long new_len, | 453 | unsigned long old_len, unsigned long new_len, |
454 | unsigned long flags, unsigned long new_addr); | 454 | unsigned long flags, unsigned long new_addr); |
455 | asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size, | 455 | asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size, |
456 | unsigned long prot, unsigned long pgoff, | 456 | unsigned long prot, unsigned long pgoff, |
457 | unsigned long flags); | 457 | unsigned long flags); |
458 | asmlinkage long sys_msync(unsigned long start, size_t len, int flags); | 458 | asmlinkage long sys_msync(unsigned long start, size_t len, int flags); |
459 | asmlinkage long sys_fadvise64(int fd, loff_t offset, size_t len, int advice); | 459 | asmlinkage long sys_fadvise64(int fd, loff_t offset, size_t len, int advice); |
460 | asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice); | 460 | asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice); |
461 | asmlinkage long sys_munmap(unsigned long addr, size_t len); | 461 | asmlinkage long sys_munmap(unsigned long addr, size_t len); |
462 | asmlinkage long sys_mlock(unsigned long start, size_t len); | 462 | asmlinkage long sys_mlock(unsigned long start, size_t len); |
463 | asmlinkage long sys_munlock(unsigned long start, size_t len); | 463 | asmlinkage long sys_munlock(unsigned long start, size_t len); |
464 | asmlinkage long sys_mlockall(int flags); | 464 | asmlinkage long sys_mlockall(int flags); |
465 | asmlinkage long sys_munlockall(void); | 465 | asmlinkage long sys_munlockall(void); |
466 | asmlinkage long sys_madvise(unsigned long start, size_t len, int behavior); | 466 | asmlinkage long sys_madvise(unsigned long start, size_t len, int behavior); |
467 | asmlinkage long sys_mincore(unsigned long start, size_t len, | 467 | asmlinkage long sys_mincore(unsigned long start, size_t len, |
468 | unsigned char __user * vec); | 468 | unsigned char __user * vec); |
469 | 469 | ||
470 | asmlinkage long sys_pivot_root(const char __user *new_root, | 470 | asmlinkage long sys_pivot_root(const char __user *new_root, |
471 | const char __user *put_old); | 471 | const char __user *put_old); |
472 | asmlinkage long sys_chroot(const char __user *filename); | 472 | asmlinkage long sys_chroot(const char __user *filename); |
473 | asmlinkage long sys_mknod(const char __user *filename, int mode, | 473 | asmlinkage long sys_mknod(const char __user *filename, int mode, |
474 | unsigned dev); | 474 | unsigned dev); |
475 | asmlinkage long sys_link(const char __user *oldname, | 475 | asmlinkage long sys_link(const char __user *oldname, |
476 | const char __user *newname); | 476 | const char __user *newname); |
477 | asmlinkage long sys_symlink(const char __user *old, const char __user *new); | 477 | asmlinkage long sys_symlink(const char __user *old, const char __user *new); |
478 | asmlinkage long sys_unlink(const char __user *pathname); | 478 | asmlinkage long sys_unlink(const char __user *pathname); |
479 | asmlinkage long sys_rename(const char __user *oldname, | 479 | asmlinkage long sys_rename(const char __user *oldname, |
480 | const char __user *newname); | 480 | const char __user *newname); |
481 | asmlinkage long sys_chmod(const char __user *filename, mode_t mode); | 481 | asmlinkage long sys_chmod(const char __user *filename, mode_t mode); |
482 | asmlinkage long sys_fchmod(unsigned int fd, mode_t mode); | 482 | asmlinkage long sys_fchmod(unsigned int fd, mode_t mode); |
483 | 483 | ||
484 | asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg); | 484 | asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg); |
485 | #if BITS_PER_LONG == 32 | 485 | #if BITS_PER_LONG == 32 |
486 | asmlinkage long sys_fcntl64(unsigned int fd, | 486 | asmlinkage long sys_fcntl64(unsigned int fd, |
487 | unsigned int cmd, unsigned long arg); | 487 | unsigned int cmd, unsigned long arg); |
488 | #endif | 488 | #endif |
489 | asmlinkage long sys_pipe(int __user *fildes); | 489 | asmlinkage long sys_pipe(int __user *fildes); |
490 | asmlinkage long sys_pipe2(int __user *fildes, int flags); | 490 | asmlinkage long sys_pipe2(int __user *fildes, int flags); |
491 | asmlinkage long sys_dup(unsigned int fildes); | 491 | asmlinkage long sys_dup(unsigned int fildes); |
492 | asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd); | 492 | asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd); |
493 | asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags); | 493 | asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags); |
494 | asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int on); | 494 | asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int on); |
495 | asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, | 495 | asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, |
496 | unsigned long arg); | 496 | unsigned long arg); |
497 | asmlinkage long sys_flock(unsigned int fd, unsigned int cmd); | 497 | asmlinkage long sys_flock(unsigned int fd, unsigned int cmd); |
498 | asmlinkage long sys_io_setup(unsigned nr_reqs, aio_context_t __user *ctx); | 498 | asmlinkage long sys_io_setup(unsigned nr_reqs, aio_context_t __user *ctx); |
499 | asmlinkage long sys_io_destroy(aio_context_t ctx); | 499 | asmlinkage long sys_io_destroy(aio_context_t ctx); |
500 | asmlinkage long sys_io_getevents(aio_context_t ctx_id, | 500 | asmlinkage long sys_io_getevents(aio_context_t ctx_id, |
501 | long min_nr, | 501 | long min_nr, |
502 | long nr, | 502 | long nr, |
503 | struct io_event __user *events, | 503 | struct io_event __user *events, |
504 | struct timespec __user *timeout); | 504 | struct timespec __user *timeout); |
505 | asmlinkage long sys_io_submit(aio_context_t, long, | 505 | asmlinkage long sys_io_submit(aio_context_t, long, |
506 | struct iocb __user * __user *); | 506 | struct iocb __user * __user *); |
507 | asmlinkage long sys_io_cancel(aio_context_t ctx_id, struct iocb __user *iocb, | 507 | asmlinkage long sys_io_cancel(aio_context_t ctx_id, struct iocb __user *iocb, |
508 | struct io_event __user *result); | 508 | struct io_event __user *result); |
509 | asmlinkage long sys_sendfile(int out_fd, int in_fd, | 509 | asmlinkage long sys_sendfile(int out_fd, int in_fd, |
510 | off_t __user *offset, size_t count); | 510 | off_t __user *offset, size_t count); |
511 | asmlinkage long sys_sendfile64(int out_fd, int in_fd, | 511 | asmlinkage long sys_sendfile64(int out_fd, int in_fd, |
512 | loff_t __user *offset, size_t count); | 512 | loff_t __user *offset, size_t count); |
513 | asmlinkage long sys_readlink(const char __user *path, | 513 | asmlinkage long sys_readlink(const char __user *path, |
514 | char __user *buf, int bufsiz); | 514 | char __user *buf, int bufsiz); |
515 | asmlinkage long sys_creat(const char __user *pathname, int mode); | 515 | asmlinkage long sys_creat(const char __user *pathname, int mode); |
516 | asmlinkage long sys_open(const char __user *filename, | 516 | asmlinkage long sys_open(const char __user *filename, |
517 | int flags, int mode); | 517 | int flags, int mode); |
518 | asmlinkage long sys_close(unsigned int fd); | 518 | asmlinkage long sys_close(unsigned int fd); |
519 | asmlinkage long sys_access(const char __user *filename, int mode); | 519 | asmlinkage long sys_access(const char __user *filename, int mode); |
520 | asmlinkage long sys_vhangup(void); | 520 | asmlinkage long sys_vhangup(void); |
521 | asmlinkage long sys_chown(const char __user *filename, | 521 | asmlinkage long sys_chown(const char __user *filename, |
522 | uid_t user, gid_t group); | 522 | uid_t user, gid_t group); |
523 | asmlinkage long sys_lchown(const char __user *filename, | 523 | asmlinkage long sys_lchown(const char __user *filename, |
524 | uid_t user, gid_t group); | 524 | uid_t user, gid_t group); |
525 | asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group); | 525 | asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group); |
526 | #ifdef CONFIG_UID16 | 526 | #ifdef CONFIG_UID16 |
527 | asmlinkage long sys_chown16(const char __user *filename, | 527 | asmlinkage long sys_chown16(const char __user *filename, |
528 | old_uid_t user, old_gid_t group); | 528 | old_uid_t user, old_gid_t group); |
529 | asmlinkage long sys_lchown16(const char __user *filename, | 529 | asmlinkage long sys_lchown16(const char __user *filename, |
530 | old_uid_t user, old_gid_t group); | 530 | old_uid_t user, old_gid_t group); |
531 | asmlinkage long sys_fchown16(unsigned int fd, old_uid_t user, old_gid_t group); | 531 | asmlinkage long sys_fchown16(unsigned int fd, old_uid_t user, old_gid_t group); |
532 | asmlinkage long sys_setregid16(old_gid_t rgid, old_gid_t egid); | 532 | asmlinkage long sys_setregid16(old_gid_t rgid, old_gid_t egid); |
533 | asmlinkage long sys_setgid16(old_gid_t gid); | 533 | asmlinkage long sys_setgid16(old_gid_t gid); |
534 | asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid); | 534 | asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid); |
535 | asmlinkage long sys_setuid16(old_uid_t uid); | 535 | asmlinkage long sys_setuid16(old_uid_t uid); |
536 | asmlinkage long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid); | 536 | asmlinkage long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid); |
537 | asmlinkage long sys_getresuid16(old_uid_t __user *ruid, | 537 | asmlinkage long sys_getresuid16(old_uid_t __user *ruid, |
538 | old_uid_t __user *euid, old_uid_t __user *suid); | 538 | old_uid_t __user *euid, old_uid_t __user *suid); |
539 | asmlinkage long sys_setresgid16(old_gid_t rgid, old_gid_t egid, old_gid_t sgid); | 539 | asmlinkage long sys_setresgid16(old_gid_t rgid, old_gid_t egid, old_gid_t sgid); |
540 | asmlinkage long sys_getresgid16(old_gid_t __user *rgid, | 540 | asmlinkage long sys_getresgid16(old_gid_t __user *rgid, |
541 | old_gid_t __user *egid, old_gid_t __user *sgid); | 541 | old_gid_t __user *egid, old_gid_t __user *sgid); |
542 | asmlinkage long sys_setfsuid16(old_uid_t uid); | 542 | asmlinkage long sys_setfsuid16(old_uid_t uid); |
543 | asmlinkage long sys_setfsgid16(old_gid_t gid); | 543 | asmlinkage long sys_setfsgid16(old_gid_t gid); |
544 | asmlinkage long sys_getgroups16(int gidsetsize, old_gid_t __user *grouplist); | 544 | asmlinkage long sys_getgroups16(int gidsetsize, old_gid_t __user *grouplist); |
545 | asmlinkage long sys_setgroups16(int gidsetsize, old_gid_t __user *grouplist); | 545 | asmlinkage long sys_setgroups16(int gidsetsize, old_gid_t __user *grouplist); |
546 | asmlinkage long sys_getuid16(void); | 546 | asmlinkage long sys_getuid16(void); |
547 | asmlinkage long sys_geteuid16(void); | 547 | asmlinkage long sys_geteuid16(void); |
548 | asmlinkage long sys_getgid16(void); | 548 | asmlinkage long sys_getgid16(void); |
549 | asmlinkage long sys_getegid16(void); | 549 | asmlinkage long sys_getegid16(void); |
550 | #endif | 550 | #endif |
551 | 551 | ||
552 | asmlinkage long sys_utime(char __user *filename, | 552 | asmlinkage long sys_utime(char __user *filename, |
553 | struct utimbuf __user *times); | 553 | struct utimbuf __user *times); |
554 | asmlinkage long sys_utimes(char __user *filename, | 554 | asmlinkage long sys_utimes(char __user *filename, |
555 | struct timeval __user *utimes); | 555 | struct timeval __user *utimes); |
556 | asmlinkage long sys_lseek(unsigned int fd, off_t offset, | 556 | asmlinkage long sys_lseek(unsigned int fd, off_t offset, |
557 | unsigned int origin); | 557 | unsigned int origin); |
558 | asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high, | 558 | asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high, |
559 | unsigned long offset_low, loff_t __user *result, | 559 | unsigned long offset_low, loff_t __user *result, |
560 | unsigned int origin); | 560 | unsigned int origin); |
561 | asmlinkage long sys_read(unsigned int fd, char __user *buf, size_t count); | 561 | asmlinkage long sys_read(unsigned int fd, char __user *buf, size_t count); |
562 | asmlinkage long sys_readahead(int fd, loff_t offset, size_t count); | 562 | asmlinkage long sys_readahead(int fd, loff_t offset, size_t count); |
563 | asmlinkage long sys_readv(unsigned long fd, | 563 | asmlinkage long sys_readv(unsigned long fd, |
564 | const struct iovec __user *vec, | 564 | const struct iovec __user *vec, |
565 | unsigned long vlen); | 565 | unsigned long vlen); |
566 | asmlinkage long sys_write(unsigned int fd, const char __user *buf, | 566 | asmlinkage long sys_write(unsigned int fd, const char __user *buf, |
567 | size_t count); | 567 | size_t count); |
568 | asmlinkage long sys_writev(unsigned long fd, | 568 | asmlinkage long sys_writev(unsigned long fd, |
569 | const struct iovec __user *vec, | 569 | const struct iovec __user *vec, |
570 | unsigned long vlen); | 570 | unsigned long vlen); |
571 | asmlinkage long sys_pread64(unsigned int fd, char __user *buf, | 571 | asmlinkage long sys_pread64(unsigned int fd, char __user *buf, |
572 | size_t count, loff_t pos); | 572 | size_t count, loff_t pos); |
573 | asmlinkage long sys_pwrite64(unsigned int fd, const char __user *buf, | 573 | asmlinkage long sys_pwrite64(unsigned int fd, const char __user *buf, |
574 | size_t count, loff_t pos); | 574 | size_t count, loff_t pos); |
575 | asmlinkage long sys_preadv(unsigned long fd, const struct iovec __user *vec, | 575 | asmlinkage long sys_preadv(unsigned long fd, const struct iovec __user *vec, |
576 | unsigned long vlen, unsigned long pos_l, unsigned long pos_h); | 576 | unsigned long vlen, unsigned long pos_l, unsigned long pos_h); |
577 | asmlinkage long sys_pwritev(unsigned long fd, const struct iovec __user *vec, | 577 | asmlinkage long sys_pwritev(unsigned long fd, const struct iovec __user *vec, |
578 | unsigned long vlen, unsigned long pos_l, unsigned long pos_h); | 578 | unsigned long vlen, unsigned long pos_l, unsigned long pos_h); |
579 | asmlinkage long sys_getcwd(char __user *buf, unsigned long size); | 579 | asmlinkage long sys_getcwd(char __user *buf, unsigned long size); |
580 | asmlinkage long sys_mkdir(const char __user *pathname, int mode); | 580 | asmlinkage long sys_mkdir(const char __user *pathname, int mode); |
581 | asmlinkage long sys_chdir(const char __user *filename); | 581 | asmlinkage long sys_chdir(const char __user *filename); |
582 | asmlinkage long sys_fchdir(unsigned int fd); | 582 | asmlinkage long sys_fchdir(unsigned int fd); |
583 | asmlinkage long sys_rmdir(const char __user *pathname); | 583 | asmlinkage long sys_rmdir(const char __user *pathname); |
584 | asmlinkage long sys_lookup_dcookie(u64 cookie64, char __user *buf, size_t len); | 584 | asmlinkage long sys_lookup_dcookie(u64 cookie64, char __user *buf, size_t len); |
585 | asmlinkage long sys_quotactl(unsigned int cmd, const char __user *special, | 585 | asmlinkage long sys_quotactl(unsigned int cmd, const char __user *special, |
586 | qid_t id, void __user *addr); | 586 | qid_t id, void __user *addr); |
587 | asmlinkage long sys_getdents(unsigned int fd, | 587 | asmlinkage long sys_getdents(unsigned int fd, |
588 | struct linux_dirent __user *dirent, | 588 | struct linux_dirent __user *dirent, |
589 | unsigned int count); | 589 | unsigned int count); |
590 | asmlinkage long sys_getdents64(unsigned int fd, | 590 | asmlinkage long sys_getdents64(unsigned int fd, |
591 | struct linux_dirent64 __user *dirent, | 591 | struct linux_dirent64 __user *dirent, |
592 | unsigned int count); | 592 | unsigned int count); |
593 | 593 | ||
594 | asmlinkage long sys_setsockopt(int fd, int level, int optname, | 594 | asmlinkage long sys_setsockopt(int fd, int level, int optname, |
595 | char __user *optval, int optlen); | 595 | char __user *optval, int optlen); |
596 | asmlinkage long sys_getsockopt(int fd, int level, int optname, | 596 | asmlinkage long sys_getsockopt(int fd, int level, int optname, |
597 | char __user *optval, int __user *optlen); | 597 | char __user *optval, int __user *optlen); |
598 | asmlinkage long sys_bind(int, struct sockaddr __user *, int); | 598 | asmlinkage long sys_bind(int, struct sockaddr __user *, int); |
599 | asmlinkage long sys_connect(int, struct sockaddr __user *, int); | 599 | asmlinkage long sys_connect(int, struct sockaddr __user *, int); |
600 | asmlinkage long sys_accept(int, struct sockaddr __user *, int __user *); | 600 | asmlinkage long sys_accept(int, struct sockaddr __user *, int __user *); |
601 | asmlinkage long sys_accept4(int, struct sockaddr __user *, int __user *, int); | 601 | asmlinkage long sys_accept4(int, struct sockaddr __user *, int __user *, int); |
602 | asmlinkage long sys_getsockname(int, struct sockaddr __user *, int __user *); | 602 | asmlinkage long sys_getsockname(int, struct sockaddr __user *, int __user *); |
603 | asmlinkage long sys_getpeername(int, struct sockaddr __user *, int __user *); | 603 | asmlinkage long sys_getpeername(int, struct sockaddr __user *, int __user *); |
604 | asmlinkage long sys_send(int, void __user *, size_t, unsigned); | 604 | asmlinkage long sys_send(int, void __user *, size_t, unsigned); |
605 | asmlinkage long sys_sendto(int, void __user *, size_t, unsigned, | 605 | asmlinkage long sys_sendto(int, void __user *, size_t, unsigned, |
606 | struct sockaddr __user *, int); | 606 | struct sockaddr __user *, int); |
607 | asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags); | 607 | asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags); |
608 | asmlinkage long sys_recv(int, void __user *, size_t, unsigned); | 608 | asmlinkage long sys_recv(int, void __user *, size_t, unsigned); |
609 | asmlinkage long sys_recvfrom(int, void __user *, size_t, unsigned, | 609 | asmlinkage long sys_recvfrom(int, void __user *, size_t, unsigned, |
610 | struct sockaddr __user *, int __user *); | 610 | struct sockaddr __user *, int __user *); |
611 | asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags); | 611 | asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags); |
612 | asmlinkage long sys_recvmmsg(int fd, struct mmsghdr __user *msg, | 612 | asmlinkage long sys_recvmmsg(int fd, struct mmsghdr __user *msg, |
613 | unsigned int vlen, unsigned flags, | 613 | unsigned int vlen, unsigned flags, |
614 | struct timespec __user *timeout); | 614 | struct timespec __user *timeout); |
615 | asmlinkage long sys_socket(int, int, int); | 615 | asmlinkage long sys_socket(int, int, int); |
616 | asmlinkage long sys_socketpair(int, int, int, int __user *); | 616 | asmlinkage long sys_socketpair(int, int, int, int __user *); |
617 | asmlinkage long sys_socketcall(int call, unsigned long __user *args); | 617 | asmlinkage long sys_socketcall(int call, unsigned long __user *args); |
618 | asmlinkage long sys_listen(int, int); | 618 | asmlinkage long sys_listen(int, int); |
619 | asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds, | 619 | asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds, |
620 | long timeout); | 620 | long timeout); |
621 | asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp, | 621 | asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp, |
622 | fd_set __user *exp, struct timeval __user *tvp); | 622 | fd_set __user *exp, struct timeval __user *tvp); |
623 | asmlinkage long sys_old_select(struct sel_arg_struct __user *arg); | 623 | asmlinkage long sys_old_select(struct sel_arg_struct __user *arg); |
624 | asmlinkage long sys_epoll_create(int size); | 624 | asmlinkage long sys_epoll_create(int size); |
625 | asmlinkage long sys_epoll_create1(int flags); | 625 | asmlinkage long sys_epoll_create1(int flags); |
626 | asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, | 626 | asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, |
627 | struct epoll_event __user *event); | 627 | struct epoll_event __user *event); |
628 | asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events, | 628 | asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events, |
629 | int maxevents, int timeout); | 629 | int maxevents, int timeout); |
630 | asmlinkage long sys_epoll_pwait(int epfd, struct epoll_event __user *events, | 630 | asmlinkage long sys_epoll_pwait(int epfd, struct epoll_event __user *events, |
631 | int maxevents, int timeout, | 631 | int maxevents, int timeout, |
632 | const sigset_t __user *sigmask, | 632 | const sigset_t __user *sigmask, |
633 | size_t sigsetsize); | 633 | size_t sigsetsize); |
634 | asmlinkage long sys_gethostname(char __user *name, int len); | 634 | asmlinkage long sys_gethostname(char __user *name, int len); |
635 | asmlinkage long sys_sethostname(char __user *name, int len); | 635 | asmlinkage long sys_sethostname(char __user *name, int len); |
636 | asmlinkage long sys_setdomainname(char __user *name, int len); | 636 | asmlinkage long sys_setdomainname(char __user *name, int len); |
637 | asmlinkage long sys_newuname(struct new_utsname __user *name); | 637 | asmlinkage long sys_newuname(struct new_utsname __user *name); |
638 | asmlinkage long sys_uname(struct old_utsname __user *); | 638 | asmlinkage long sys_uname(struct old_utsname __user *); |
639 | asmlinkage long sys_olduname(struct oldold_utsname __user *); | 639 | asmlinkage long sys_olduname(struct oldold_utsname __user *); |
640 | 640 | ||
641 | asmlinkage long sys_getrlimit(unsigned int resource, | 641 | asmlinkage long sys_getrlimit(unsigned int resource, |
642 | struct rlimit __user *rlim); | 642 | struct rlimit __user *rlim); |
643 | #if defined(COMPAT_RLIM_OLD_INFINITY) || !(defined(CONFIG_IA64)) | 643 | #if defined(COMPAT_RLIM_OLD_INFINITY) || !(defined(CONFIG_IA64)) |
644 | asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit __user *rlim); | 644 | asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit __user *rlim); |
645 | #endif | 645 | #endif |
646 | asmlinkage long sys_setrlimit(unsigned int resource, | 646 | asmlinkage long sys_setrlimit(unsigned int resource, |
647 | struct rlimit __user *rlim); | 647 | struct rlimit __user *rlim); |
648 | asmlinkage long sys_prlimit64(pid_t pid, unsigned int resource, | 648 | asmlinkage long sys_prlimit64(pid_t pid, unsigned int resource, |
649 | const struct rlimit64 __user *new_rlim, | 649 | const struct rlimit64 __user *new_rlim, |
650 | struct rlimit64 __user *old_rlim); | 650 | struct rlimit64 __user *old_rlim); |
651 | asmlinkage long sys_getrusage(int who, struct rusage __user *ru); | 651 | asmlinkage long sys_getrusage(int who, struct rusage __user *ru); |
652 | asmlinkage long sys_umask(int mask); | 652 | asmlinkage long sys_umask(int mask); |
653 | 653 | ||
654 | asmlinkage long sys_msgget(key_t key, int msgflg); | 654 | asmlinkage long sys_msgget(key_t key, int msgflg); |
655 | asmlinkage long sys_msgsnd(int msqid, struct msgbuf __user *msgp, | 655 | asmlinkage long sys_msgsnd(int msqid, struct msgbuf __user *msgp, |
656 | size_t msgsz, int msgflg); | 656 | size_t msgsz, int msgflg); |
657 | asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, | 657 | asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, |
658 | size_t msgsz, long msgtyp, int msgflg); | 658 | size_t msgsz, long msgtyp, int msgflg); |
659 | asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf); | 659 | asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf); |
660 | 660 | ||
661 | asmlinkage long sys_semget(key_t key, int nsems, int semflg); | 661 | asmlinkage long sys_semget(key_t key, int nsems, int semflg); |
662 | asmlinkage long sys_semop(int semid, struct sembuf __user *sops, | 662 | asmlinkage long sys_semop(int semid, struct sembuf __user *sops, |
663 | unsigned nsops); | 663 | unsigned nsops); |
664 | asmlinkage long sys_semctl(int semid, int semnum, int cmd, union semun arg); | 664 | asmlinkage long sys_semctl(int semid, int semnum, int cmd, union semun arg); |
665 | asmlinkage long sys_semtimedop(int semid, struct sembuf __user *sops, | 665 | asmlinkage long sys_semtimedop(int semid, struct sembuf __user *sops, |
666 | unsigned nsops, | 666 | unsigned nsops, |
667 | const struct timespec __user *timeout); | 667 | const struct timespec __user *timeout); |
668 | asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg); | 668 | asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg); |
669 | asmlinkage long sys_shmget(key_t key, size_t size, int flag); | 669 | asmlinkage long sys_shmget(key_t key, size_t size, int flag); |
670 | asmlinkage long sys_shmdt(char __user *shmaddr); | 670 | asmlinkage long sys_shmdt(char __user *shmaddr); |
671 | asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf); | 671 | asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf); |
672 | asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second, | 672 | asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second, |
673 | unsigned long third, void __user *ptr, long fifth); | 673 | unsigned long third, void __user *ptr, long fifth); |
674 | 674 | ||
675 | asmlinkage long sys_mq_open(const char __user *name, int oflag, mode_t mode, struct mq_attr __user *attr); | 675 | asmlinkage long sys_mq_open(const char __user *name, int oflag, mode_t mode, struct mq_attr __user *attr); |
676 | asmlinkage long sys_mq_unlink(const char __user *name); | 676 | asmlinkage long sys_mq_unlink(const char __user *name); |
677 | asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec __user *abs_timeout); | 677 | asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec __user *abs_timeout); |
678 | asmlinkage long sys_mq_timedreceive(mqd_t mqdes, char __user *msg_ptr, size_t msg_len, unsigned int __user *msg_prio, const struct timespec __user *abs_timeout); | 678 | asmlinkage long sys_mq_timedreceive(mqd_t mqdes, char __user *msg_ptr, size_t msg_len, unsigned int __user *msg_prio, const struct timespec __user *abs_timeout); |
679 | asmlinkage long sys_mq_notify(mqd_t mqdes, const struct sigevent __user *notification); | 679 | asmlinkage long sys_mq_notify(mqd_t mqdes, const struct sigevent __user *notification); |
680 | asmlinkage long sys_mq_getsetattr(mqd_t mqdes, const struct mq_attr __user *mqstat, struct mq_attr __user *omqstat); | 680 | asmlinkage long sys_mq_getsetattr(mqd_t mqdes, const struct mq_attr __user *mqstat, struct mq_attr __user *omqstat); |
681 | 681 | ||
682 | asmlinkage long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn); | 682 | asmlinkage long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn); |
683 | asmlinkage long sys_pciconfig_read(unsigned long bus, unsigned long dfn, | 683 | asmlinkage long sys_pciconfig_read(unsigned long bus, unsigned long dfn, |
684 | unsigned long off, unsigned long len, | 684 | unsigned long off, unsigned long len, |
685 | void __user *buf); | 685 | void __user *buf); |
686 | asmlinkage long sys_pciconfig_write(unsigned long bus, unsigned long dfn, | 686 | asmlinkage long sys_pciconfig_write(unsigned long bus, unsigned long dfn, |
687 | unsigned long off, unsigned long len, | 687 | unsigned long off, unsigned long len, |
688 | void __user *buf); | 688 | void __user *buf); |
689 | 689 | ||
690 | asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, | 690 | asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, |
691 | unsigned long arg4, unsigned long arg5); | 691 | unsigned long arg4, unsigned long arg5); |
692 | asmlinkage long sys_swapon(const char __user *specialfile, int swap_flags); | 692 | asmlinkage long sys_swapon(const char __user *specialfile, int swap_flags); |
693 | asmlinkage long sys_swapoff(const char __user *specialfile); | 693 | asmlinkage long sys_swapoff(const char __user *specialfile); |
694 | asmlinkage long sys_sysctl(struct __sysctl_args __user *args); | 694 | asmlinkage long sys_sysctl(struct __sysctl_args __user *args); |
695 | asmlinkage long sys_sysinfo(struct sysinfo __user *info); | 695 | asmlinkage long sys_sysinfo(struct sysinfo __user *info); |
696 | asmlinkage long sys_sysfs(int option, | 696 | asmlinkage long sys_sysfs(int option, |
697 | unsigned long arg1, unsigned long arg2); | 697 | unsigned long arg1, unsigned long arg2); |
698 | asmlinkage long sys_nfsservctl(int cmd, | 698 | asmlinkage long sys_nfsservctl(int cmd, |
699 | struct nfsctl_arg __user *arg, | 699 | struct nfsctl_arg __user *arg, |
700 | void __user *res); | 700 | void __user *res); |
701 | asmlinkage long sys_syslog(int type, char __user *buf, int len); | 701 | asmlinkage long sys_syslog(int type, char __user *buf, int len); |
702 | asmlinkage long sys_uselib(const char __user *library); | 702 | asmlinkage long sys_uselib(const char __user *library); |
703 | asmlinkage long sys_ni_syscall(void); | 703 | asmlinkage long sys_ni_syscall(void); |
704 | asmlinkage long sys_ptrace(long request, long pid, long addr, long data); | 704 | asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, |
705 | unsigned long data); | ||
705 | 706 | ||
706 | asmlinkage long sys_add_key(const char __user *_type, | 707 | asmlinkage long sys_add_key(const char __user *_type, |
707 | const char __user *_description, | 708 | const char __user *_description, |
708 | const void __user *_payload, | 709 | const void __user *_payload, |
709 | size_t plen, | 710 | size_t plen, |
710 | key_serial_t destringid); | 711 | key_serial_t destringid); |
711 | 712 | ||
712 | asmlinkage long sys_request_key(const char __user *_type, | 713 | asmlinkage long sys_request_key(const char __user *_type, |
713 | const char __user *_description, | 714 | const char __user *_description, |
714 | const char __user *_callout_info, | 715 | const char __user *_callout_info, |
715 | key_serial_t destringid); | 716 | key_serial_t destringid); |
716 | 717 | ||
717 | asmlinkage long sys_keyctl(int cmd, unsigned long arg2, unsigned long arg3, | 718 | asmlinkage long sys_keyctl(int cmd, unsigned long arg2, unsigned long arg3, |
718 | unsigned long arg4, unsigned long arg5); | 719 | unsigned long arg4, unsigned long arg5); |
719 | 720 | ||
720 | asmlinkage long sys_ioprio_set(int which, int who, int ioprio); | 721 | asmlinkage long sys_ioprio_set(int which, int who, int ioprio); |
721 | asmlinkage long sys_ioprio_get(int which, int who); | 722 | asmlinkage long sys_ioprio_get(int which, int who); |
722 | asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask, | 723 | asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask, |
723 | unsigned long maxnode); | 724 | unsigned long maxnode); |
724 | asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode, | 725 | asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode, |
725 | const unsigned long __user *from, | 726 | const unsigned long __user *from, |
726 | const unsigned long __user *to); | 727 | const unsigned long __user *to); |
727 | asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages, | 728 | asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages, |
728 | const void __user * __user *pages, | 729 | const void __user * __user *pages, |
729 | const int __user *nodes, | 730 | const int __user *nodes, |
730 | int __user *status, | 731 | int __user *status, |
731 | int flags); | 732 | int flags); |
732 | asmlinkage long sys_mbind(unsigned long start, unsigned long len, | 733 | asmlinkage long sys_mbind(unsigned long start, unsigned long len, |
733 | unsigned long mode, | 734 | unsigned long mode, |
734 | unsigned long __user *nmask, | 735 | unsigned long __user *nmask, |
735 | unsigned long maxnode, | 736 | unsigned long maxnode, |
736 | unsigned flags); | 737 | unsigned flags); |
737 | asmlinkage long sys_get_mempolicy(int __user *policy, | 738 | asmlinkage long sys_get_mempolicy(int __user *policy, |
738 | unsigned long __user *nmask, | 739 | unsigned long __user *nmask, |
739 | unsigned long maxnode, | 740 | unsigned long maxnode, |
740 | unsigned long addr, unsigned long flags); | 741 | unsigned long addr, unsigned long flags); |
741 | 742 | ||
742 | asmlinkage long sys_inotify_init(void); | 743 | asmlinkage long sys_inotify_init(void); |
743 | asmlinkage long sys_inotify_init1(int flags); | 744 | asmlinkage long sys_inotify_init1(int flags); |
744 | asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, | 745 | asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, |
745 | u32 mask); | 746 | u32 mask); |
746 | asmlinkage long sys_inotify_rm_watch(int fd, __s32 wd); | 747 | asmlinkage long sys_inotify_rm_watch(int fd, __s32 wd); |
747 | 748 | ||
748 | asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, | 749 | asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, |
749 | __u32 __user *ustatus); | 750 | __u32 __user *ustatus); |
750 | asmlinkage long sys_spu_create(const char __user *name, | 751 | asmlinkage long sys_spu_create(const char __user *name, |
751 | unsigned int flags, mode_t mode, int fd); | 752 | unsigned int flags, mode_t mode, int fd); |
752 | 753 | ||
753 | asmlinkage long sys_mknodat(int dfd, const char __user * filename, int mode, | 754 | asmlinkage long sys_mknodat(int dfd, const char __user * filename, int mode, |
754 | unsigned dev); | 755 | unsigned dev); |
755 | asmlinkage long sys_mkdirat(int dfd, const char __user * pathname, int mode); | 756 | asmlinkage long sys_mkdirat(int dfd, const char __user * pathname, int mode); |
756 | asmlinkage long sys_unlinkat(int dfd, const char __user * pathname, int flag); | 757 | asmlinkage long sys_unlinkat(int dfd, const char __user * pathname, int flag); |
757 | asmlinkage long sys_symlinkat(const char __user * oldname, | 758 | asmlinkage long sys_symlinkat(const char __user * oldname, |
758 | int newdfd, const char __user * newname); | 759 | int newdfd, const char __user * newname); |
759 | asmlinkage long sys_linkat(int olddfd, const char __user *oldname, | 760 | asmlinkage long sys_linkat(int olddfd, const char __user *oldname, |
760 | int newdfd, const char __user *newname, int flags); | 761 | int newdfd, const char __user *newname, int flags); |
761 | asmlinkage long sys_renameat(int olddfd, const char __user * oldname, | 762 | asmlinkage long sys_renameat(int olddfd, const char __user * oldname, |
762 | int newdfd, const char __user * newname); | 763 | int newdfd, const char __user * newname); |
763 | asmlinkage long sys_futimesat(int dfd, const char __user *filename, | 764 | asmlinkage long sys_futimesat(int dfd, const char __user *filename, |
764 | struct timeval __user *utimes); | 765 | struct timeval __user *utimes); |
765 | asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode); | 766 | asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode); |
766 | asmlinkage long sys_fchmodat(int dfd, const char __user * filename, | 767 | asmlinkage long sys_fchmodat(int dfd, const char __user * filename, |
767 | mode_t mode); | 768 | mode_t mode); |
768 | asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user, | 769 | asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user, |
769 | gid_t group, int flag); | 770 | gid_t group, int flag); |
770 | asmlinkage long sys_openat(int dfd, const char __user *filename, int flags, | 771 | asmlinkage long sys_openat(int dfd, const char __user *filename, int flags, |
771 | int mode); | 772 | int mode); |
772 | asmlinkage long sys_newfstatat(int dfd, const char __user *filename, | 773 | asmlinkage long sys_newfstatat(int dfd, const char __user *filename, |
773 | struct stat __user *statbuf, int flag); | 774 | struct stat __user *statbuf, int flag); |
774 | asmlinkage long sys_fstatat64(int dfd, const char __user *filename, | 775 | asmlinkage long sys_fstatat64(int dfd, const char __user *filename, |
775 | struct stat64 __user *statbuf, int flag); | 776 | struct stat64 __user *statbuf, int flag); |
776 | asmlinkage long sys_readlinkat(int dfd, const char __user *path, char __user *buf, | 777 | asmlinkage long sys_readlinkat(int dfd, const char __user *path, char __user *buf, |
777 | int bufsiz); | 778 | int bufsiz); |
778 | asmlinkage long sys_utimensat(int dfd, const char __user *filename, | 779 | asmlinkage long sys_utimensat(int dfd, const char __user *filename, |
779 | struct timespec __user *utimes, int flags); | 780 | struct timespec __user *utimes, int flags); |
780 | asmlinkage long sys_unshare(unsigned long unshare_flags); | 781 | asmlinkage long sys_unshare(unsigned long unshare_flags); |
781 | 782 | ||
782 | asmlinkage long sys_splice(int fd_in, loff_t __user *off_in, | 783 | asmlinkage long sys_splice(int fd_in, loff_t __user *off_in, |
783 | int fd_out, loff_t __user *off_out, | 784 | int fd_out, loff_t __user *off_out, |
784 | size_t len, unsigned int flags); | 785 | size_t len, unsigned int flags); |
785 | 786 | ||
786 | asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov, | 787 | asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov, |
787 | unsigned long nr_segs, unsigned int flags); | 788 | unsigned long nr_segs, unsigned int flags); |
788 | 789 | ||
789 | asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags); | 790 | asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags); |
790 | 791 | ||
791 | asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, | 792 | asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, |
792 | unsigned int flags); | 793 | unsigned int flags); |
793 | asmlinkage long sys_sync_file_range2(int fd, unsigned int flags, | 794 | asmlinkage long sys_sync_file_range2(int fd, unsigned int flags, |
794 | loff_t offset, loff_t nbytes); | 795 | loff_t offset, loff_t nbytes); |
795 | asmlinkage long sys_get_robust_list(int pid, | 796 | asmlinkage long sys_get_robust_list(int pid, |
796 | struct robust_list_head __user * __user *head_ptr, | 797 | struct robust_list_head __user * __user *head_ptr, |
797 | size_t __user *len_ptr); | 798 | size_t __user *len_ptr); |
798 | asmlinkage long sys_set_robust_list(struct robust_list_head __user *head, | 799 | asmlinkage long sys_set_robust_list(struct robust_list_head __user *head, |
799 | size_t len); | 800 | size_t len); |
800 | asmlinkage long sys_getcpu(unsigned __user *cpu, unsigned __user *node, struct getcpu_cache __user *cache); | 801 | asmlinkage long sys_getcpu(unsigned __user *cpu, unsigned __user *node, struct getcpu_cache __user *cache); |
801 | asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemask); | 802 | asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemask); |
802 | asmlinkage long sys_signalfd4(int ufd, sigset_t __user *user_mask, size_t sizemask, int flags); | 803 | asmlinkage long sys_signalfd4(int ufd, sigset_t __user *user_mask, size_t sizemask, int flags); |
803 | asmlinkage long sys_timerfd_create(int clockid, int flags); | 804 | asmlinkage long sys_timerfd_create(int clockid, int flags); |
804 | asmlinkage long sys_timerfd_settime(int ufd, int flags, | 805 | asmlinkage long sys_timerfd_settime(int ufd, int flags, |
805 | const struct itimerspec __user *utmr, | 806 | const struct itimerspec __user *utmr, |
806 | struct itimerspec __user *otmr); | 807 | struct itimerspec __user *otmr); |
807 | asmlinkage long sys_timerfd_gettime(int ufd, struct itimerspec __user *otmr); | 808 | asmlinkage long sys_timerfd_gettime(int ufd, struct itimerspec __user *otmr); |
808 | asmlinkage long sys_eventfd(unsigned int count); | 809 | asmlinkage long sys_eventfd(unsigned int count); |
809 | asmlinkage long sys_eventfd2(unsigned int count, int flags); | 810 | asmlinkage long sys_eventfd2(unsigned int count, int flags); |
810 | asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len); | 811 | asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len); |
811 | asmlinkage long sys_old_readdir(unsigned int, struct old_linux_dirent __user *, unsigned int); | 812 | asmlinkage long sys_old_readdir(unsigned int, struct old_linux_dirent __user *, unsigned int); |
812 | asmlinkage long sys_pselect6(int, fd_set __user *, fd_set __user *, | 813 | asmlinkage long sys_pselect6(int, fd_set __user *, fd_set __user *, |
813 | fd_set __user *, struct timespec __user *, | 814 | fd_set __user *, struct timespec __user *, |
814 | void __user *); | 815 | void __user *); |
815 | asmlinkage long sys_ppoll(struct pollfd __user *, unsigned int, | 816 | asmlinkage long sys_ppoll(struct pollfd __user *, unsigned int, |
816 | struct timespec __user *, const sigset_t __user *, | 817 | struct timespec __user *, const sigset_t __user *, |
817 | size_t); | 818 | size_t); |
818 | asmlinkage long sys_fanotify_init(unsigned int flags, unsigned int event_f_flags); | 819 | asmlinkage long sys_fanotify_init(unsigned int flags, unsigned int event_f_flags); |
819 | asmlinkage long sys_fanotify_mark(int fanotify_fd, unsigned int flags, | 820 | asmlinkage long sys_fanotify_mark(int fanotify_fd, unsigned int flags, |
820 | u64 mask, int fd, | 821 | u64 mask, int fd, |
821 | const char __user *pathname); | 822 | const char __user *pathname); |
822 | 823 | ||
823 | int kernel_execve(const char *filename, const char *const argv[], const char *const envp[]); | 824 | int kernel_execve(const char *filename, const char *const argv[], const char *const envp[]); |
824 | 825 | ||
825 | 826 | ||
826 | asmlinkage long sys_perf_event_open( | 827 | asmlinkage long sys_perf_event_open( |
827 | struct perf_event_attr __user *attr_uptr, | 828 | struct perf_event_attr __user *attr_uptr, |
828 | pid_t pid, int cpu, int group_fd, unsigned long flags); | 829 | pid_t pid, int cpu, int group_fd, unsigned long flags); |
829 | 830 | ||
830 | asmlinkage long sys_mmap_pgoff(unsigned long addr, unsigned long len, | 831 | asmlinkage long sys_mmap_pgoff(unsigned long addr, unsigned long len, |
831 | unsigned long prot, unsigned long flags, | 832 | unsigned long prot, unsigned long flags, |
832 | unsigned long fd, unsigned long pgoff); | 833 | unsigned long fd, unsigned long pgoff); |
833 | asmlinkage long sys_old_mmap(struct mmap_arg_struct __user *arg); | 834 | asmlinkage long sys_old_mmap(struct mmap_arg_struct __user *arg); |
834 | 835 | ||
835 | #endif | 836 | #endif |
836 | 837 |
kernel/ptrace.c
1 | /* | 1 | /* |
2 | * linux/kernel/ptrace.c | 2 | * linux/kernel/ptrace.c |
3 | * | 3 | * |
4 | * (C) Copyright 1999 Linus Torvalds | 4 | * (C) Copyright 1999 Linus Torvalds |
5 | * | 5 | * |
6 | * Common interfaces for "ptrace()" which we do not want | 6 | * Common interfaces for "ptrace()" which we do not want |
7 | * to continually duplicate across every architecture. | 7 | * to continually duplicate across every architecture. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/capability.h> | 10 | #include <linux/capability.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
14 | #include <linux/mm.h> | 14 | #include <linux/mm.h> |
15 | #include <linux/highmem.h> | 15 | #include <linux/highmem.h> |
16 | #include <linux/pagemap.h> | 16 | #include <linux/pagemap.h> |
17 | #include <linux/ptrace.h> | 17 | #include <linux/ptrace.h> |
18 | #include <linux/security.h> | 18 | #include <linux/security.h> |
19 | #include <linux/signal.h> | 19 | #include <linux/signal.h> |
20 | #include <linux/audit.h> | 20 | #include <linux/audit.h> |
21 | #include <linux/pid_namespace.h> | 21 | #include <linux/pid_namespace.h> |
22 | #include <linux/syscalls.h> | 22 | #include <linux/syscalls.h> |
23 | #include <linux/uaccess.h> | 23 | #include <linux/uaccess.h> |
24 | #include <linux/regset.h> | 24 | #include <linux/regset.h> |
25 | 25 | ||
26 | 26 | ||
27 | /* | 27 | /* |
28 | * ptrace a task: make the debugger its new parent and | 28 | * ptrace a task: make the debugger its new parent and |
29 | * move it to the ptrace list. | 29 | * move it to the ptrace list. |
30 | * | 30 | * |
31 | * Must be called with the tasklist lock write-held. | 31 | * Must be called with the tasklist lock write-held. |
32 | */ | 32 | */ |
33 | void __ptrace_link(struct task_struct *child, struct task_struct *new_parent) | 33 | void __ptrace_link(struct task_struct *child, struct task_struct *new_parent) |
34 | { | 34 | { |
35 | BUG_ON(!list_empty(&child->ptrace_entry)); | 35 | BUG_ON(!list_empty(&child->ptrace_entry)); |
36 | list_add(&child->ptrace_entry, &new_parent->ptraced); | 36 | list_add(&child->ptrace_entry, &new_parent->ptraced); |
37 | child->parent = new_parent; | 37 | child->parent = new_parent; |
38 | } | 38 | } |
39 | 39 | ||
40 | /* | 40 | /* |
41 | * Turn a tracing stop into a normal stop now, since with no tracer there | 41 | * Turn a tracing stop into a normal stop now, since with no tracer there |
42 | * would be no way to wake it up with SIGCONT or SIGKILL. If there was a | 42 | * would be no way to wake it up with SIGCONT or SIGKILL. If there was a |
43 | * signal sent that would resume the child, but didn't because it was in | 43 | * signal sent that would resume the child, but didn't because it was in |
44 | * TASK_TRACED, resume it now. | 44 | * TASK_TRACED, resume it now. |
45 | * Requires that irqs be disabled. | 45 | * Requires that irqs be disabled. |
46 | */ | 46 | */ |
47 | static void ptrace_untrace(struct task_struct *child) | 47 | static void ptrace_untrace(struct task_struct *child) |
48 | { | 48 | { |
49 | spin_lock(&child->sighand->siglock); | 49 | spin_lock(&child->sighand->siglock); |
50 | if (task_is_traced(child)) { | 50 | if (task_is_traced(child)) { |
51 | /* | 51 | /* |
52 | * If the group stop is completed or in progress, | 52 | * If the group stop is completed or in progress, |
53 | * this thread was already counted as stopped. | 53 | * this thread was already counted as stopped. |
54 | */ | 54 | */ |
55 | if (child->signal->flags & SIGNAL_STOP_STOPPED || | 55 | if (child->signal->flags & SIGNAL_STOP_STOPPED || |
56 | child->signal->group_stop_count) | 56 | child->signal->group_stop_count) |
57 | __set_task_state(child, TASK_STOPPED); | 57 | __set_task_state(child, TASK_STOPPED); |
58 | else | 58 | else |
59 | signal_wake_up(child, 1); | 59 | signal_wake_up(child, 1); |
60 | } | 60 | } |
61 | spin_unlock(&child->sighand->siglock); | 61 | spin_unlock(&child->sighand->siglock); |
62 | } | 62 | } |
63 | 63 | ||
64 | /* | 64 | /* |
65 | * unptrace a task: move it back to its original parent and | 65 | * unptrace a task: move it back to its original parent and |
66 | * remove it from the ptrace list. | 66 | * remove it from the ptrace list. |
67 | * | 67 | * |
68 | * Must be called with the tasklist lock write-held. | 68 | * Must be called with the tasklist lock write-held. |
69 | */ | 69 | */ |
70 | void __ptrace_unlink(struct task_struct *child) | 70 | void __ptrace_unlink(struct task_struct *child) |
71 | { | 71 | { |
72 | BUG_ON(!child->ptrace); | 72 | BUG_ON(!child->ptrace); |
73 | 73 | ||
74 | child->ptrace = 0; | 74 | child->ptrace = 0; |
75 | child->parent = child->real_parent; | 75 | child->parent = child->real_parent; |
76 | list_del_init(&child->ptrace_entry); | 76 | list_del_init(&child->ptrace_entry); |
77 | 77 | ||
78 | if (task_is_traced(child)) | 78 | if (task_is_traced(child)) |
79 | ptrace_untrace(child); | 79 | ptrace_untrace(child); |
80 | } | 80 | } |
81 | 81 | ||
82 | /* | 82 | /* |
83 | * Check that we have indeed attached to the thing.. | 83 | * Check that we have indeed attached to the thing.. |
84 | */ | 84 | */ |
85 | int ptrace_check_attach(struct task_struct *child, int kill) | 85 | int ptrace_check_attach(struct task_struct *child, int kill) |
86 | { | 86 | { |
87 | int ret = -ESRCH; | 87 | int ret = -ESRCH; |
88 | 88 | ||
89 | /* | 89 | /* |
90 | * We take the read lock around doing both checks to close a | 90 | * We take the read lock around doing both checks to close a |
91 | * possible race where someone else was tracing our child and | 91 | * possible race where someone else was tracing our child and |
92 | * detached between these two checks. After this locked check, | 92 | * detached between these two checks. After this locked check, |
93 | * we are sure that this is our traced child and that can only | 93 | * we are sure that this is our traced child and that can only |
94 | * be changed by us so it's not changing right after this. | 94 | * be changed by us so it's not changing right after this. |
95 | */ | 95 | */ |
96 | read_lock(&tasklist_lock); | 96 | read_lock(&tasklist_lock); |
97 | if ((child->ptrace & PT_PTRACED) && child->parent == current) { | 97 | if ((child->ptrace & PT_PTRACED) && child->parent == current) { |
98 | ret = 0; | 98 | ret = 0; |
99 | /* | 99 | /* |
100 | * child->sighand can't be NULL, release_task() | 100 | * child->sighand can't be NULL, release_task() |
101 | * does ptrace_unlink() before __exit_signal(). | 101 | * does ptrace_unlink() before __exit_signal(). |
102 | */ | 102 | */ |
103 | spin_lock_irq(&child->sighand->siglock); | 103 | spin_lock_irq(&child->sighand->siglock); |
104 | if (task_is_stopped(child)) | 104 | if (task_is_stopped(child)) |
105 | child->state = TASK_TRACED; | 105 | child->state = TASK_TRACED; |
106 | else if (!task_is_traced(child) && !kill) | 106 | else if (!task_is_traced(child) && !kill) |
107 | ret = -ESRCH; | 107 | ret = -ESRCH; |
108 | spin_unlock_irq(&child->sighand->siglock); | 108 | spin_unlock_irq(&child->sighand->siglock); |
109 | } | 109 | } |
110 | read_unlock(&tasklist_lock); | 110 | read_unlock(&tasklist_lock); |
111 | 111 | ||
112 | if (!ret && !kill) | 112 | if (!ret && !kill) |
113 | ret = wait_task_inactive(child, TASK_TRACED) ? 0 : -ESRCH; | 113 | ret = wait_task_inactive(child, TASK_TRACED) ? 0 : -ESRCH; |
114 | 114 | ||
115 | /* All systems go.. */ | 115 | /* All systems go.. */ |
116 | return ret; | 116 | return ret; |
117 | } | 117 | } |
118 | 118 | ||
119 | int __ptrace_may_access(struct task_struct *task, unsigned int mode) | 119 | int __ptrace_may_access(struct task_struct *task, unsigned int mode) |
120 | { | 120 | { |
121 | const struct cred *cred = current_cred(), *tcred; | 121 | const struct cred *cred = current_cred(), *tcred; |
122 | 122 | ||
123 | /* May we inspect the given task? | 123 | /* May we inspect the given task? |
124 | * This check is used both for attaching with ptrace | 124 | * This check is used both for attaching with ptrace |
125 | * and for allowing access to sensitive information in /proc. | 125 | * and for allowing access to sensitive information in /proc. |
126 | * | 126 | * |
127 | * ptrace_attach denies several cases that /proc allows | 127 | * ptrace_attach denies several cases that /proc allows |
128 | * because setting up the necessary parent/child relationship | 128 | * because setting up the necessary parent/child relationship |
129 | * or halting the specified task is impossible. | 129 | * or halting the specified task is impossible. |
130 | */ | 130 | */ |
131 | int dumpable = 0; | 131 | int dumpable = 0; |
132 | /* Don't let security modules deny introspection */ | 132 | /* Don't let security modules deny introspection */ |
133 | if (task == current) | 133 | if (task == current) |
134 | return 0; | 134 | return 0; |
135 | rcu_read_lock(); | 135 | rcu_read_lock(); |
136 | tcred = __task_cred(task); | 136 | tcred = __task_cred(task); |
137 | if ((cred->uid != tcred->euid || | 137 | if ((cred->uid != tcred->euid || |
138 | cred->uid != tcred->suid || | 138 | cred->uid != tcred->suid || |
139 | cred->uid != tcred->uid || | 139 | cred->uid != tcred->uid || |
140 | cred->gid != tcred->egid || | 140 | cred->gid != tcred->egid || |
141 | cred->gid != tcred->sgid || | 141 | cred->gid != tcred->sgid || |
142 | cred->gid != tcred->gid) && | 142 | cred->gid != tcred->gid) && |
143 | !capable(CAP_SYS_PTRACE)) { | 143 | !capable(CAP_SYS_PTRACE)) { |
144 | rcu_read_unlock(); | 144 | rcu_read_unlock(); |
145 | return -EPERM; | 145 | return -EPERM; |
146 | } | 146 | } |
147 | rcu_read_unlock(); | 147 | rcu_read_unlock(); |
148 | smp_rmb(); | 148 | smp_rmb(); |
149 | if (task->mm) | 149 | if (task->mm) |
150 | dumpable = get_dumpable(task->mm); | 150 | dumpable = get_dumpable(task->mm); |
151 | if (!dumpable && !capable(CAP_SYS_PTRACE)) | 151 | if (!dumpable && !capable(CAP_SYS_PTRACE)) |
152 | return -EPERM; | 152 | return -EPERM; |
153 | 153 | ||
154 | return security_ptrace_access_check(task, mode); | 154 | return security_ptrace_access_check(task, mode); |
155 | } | 155 | } |
156 | 156 | ||
157 | bool ptrace_may_access(struct task_struct *task, unsigned int mode) | 157 | bool ptrace_may_access(struct task_struct *task, unsigned int mode) |
158 | { | 158 | { |
159 | int err; | 159 | int err; |
160 | task_lock(task); | 160 | task_lock(task); |
161 | err = __ptrace_may_access(task, mode); | 161 | err = __ptrace_may_access(task, mode); |
162 | task_unlock(task); | 162 | task_unlock(task); |
163 | return !err; | 163 | return !err; |
164 | } | 164 | } |
165 | 165 | ||
166 | int ptrace_attach(struct task_struct *task) | 166 | int ptrace_attach(struct task_struct *task) |
167 | { | 167 | { |
168 | int retval; | 168 | int retval; |
169 | 169 | ||
170 | audit_ptrace(task); | 170 | audit_ptrace(task); |
171 | 171 | ||
172 | retval = -EPERM; | 172 | retval = -EPERM; |
173 | if (unlikely(task->flags & PF_KTHREAD)) | 173 | if (unlikely(task->flags & PF_KTHREAD)) |
174 | goto out; | 174 | goto out; |
175 | if (same_thread_group(task, current)) | 175 | if (same_thread_group(task, current)) |
176 | goto out; | 176 | goto out; |
177 | 177 | ||
178 | /* | 178 | /* |
179 | * Protect exec's credential calculations against our interference; | 179 | * Protect exec's credential calculations against our interference; |
180 | * interference; SUID, SGID and LSM creds get determined differently | 180 | * interference; SUID, SGID and LSM creds get determined differently |
181 | * under ptrace. | 181 | * under ptrace. |
182 | */ | 182 | */ |
183 | retval = -ERESTARTNOINTR; | 183 | retval = -ERESTARTNOINTR; |
184 | if (mutex_lock_interruptible(&task->cred_guard_mutex)) | 184 | if (mutex_lock_interruptible(&task->cred_guard_mutex)) |
185 | goto out; | 185 | goto out; |
186 | 186 | ||
187 | task_lock(task); | 187 | task_lock(task); |
188 | retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH); | 188 | retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH); |
189 | task_unlock(task); | 189 | task_unlock(task); |
190 | if (retval) | 190 | if (retval) |
191 | goto unlock_creds; | 191 | goto unlock_creds; |
192 | 192 | ||
193 | write_lock_irq(&tasklist_lock); | 193 | write_lock_irq(&tasklist_lock); |
194 | retval = -EPERM; | 194 | retval = -EPERM; |
195 | if (unlikely(task->exit_state)) | 195 | if (unlikely(task->exit_state)) |
196 | goto unlock_tasklist; | 196 | goto unlock_tasklist; |
197 | if (task->ptrace) | 197 | if (task->ptrace) |
198 | goto unlock_tasklist; | 198 | goto unlock_tasklist; |
199 | 199 | ||
200 | task->ptrace = PT_PTRACED; | 200 | task->ptrace = PT_PTRACED; |
201 | if (capable(CAP_SYS_PTRACE)) | 201 | if (capable(CAP_SYS_PTRACE)) |
202 | task->ptrace |= PT_PTRACE_CAP; | 202 | task->ptrace |= PT_PTRACE_CAP; |
203 | 203 | ||
204 | __ptrace_link(task, current); | 204 | __ptrace_link(task, current); |
205 | send_sig_info(SIGSTOP, SEND_SIG_FORCED, task); | 205 | send_sig_info(SIGSTOP, SEND_SIG_FORCED, task); |
206 | 206 | ||
207 | retval = 0; | 207 | retval = 0; |
208 | unlock_tasklist: | 208 | unlock_tasklist: |
209 | write_unlock_irq(&tasklist_lock); | 209 | write_unlock_irq(&tasklist_lock); |
210 | unlock_creds: | 210 | unlock_creds: |
211 | mutex_unlock(&task->cred_guard_mutex); | 211 | mutex_unlock(&task->cred_guard_mutex); |
212 | out: | 212 | out: |
213 | return retval; | 213 | return retval; |
214 | } | 214 | } |
215 | 215 | ||
216 | /** | 216 | /** |
217 | * ptrace_traceme -- helper for PTRACE_TRACEME | 217 | * ptrace_traceme -- helper for PTRACE_TRACEME |
218 | * | 218 | * |
219 | * Performs checks and sets PT_PTRACED. | 219 | * Performs checks and sets PT_PTRACED. |
220 | * Should be used by all ptrace implementations for PTRACE_TRACEME. | 220 | * Should be used by all ptrace implementations for PTRACE_TRACEME. |
221 | */ | 221 | */ |
222 | int ptrace_traceme(void) | 222 | int ptrace_traceme(void) |
223 | { | 223 | { |
224 | int ret = -EPERM; | 224 | int ret = -EPERM; |
225 | 225 | ||
226 | write_lock_irq(&tasklist_lock); | 226 | write_lock_irq(&tasklist_lock); |
227 | /* Are we already being traced? */ | 227 | /* Are we already being traced? */ |
228 | if (!current->ptrace) { | 228 | if (!current->ptrace) { |
229 | ret = security_ptrace_traceme(current->parent); | 229 | ret = security_ptrace_traceme(current->parent); |
230 | /* | 230 | /* |
231 | * Check PF_EXITING to ensure ->real_parent has not passed | 231 | * Check PF_EXITING to ensure ->real_parent has not passed |
232 | * exit_ptrace(). Otherwise we don't report the error but | 232 | * exit_ptrace(). Otherwise we don't report the error but |
233 | * pretend ->real_parent untraces us right after return. | 233 | * pretend ->real_parent untraces us right after return. |
234 | */ | 234 | */ |
235 | if (!ret && !(current->real_parent->flags & PF_EXITING)) { | 235 | if (!ret && !(current->real_parent->flags & PF_EXITING)) { |
236 | current->ptrace = PT_PTRACED; | 236 | current->ptrace = PT_PTRACED; |
237 | __ptrace_link(current, current->real_parent); | 237 | __ptrace_link(current, current->real_parent); |
238 | } | 238 | } |
239 | } | 239 | } |
240 | write_unlock_irq(&tasklist_lock); | 240 | write_unlock_irq(&tasklist_lock); |
241 | 241 | ||
242 | return ret; | 242 | return ret; |
243 | } | 243 | } |
244 | 244 | ||
245 | /* | 245 | /* |
246 | * Called with irqs disabled, returns true if childs should reap themselves. | 246 | * Called with irqs disabled, returns true if childs should reap themselves. |
247 | */ | 247 | */ |
248 | static int ignoring_children(struct sighand_struct *sigh) | 248 | static int ignoring_children(struct sighand_struct *sigh) |
249 | { | 249 | { |
250 | int ret; | 250 | int ret; |
251 | spin_lock(&sigh->siglock); | 251 | spin_lock(&sigh->siglock); |
252 | ret = (sigh->action[SIGCHLD-1].sa.sa_handler == SIG_IGN) || | 252 | ret = (sigh->action[SIGCHLD-1].sa.sa_handler == SIG_IGN) || |
253 | (sigh->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT); | 253 | (sigh->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT); |
254 | spin_unlock(&sigh->siglock); | 254 | spin_unlock(&sigh->siglock); |
255 | return ret; | 255 | return ret; |
256 | } | 256 | } |
257 | 257 | ||
258 | /* | 258 | /* |
259 | * Called with tasklist_lock held for writing. | 259 | * Called with tasklist_lock held for writing. |
260 | * Unlink a traced task, and clean it up if it was a traced zombie. | 260 | * Unlink a traced task, and clean it up if it was a traced zombie. |
261 | * Return true if it needs to be reaped with release_task(). | 261 | * Return true if it needs to be reaped with release_task(). |
262 | * (We can't call release_task() here because we already hold tasklist_lock.) | 262 | * (We can't call release_task() here because we already hold tasklist_lock.) |
263 | * | 263 | * |
264 | * If it's a zombie, our attachedness prevented normal parent notification | 264 | * If it's a zombie, our attachedness prevented normal parent notification |
265 | * or self-reaping. Do notification now if it would have happened earlier. | 265 | * or self-reaping. Do notification now if it would have happened earlier. |
266 | * If it should reap itself, return true. | 266 | * If it should reap itself, return true. |
267 | * | 267 | * |
268 | * If it's our own child, there is no notification to do. But if our normal | 268 | * If it's our own child, there is no notification to do. But if our normal |
269 | * children self-reap, then this child was prevented by ptrace and we must | 269 | * children self-reap, then this child was prevented by ptrace and we must |
270 | * reap it now, in that case we must also wake up sub-threads sleeping in | 270 | * reap it now, in that case we must also wake up sub-threads sleeping in |
271 | * do_wait(). | 271 | * do_wait(). |
272 | */ | 272 | */ |
273 | static bool __ptrace_detach(struct task_struct *tracer, struct task_struct *p) | 273 | static bool __ptrace_detach(struct task_struct *tracer, struct task_struct *p) |
274 | { | 274 | { |
275 | __ptrace_unlink(p); | 275 | __ptrace_unlink(p); |
276 | 276 | ||
277 | if (p->exit_state == EXIT_ZOMBIE) { | 277 | if (p->exit_state == EXIT_ZOMBIE) { |
278 | if (!task_detached(p) && thread_group_empty(p)) { | 278 | if (!task_detached(p) && thread_group_empty(p)) { |
279 | if (!same_thread_group(p->real_parent, tracer)) | 279 | if (!same_thread_group(p->real_parent, tracer)) |
280 | do_notify_parent(p, p->exit_signal); | 280 | do_notify_parent(p, p->exit_signal); |
281 | else if (ignoring_children(tracer->sighand)) { | 281 | else if (ignoring_children(tracer->sighand)) { |
282 | __wake_up_parent(p, tracer); | 282 | __wake_up_parent(p, tracer); |
283 | p->exit_signal = -1; | 283 | p->exit_signal = -1; |
284 | } | 284 | } |
285 | } | 285 | } |
286 | if (task_detached(p)) { | 286 | if (task_detached(p)) { |
287 | /* Mark it as in the process of being reaped. */ | 287 | /* Mark it as in the process of being reaped. */ |
288 | p->exit_state = EXIT_DEAD; | 288 | p->exit_state = EXIT_DEAD; |
289 | return true; | 289 | return true; |
290 | } | 290 | } |
291 | } | 291 | } |
292 | 292 | ||
293 | return false; | 293 | return false; |
294 | } | 294 | } |
295 | 295 | ||
296 | int ptrace_detach(struct task_struct *child, unsigned int data) | 296 | int ptrace_detach(struct task_struct *child, unsigned int data) |
297 | { | 297 | { |
298 | bool dead = false; | 298 | bool dead = false; |
299 | 299 | ||
300 | if (!valid_signal(data)) | 300 | if (!valid_signal(data)) |
301 | return -EIO; | 301 | return -EIO; |
302 | 302 | ||
303 | /* Architecture-specific hardware disable .. */ | 303 | /* Architecture-specific hardware disable .. */ |
304 | ptrace_disable(child); | 304 | ptrace_disable(child); |
305 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 305 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
306 | 306 | ||
307 | write_lock_irq(&tasklist_lock); | 307 | write_lock_irq(&tasklist_lock); |
308 | /* | 308 | /* |
309 | * This child can be already killed. Make sure de_thread() or | 309 | * This child can be already killed. Make sure de_thread() or |
310 | * our sub-thread doing do_wait() didn't do release_task() yet. | 310 | * our sub-thread doing do_wait() didn't do release_task() yet. |
311 | */ | 311 | */ |
312 | if (child->ptrace) { | 312 | if (child->ptrace) { |
313 | child->exit_code = data; | 313 | child->exit_code = data; |
314 | dead = __ptrace_detach(current, child); | 314 | dead = __ptrace_detach(current, child); |
315 | if (!child->exit_state) | 315 | if (!child->exit_state) |
316 | wake_up_process(child); | 316 | wake_up_process(child); |
317 | } | 317 | } |
318 | write_unlock_irq(&tasklist_lock); | 318 | write_unlock_irq(&tasklist_lock); |
319 | 319 | ||
320 | if (unlikely(dead)) | 320 | if (unlikely(dead)) |
321 | release_task(child); | 321 | release_task(child); |
322 | 322 | ||
323 | return 0; | 323 | return 0; |
324 | } | 324 | } |
325 | 325 | ||
326 | /* | 326 | /* |
327 | * Detach all tasks we were using ptrace on. Called with tasklist held | 327 | * Detach all tasks we were using ptrace on. Called with tasklist held |
328 | * for writing, and returns with it held too. But note it can release | 328 | * for writing, and returns with it held too. But note it can release |
329 | * and reacquire the lock. | 329 | * and reacquire the lock. |
330 | */ | 330 | */ |
331 | void exit_ptrace(struct task_struct *tracer) | 331 | void exit_ptrace(struct task_struct *tracer) |
332 | __releases(&tasklist_lock) | 332 | __releases(&tasklist_lock) |
333 | __acquires(&tasklist_lock) | 333 | __acquires(&tasklist_lock) |
334 | { | 334 | { |
335 | struct task_struct *p, *n; | 335 | struct task_struct *p, *n; |
336 | LIST_HEAD(ptrace_dead); | 336 | LIST_HEAD(ptrace_dead); |
337 | 337 | ||
338 | if (likely(list_empty(&tracer->ptraced))) | 338 | if (likely(list_empty(&tracer->ptraced))) |
339 | return; | 339 | return; |
340 | 340 | ||
341 | list_for_each_entry_safe(p, n, &tracer->ptraced, ptrace_entry) { | 341 | list_for_each_entry_safe(p, n, &tracer->ptraced, ptrace_entry) { |
342 | if (__ptrace_detach(tracer, p)) | 342 | if (__ptrace_detach(tracer, p)) |
343 | list_add(&p->ptrace_entry, &ptrace_dead); | 343 | list_add(&p->ptrace_entry, &ptrace_dead); |
344 | } | 344 | } |
345 | 345 | ||
346 | write_unlock_irq(&tasklist_lock); | 346 | write_unlock_irq(&tasklist_lock); |
347 | BUG_ON(!list_empty(&tracer->ptraced)); | 347 | BUG_ON(!list_empty(&tracer->ptraced)); |
348 | 348 | ||
349 | list_for_each_entry_safe(p, n, &ptrace_dead, ptrace_entry) { | 349 | list_for_each_entry_safe(p, n, &ptrace_dead, ptrace_entry) { |
350 | list_del_init(&p->ptrace_entry); | 350 | list_del_init(&p->ptrace_entry); |
351 | release_task(p); | 351 | release_task(p); |
352 | } | 352 | } |
353 | 353 | ||
354 | write_lock_irq(&tasklist_lock); | 354 | write_lock_irq(&tasklist_lock); |
355 | } | 355 | } |
356 | 356 | ||
357 | int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len) | 357 | int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len) |
358 | { | 358 | { |
359 | int copied = 0; | 359 | int copied = 0; |
360 | 360 | ||
361 | while (len > 0) { | 361 | while (len > 0) { |
362 | char buf[128]; | 362 | char buf[128]; |
363 | int this_len, retval; | 363 | int this_len, retval; |
364 | 364 | ||
365 | this_len = (len > sizeof(buf)) ? sizeof(buf) : len; | 365 | this_len = (len > sizeof(buf)) ? sizeof(buf) : len; |
366 | retval = access_process_vm(tsk, src, buf, this_len, 0); | 366 | retval = access_process_vm(tsk, src, buf, this_len, 0); |
367 | if (!retval) { | 367 | if (!retval) { |
368 | if (copied) | 368 | if (copied) |
369 | break; | 369 | break; |
370 | return -EIO; | 370 | return -EIO; |
371 | } | 371 | } |
372 | if (copy_to_user(dst, buf, retval)) | 372 | if (copy_to_user(dst, buf, retval)) |
373 | return -EFAULT; | 373 | return -EFAULT; |
374 | copied += retval; | 374 | copied += retval; |
375 | src += retval; | 375 | src += retval; |
376 | dst += retval; | 376 | dst += retval; |
377 | len -= retval; | 377 | len -= retval; |
378 | } | 378 | } |
379 | return copied; | 379 | return copied; |
380 | } | 380 | } |
381 | 381 | ||
382 | int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len) | 382 | int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len) |
383 | { | 383 | { |
384 | int copied = 0; | 384 | int copied = 0; |
385 | 385 | ||
386 | while (len > 0) { | 386 | while (len > 0) { |
387 | char buf[128]; | 387 | char buf[128]; |
388 | int this_len, retval; | 388 | int this_len, retval; |
389 | 389 | ||
390 | this_len = (len > sizeof(buf)) ? sizeof(buf) : len; | 390 | this_len = (len > sizeof(buf)) ? sizeof(buf) : len; |
391 | if (copy_from_user(buf, src, this_len)) | 391 | if (copy_from_user(buf, src, this_len)) |
392 | return -EFAULT; | 392 | return -EFAULT; |
393 | retval = access_process_vm(tsk, dst, buf, this_len, 1); | 393 | retval = access_process_vm(tsk, dst, buf, this_len, 1); |
394 | if (!retval) { | 394 | if (!retval) { |
395 | if (copied) | 395 | if (copied) |
396 | break; | 396 | break; |
397 | return -EIO; | 397 | return -EIO; |
398 | } | 398 | } |
399 | copied += retval; | 399 | copied += retval; |
400 | src += retval; | 400 | src += retval; |
401 | dst += retval; | 401 | dst += retval; |
402 | len -= retval; | 402 | len -= retval; |
403 | } | 403 | } |
404 | return copied; | 404 | return copied; |
405 | } | 405 | } |
406 | 406 | ||
407 | static int ptrace_setoptions(struct task_struct *child, long data) | 407 | static int ptrace_setoptions(struct task_struct *child, unsigned long data) |
408 | { | 408 | { |
409 | child->ptrace &= ~PT_TRACE_MASK; | 409 | child->ptrace &= ~PT_TRACE_MASK; |
410 | 410 | ||
411 | if (data & PTRACE_O_TRACESYSGOOD) | 411 | if (data & PTRACE_O_TRACESYSGOOD) |
412 | child->ptrace |= PT_TRACESYSGOOD; | 412 | child->ptrace |= PT_TRACESYSGOOD; |
413 | 413 | ||
414 | if (data & PTRACE_O_TRACEFORK) | 414 | if (data & PTRACE_O_TRACEFORK) |
415 | child->ptrace |= PT_TRACE_FORK; | 415 | child->ptrace |= PT_TRACE_FORK; |
416 | 416 | ||
417 | if (data & PTRACE_O_TRACEVFORK) | 417 | if (data & PTRACE_O_TRACEVFORK) |
418 | child->ptrace |= PT_TRACE_VFORK; | 418 | child->ptrace |= PT_TRACE_VFORK; |
419 | 419 | ||
420 | if (data & PTRACE_O_TRACECLONE) | 420 | if (data & PTRACE_O_TRACECLONE) |
421 | child->ptrace |= PT_TRACE_CLONE; | 421 | child->ptrace |= PT_TRACE_CLONE; |
422 | 422 | ||
423 | if (data & PTRACE_O_TRACEEXEC) | 423 | if (data & PTRACE_O_TRACEEXEC) |
424 | child->ptrace |= PT_TRACE_EXEC; | 424 | child->ptrace |= PT_TRACE_EXEC; |
425 | 425 | ||
426 | if (data & PTRACE_O_TRACEVFORKDONE) | 426 | if (data & PTRACE_O_TRACEVFORKDONE) |
427 | child->ptrace |= PT_TRACE_VFORK_DONE; | 427 | child->ptrace |= PT_TRACE_VFORK_DONE; |
428 | 428 | ||
429 | if (data & PTRACE_O_TRACEEXIT) | 429 | if (data & PTRACE_O_TRACEEXIT) |
430 | child->ptrace |= PT_TRACE_EXIT; | 430 | child->ptrace |= PT_TRACE_EXIT; |
431 | 431 | ||
432 | return (data & ~PTRACE_O_MASK) ? -EINVAL : 0; | 432 | return (data & ~PTRACE_O_MASK) ? -EINVAL : 0; |
433 | } | 433 | } |
434 | 434 | ||
435 | static int ptrace_getsiginfo(struct task_struct *child, siginfo_t *info) | 435 | static int ptrace_getsiginfo(struct task_struct *child, siginfo_t *info) |
436 | { | 436 | { |
437 | unsigned long flags; | 437 | unsigned long flags; |
438 | int error = -ESRCH; | 438 | int error = -ESRCH; |
439 | 439 | ||
440 | if (lock_task_sighand(child, &flags)) { | 440 | if (lock_task_sighand(child, &flags)) { |
441 | error = -EINVAL; | 441 | error = -EINVAL; |
442 | if (likely(child->last_siginfo != NULL)) { | 442 | if (likely(child->last_siginfo != NULL)) { |
443 | *info = *child->last_siginfo; | 443 | *info = *child->last_siginfo; |
444 | error = 0; | 444 | error = 0; |
445 | } | 445 | } |
446 | unlock_task_sighand(child, &flags); | 446 | unlock_task_sighand(child, &flags); |
447 | } | 447 | } |
448 | return error; | 448 | return error; |
449 | } | 449 | } |
450 | 450 | ||
451 | static int ptrace_setsiginfo(struct task_struct *child, const siginfo_t *info) | 451 | static int ptrace_setsiginfo(struct task_struct *child, const siginfo_t *info) |
452 | { | 452 | { |
453 | unsigned long flags; | 453 | unsigned long flags; |
454 | int error = -ESRCH; | 454 | int error = -ESRCH; |
455 | 455 | ||
456 | if (lock_task_sighand(child, &flags)) { | 456 | if (lock_task_sighand(child, &flags)) { |
457 | error = -EINVAL; | 457 | error = -EINVAL; |
458 | if (likely(child->last_siginfo != NULL)) { | 458 | if (likely(child->last_siginfo != NULL)) { |
459 | *child->last_siginfo = *info; | 459 | *child->last_siginfo = *info; |
460 | error = 0; | 460 | error = 0; |
461 | } | 461 | } |
462 | unlock_task_sighand(child, &flags); | 462 | unlock_task_sighand(child, &flags); |
463 | } | 463 | } |
464 | return error; | 464 | return error; |
465 | } | 465 | } |
466 | 466 | ||
467 | 467 | ||
468 | #ifdef PTRACE_SINGLESTEP | 468 | #ifdef PTRACE_SINGLESTEP |
469 | #define is_singlestep(request) ((request) == PTRACE_SINGLESTEP) | 469 | #define is_singlestep(request) ((request) == PTRACE_SINGLESTEP) |
470 | #else | 470 | #else |
471 | #define is_singlestep(request) 0 | 471 | #define is_singlestep(request) 0 |
472 | #endif | 472 | #endif |
473 | 473 | ||
474 | #ifdef PTRACE_SINGLEBLOCK | 474 | #ifdef PTRACE_SINGLEBLOCK |
475 | #define is_singleblock(request) ((request) == PTRACE_SINGLEBLOCK) | 475 | #define is_singleblock(request) ((request) == PTRACE_SINGLEBLOCK) |
476 | #else | 476 | #else |
477 | #define is_singleblock(request) 0 | 477 | #define is_singleblock(request) 0 |
478 | #endif | 478 | #endif |
479 | 479 | ||
480 | #ifdef PTRACE_SYSEMU | 480 | #ifdef PTRACE_SYSEMU |
481 | #define is_sysemu_singlestep(request) ((request) == PTRACE_SYSEMU_SINGLESTEP) | 481 | #define is_sysemu_singlestep(request) ((request) == PTRACE_SYSEMU_SINGLESTEP) |
482 | #else | 482 | #else |
483 | #define is_sysemu_singlestep(request) 0 | 483 | #define is_sysemu_singlestep(request) 0 |
484 | #endif | 484 | #endif |
485 | 485 | ||
486 | static int ptrace_resume(struct task_struct *child, long request, long data) | 486 | static int ptrace_resume(struct task_struct *child, long request, |
487 | unsigned long data) | ||
487 | { | 488 | { |
488 | if (!valid_signal(data)) | 489 | if (!valid_signal(data)) |
489 | return -EIO; | 490 | return -EIO; |
490 | 491 | ||
491 | if (request == PTRACE_SYSCALL) | 492 | if (request == PTRACE_SYSCALL) |
492 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 493 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
493 | else | 494 | else |
494 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 495 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
495 | 496 | ||
496 | #ifdef TIF_SYSCALL_EMU | 497 | #ifdef TIF_SYSCALL_EMU |
497 | if (request == PTRACE_SYSEMU || request == PTRACE_SYSEMU_SINGLESTEP) | 498 | if (request == PTRACE_SYSEMU || request == PTRACE_SYSEMU_SINGLESTEP) |
498 | set_tsk_thread_flag(child, TIF_SYSCALL_EMU); | 499 | set_tsk_thread_flag(child, TIF_SYSCALL_EMU); |
499 | else | 500 | else |
500 | clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); | 501 | clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); |
501 | #endif | 502 | #endif |
502 | 503 | ||
503 | if (is_singleblock(request)) { | 504 | if (is_singleblock(request)) { |
504 | if (unlikely(!arch_has_block_step())) | 505 | if (unlikely(!arch_has_block_step())) |
505 | return -EIO; | 506 | return -EIO; |
506 | user_enable_block_step(child); | 507 | user_enable_block_step(child); |
507 | } else if (is_singlestep(request) || is_sysemu_singlestep(request)) { | 508 | } else if (is_singlestep(request) || is_sysemu_singlestep(request)) { |
508 | if (unlikely(!arch_has_single_step())) | 509 | if (unlikely(!arch_has_single_step())) |
509 | return -EIO; | 510 | return -EIO; |
510 | user_enable_single_step(child); | 511 | user_enable_single_step(child); |
511 | } else { | 512 | } else { |
512 | user_disable_single_step(child); | 513 | user_disable_single_step(child); |
513 | } | 514 | } |
514 | 515 | ||
515 | child->exit_code = data; | 516 | child->exit_code = data; |
516 | wake_up_process(child); | 517 | wake_up_process(child); |
517 | 518 | ||
518 | return 0; | 519 | return 0; |
519 | } | 520 | } |
520 | 521 | ||
521 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK | 522 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK |
522 | 523 | ||
523 | static const struct user_regset * | 524 | static const struct user_regset * |
524 | find_regset(const struct user_regset_view *view, unsigned int type) | 525 | find_regset(const struct user_regset_view *view, unsigned int type) |
525 | { | 526 | { |
526 | const struct user_regset *regset; | 527 | const struct user_regset *regset; |
527 | int n; | 528 | int n; |
528 | 529 | ||
529 | for (n = 0; n < view->n; ++n) { | 530 | for (n = 0; n < view->n; ++n) { |
530 | regset = view->regsets + n; | 531 | regset = view->regsets + n; |
531 | if (regset->core_note_type == type) | 532 | if (regset->core_note_type == type) |
532 | return regset; | 533 | return regset; |
533 | } | 534 | } |
534 | 535 | ||
535 | return NULL; | 536 | return NULL; |
536 | } | 537 | } |
537 | 538 | ||
538 | static int ptrace_regset(struct task_struct *task, int req, unsigned int type, | 539 | static int ptrace_regset(struct task_struct *task, int req, unsigned int type, |
539 | struct iovec *kiov) | 540 | struct iovec *kiov) |
540 | { | 541 | { |
541 | const struct user_regset_view *view = task_user_regset_view(task); | 542 | const struct user_regset_view *view = task_user_regset_view(task); |
542 | const struct user_regset *regset = find_regset(view, type); | 543 | const struct user_regset *regset = find_regset(view, type); |
543 | int regset_no; | 544 | int regset_no; |
544 | 545 | ||
545 | if (!regset || (kiov->iov_len % regset->size) != 0) | 546 | if (!regset || (kiov->iov_len % regset->size) != 0) |
546 | return -EINVAL; | 547 | return -EINVAL; |
547 | 548 | ||
548 | regset_no = regset - view->regsets; | 549 | regset_no = regset - view->regsets; |
549 | kiov->iov_len = min(kiov->iov_len, | 550 | kiov->iov_len = min(kiov->iov_len, |
550 | (__kernel_size_t) (regset->n * regset->size)); | 551 | (__kernel_size_t) (regset->n * regset->size)); |
551 | 552 | ||
552 | if (req == PTRACE_GETREGSET) | 553 | if (req == PTRACE_GETREGSET) |
553 | return copy_regset_to_user(task, view, regset_no, 0, | 554 | return copy_regset_to_user(task, view, regset_no, 0, |
554 | kiov->iov_len, kiov->iov_base); | 555 | kiov->iov_len, kiov->iov_base); |
555 | else | 556 | else |
556 | return copy_regset_from_user(task, view, regset_no, 0, | 557 | return copy_regset_from_user(task, view, regset_no, 0, |
557 | kiov->iov_len, kiov->iov_base); | 558 | kiov->iov_len, kiov->iov_base); |
558 | } | 559 | } |
559 | 560 | ||
560 | #endif | 561 | #endif |
561 | 562 | ||
562 | int ptrace_request(struct task_struct *child, long request, | 563 | int ptrace_request(struct task_struct *child, long request, |
563 | long addr, long data) | 564 | unsigned long addr, unsigned long data) |
564 | { | 565 | { |
565 | int ret = -EIO; | 566 | int ret = -EIO; |
566 | siginfo_t siginfo; | 567 | siginfo_t siginfo; |
567 | 568 | ||
568 | switch (request) { | 569 | switch (request) { |
569 | case PTRACE_PEEKTEXT: | 570 | case PTRACE_PEEKTEXT: |
570 | case PTRACE_PEEKDATA: | 571 | case PTRACE_PEEKDATA: |
571 | return generic_ptrace_peekdata(child, addr, data); | 572 | return generic_ptrace_peekdata(child, addr, data); |
572 | case PTRACE_POKETEXT: | 573 | case PTRACE_POKETEXT: |
573 | case PTRACE_POKEDATA: | 574 | case PTRACE_POKEDATA: |
574 | return generic_ptrace_pokedata(child, addr, data); | 575 | return generic_ptrace_pokedata(child, addr, data); |
575 | 576 | ||
576 | #ifdef PTRACE_OLDSETOPTIONS | 577 | #ifdef PTRACE_OLDSETOPTIONS |
577 | case PTRACE_OLDSETOPTIONS: | 578 | case PTRACE_OLDSETOPTIONS: |
578 | #endif | 579 | #endif |
579 | case PTRACE_SETOPTIONS: | 580 | case PTRACE_SETOPTIONS: |
580 | ret = ptrace_setoptions(child, data); | 581 | ret = ptrace_setoptions(child, data); |
581 | break; | 582 | break; |
582 | case PTRACE_GETEVENTMSG: | 583 | case PTRACE_GETEVENTMSG: |
583 | ret = put_user(child->ptrace_message, (unsigned long __user *) data); | 584 | ret = put_user(child->ptrace_message, (unsigned long __user *) data); |
584 | break; | 585 | break; |
585 | 586 | ||
586 | case PTRACE_GETSIGINFO: | 587 | case PTRACE_GETSIGINFO: |
587 | ret = ptrace_getsiginfo(child, &siginfo); | 588 | ret = ptrace_getsiginfo(child, &siginfo); |
588 | if (!ret) | 589 | if (!ret) |
589 | ret = copy_siginfo_to_user((siginfo_t __user *) data, | 590 | ret = copy_siginfo_to_user((siginfo_t __user *) data, |
590 | &siginfo); | 591 | &siginfo); |
591 | break; | 592 | break; |
592 | 593 | ||
593 | case PTRACE_SETSIGINFO: | 594 | case PTRACE_SETSIGINFO: |
594 | if (copy_from_user(&siginfo, (siginfo_t __user *) data, | 595 | if (copy_from_user(&siginfo, (siginfo_t __user *) data, |
595 | sizeof siginfo)) | 596 | sizeof siginfo)) |
596 | ret = -EFAULT; | 597 | ret = -EFAULT; |
597 | else | 598 | else |
598 | ret = ptrace_setsiginfo(child, &siginfo); | 599 | ret = ptrace_setsiginfo(child, &siginfo); |
599 | break; | 600 | break; |
600 | 601 | ||
601 | case PTRACE_DETACH: /* detach a process that was attached. */ | 602 | case PTRACE_DETACH: /* detach a process that was attached. */ |
602 | ret = ptrace_detach(child, data); | 603 | ret = ptrace_detach(child, data); |
603 | break; | 604 | break; |
604 | 605 | ||
605 | #ifdef CONFIG_BINFMT_ELF_FDPIC | 606 | #ifdef CONFIG_BINFMT_ELF_FDPIC |
606 | case PTRACE_GETFDPIC: { | 607 | case PTRACE_GETFDPIC: { |
607 | struct mm_struct *mm = get_task_mm(child); | 608 | struct mm_struct *mm = get_task_mm(child); |
608 | unsigned long tmp = 0; | 609 | unsigned long tmp = 0; |
609 | 610 | ||
610 | ret = -ESRCH; | 611 | ret = -ESRCH; |
611 | if (!mm) | 612 | if (!mm) |
612 | break; | 613 | break; |
613 | 614 | ||
614 | switch (addr) { | 615 | switch (addr) { |
615 | case PTRACE_GETFDPIC_EXEC: | 616 | case PTRACE_GETFDPIC_EXEC: |
616 | tmp = mm->context.exec_fdpic_loadmap; | 617 | tmp = mm->context.exec_fdpic_loadmap; |
617 | break; | 618 | break; |
618 | case PTRACE_GETFDPIC_INTERP: | 619 | case PTRACE_GETFDPIC_INTERP: |
619 | tmp = mm->context.interp_fdpic_loadmap; | 620 | tmp = mm->context.interp_fdpic_loadmap; |
620 | break; | 621 | break; |
621 | default: | 622 | default: |
622 | break; | 623 | break; |
623 | } | 624 | } |
624 | mmput(mm); | 625 | mmput(mm); |
625 | 626 | ||
626 | ret = put_user(tmp, (unsigned long __user *) data); | 627 | ret = put_user(tmp, (unsigned long __user *) data); |
627 | break; | 628 | break; |
628 | } | 629 | } |
629 | #endif | 630 | #endif |
630 | 631 | ||
631 | #ifdef PTRACE_SINGLESTEP | 632 | #ifdef PTRACE_SINGLESTEP |
632 | case PTRACE_SINGLESTEP: | 633 | case PTRACE_SINGLESTEP: |
633 | #endif | 634 | #endif |
634 | #ifdef PTRACE_SINGLEBLOCK | 635 | #ifdef PTRACE_SINGLEBLOCK |
635 | case PTRACE_SINGLEBLOCK: | 636 | case PTRACE_SINGLEBLOCK: |
636 | #endif | 637 | #endif |
637 | #ifdef PTRACE_SYSEMU | 638 | #ifdef PTRACE_SYSEMU |
638 | case PTRACE_SYSEMU: | 639 | case PTRACE_SYSEMU: |
639 | case PTRACE_SYSEMU_SINGLESTEP: | 640 | case PTRACE_SYSEMU_SINGLESTEP: |
640 | #endif | 641 | #endif |
641 | case PTRACE_SYSCALL: | 642 | case PTRACE_SYSCALL: |
642 | case PTRACE_CONT: | 643 | case PTRACE_CONT: |
643 | return ptrace_resume(child, request, data); | 644 | return ptrace_resume(child, request, data); |
644 | 645 | ||
645 | case PTRACE_KILL: | 646 | case PTRACE_KILL: |
646 | if (child->exit_state) /* already dead */ | 647 | if (child->exit_state) /* already dead */ |
647 | return 0; | 648 | return 0; |
648 | return ptrace_resume(child, request, SIGKILL); | 649 | return ptrace_resume(child, request, SIGKILL); |
649 | 650 | ||
650 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK | 651 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK |
651 | case PTRACE_GETREGSET: | 652 | case PTRACE_GETREGSET: |
652 | case PTRACE_SETREGSET: | 653 | case PTRACE_SETREGSET: |
653 | { | 654 | { |
654 | struct iovec kiov; | 655 | struct iovec kiov; |
655 | struct iovec __user *uiov = (struct iovec __user *) data; | 656 | struct iovec __user *uiov = (struct iovec __user *) data; |
656 | 657 | ||
657 | if (!access_ok(VERIFY_WRITE, uiov, sizeof(*uiov))) | 658 | if (!access_ok(VERIFY_WRITE, uiov, sizeof(*uiov))) |
658 | return -EFAULT; | 659 | return -EFAULT; |
659 | 660 | ||
660 | if (__get_user(kiov.iov_base, &uiov->iov_base) || | 661 | if (__get_user(kiov.iov_base, &uiov->iov_base) || |
661 | __get_user(kiov.iov_len, &uiov->iov_len)) | 662 | __get_user(kiov.iov_len, &uiov->iov_len)) |
662 | return -EFAULT; | 663 | return -EFAULT; |
663 | 664 | ||
664 | ret = ptrace_regset(child, request, addr, &kiov); | 665 | ret = ptrace_regset(child, request, addr, &kiov); |
665 | if (!ret) | 666 | if (!ret) |
666 | ret = __put_user(kiov.iov_len, &uiov->iov_len); | 667 | ret = __put_user(kiov.iov_len, &uiov->iov_len); |
667 | break; | 668 | break; |
668 | } | 669 | } |
669 | #endif | 670 | #endif |
670 | default: | 671 | default: |
671 | break; | 672 | break; |
672 | } | 673 | } |
673 | 674 | ||
674 | return ret; | 675 | return ret; |
675 | } | 676 | } |
676 | 677 | ||
677 | static struct task_struct *ptrace_get_task_struct(pid_t pid) | 678 | static struct task_struct *ptrace_get_task_struct(pid_t pid) |
678 | { | 679 | { |
679 | struct task_struct *child; | 680 | struct task_struct *child; |
680 | 681 | ||
681 | rcu_read_lock(); | 682 | rcu_read_lock(); |
682 | child = find_task_by_vpid(pid); | 683 | child = find_task_by_vpid(pid); |
683 | if (child) | 684 | if (child) |
684 | get_task_struct(child); | 685 | get_task_struct(child); |
685 | rcu_read_unlock(); | 686 | rcu_read_unlock(); |
686 | 687 | ||
687 | if (!child) | 688 | if (!child) |
688 | return ERR_PTR(-ESRCH); | 689 | return ERR_PTR(-ESRCH); |
689 | return child; | 690 | return child; |
690 | } | 691 | } |
691 | 692 | ||
692 | #ifndef arch_ptrace_attach | 693 | #ifndef arch_ptrace_attach |
693 | #define arch_ptrace_attach(child) do { } while (0) | 694 | #define arch_ptrace_attach(child) do { } while (0) |
694 | #endif | 695 | #endif |
695 | 696 | ||
696 | SYSCALL_DEFINE4(ptrace, long, request, long, pid, long, addr, long, data) | 697 | SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr, |
698 | unsigned long, data) | ||
697 | { | 699 | { |
698 | struct task_struct *child; | 700 | struct task_struct *child; |
699 | long ret; | 701 | long ret; |
700 | 702 | ||
701 | if (request == PTRACE_TRACEME) { | 703 | if (request == PTRACE_TRACEME) { |
702 | ret = ptrace_traceme(); | 704 | ret = ptrace_traceme(); |
703 | if (!ret) | 705 | if (!ret) |
704 | arch_ptrace_attach(current); | 706 | arch_ptrace_attach(current); |
705 | goto out; | 707 | goto out; |
706 | } | 708 | } |
707 | 709 | ||
708 | child = ptrace_get_task_struct(pid); | 710 | child = ptrace_get_task_struct(pid); |
709 | if (IS_ERR(child)) { | 711 | if (IS_ERR(child)) { |
710 | ret = PTR_ERR(child); | 712 | ret = PTR_ERR(child); |
711 | goto out; | 713 | goto out; |
712 | } | 714 | } |
713 | 715 | ||
714 | if (request == PTRACE_ATTACH) { | 716 | if (request == PTRACE_ATTACH) { |
715 | ret = ptrace_attach(child); | 717 | ret = ptrace_attach(child); |
716 | /* | 718 | /* |
717 | * Some architectures need to do book-keeping after | 719 | * Some architectures need to do book-keeping after |
718 | * a ptrace attach. | 720 | * a ptrace attach. |
719 | */ | 721 | */ |
720 | if (!ret) | 722 | if (!ret) |
721 | arch_ptrace_attach(child); | 723 | arch_ptrace_attach(child); |
722 | goto out_put_task_struct; | 724 | goto out_put_task_struct; |
723 | } | 725 | } |
724 | 726 | ||
725 | ret = ptrace_check_attach(child, request == PTRACE_KILL); | 727 | ret = ptrace_check_attach(child, request == PTRACE_KILL); |
726 | if (ret < 0) | 728 | if (ret < 0) |
727 | goto out_put_task_struct; | 729 | goto out_put_task_struct; |
728 | 730 | ||
729 | ret = arch_ptrace(child, request, addr, data); | 731 | ret = arch_ptrace(child, request, addr, data); |
730 | 732 | ||
731 | out_put_task_struct: | 733 | out_put_task_struct: |
732 | put_task_struct(child); | 734 | put_task_struct(child); |
733 | out: | 735 | out: |
734 | return ret; | 736 | return ret; |
735 | } | 737 | } |
736 | 738 | ||
737 | int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data) | 739 | int generic_ptrace_peekdata(struct task_struct *tsk, unsigned long addr, |
740 | unsigned long data) | ||
738 | { | 741 | { |
739 | unsigned long tmp; | 742 | unsigned long tmp; |
740 | int copied; | 743 | int copied; |
741 | 744 | ||
742 | copied = access_process_vm(tsk, addr, &tmp, sizeof(tmp), 0); | 745 | copied = access_process_vm(tsk, addr, &tmp, sizeof(tmp), 0); |
743 | if (copied != sizeof(tmp)) | 746 | if (copied != sizeof(tmp)) |
744 | return -EIO; | 747 | return -EIO; |
745 | return put_user(tmp, (unsigned long __user *)data); | 748 | return put_user(tmp, (unsigned long __user *)data); |
746 | } | 749 | } |
747 | 750 | ||
748 | int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data) | 751 | int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr, |
752 | unsigned long data) | ||
749 | { | 753 | { |
750 | int copied; | 754 | int copied; |
751 | 755 | ||
752 | copied = access_process_vm(tsk, addr, &data, sizeof(data), 1); | 756 | copied = access_process_vm(tsk, addr, &data, sizeof(data), 1); |
753 | return (copied == sizeof(data)) ? 0 : -EIO; | 757 | return (copied == sizeof(data)) ? 0 : -EIO; |
754 | } | 758 | } |
755 | 759 | ||
756 | #if defined CONFIG_COMPAT | 760 | #if defined CONFIG_COMPAT |
757 | #include <linux/compat.h> | 761 | #include <linux/compat.h> |
758 | 762 | ||
759 | int compat_ptrace_request(struct task_struct *child, compat_long_t request, | 763 | int compat_ptrace_request(struct task_struct *child, compat_long_t request, |
760 | compat_ulong_t addr, compat_ulong_t data) | 764 | compat_ulong_t addr, compat_ulong_t data) |
761 | { | 765 | { |
762 | compat_ulong_t __user *datap = compat_ptr(data); | 766 | compat_ulong_t __user *datap = compat_ptr(data); |
763 | compat_ulong_t word; | 767 | compat_ulong_t word; |
764 | siginfo_t siginfo; | 768 | siginfo_t siginfo; |
765 | int ret; | 769 | int ret; |
766 | 770 | ||
767 | switch (request) { | 771 | switch (request) { |
768 | case PTRACE_PEEKTEXT: | 772 | case PTRACE_PEEKTEXT: |
769 | case PTRACE_PEEKDATA: | 773 | case PTRACE_PEEKDATA: |
770 | ret = access_process_vm(child, addr, &word, sizeof(word), 0); | 774 | ret = access_process_vm(child, addr, &word, sizeof(word), 0); |
771 | if (ret != sizeof(word)) | 775 | if (ret != sizeof(word)) |
772 | ret = -EIO; | 776 | ret = -EIO; |
773 | else | 777 | else |
774 | ret = put_user(word, datap); | 778 | ret = put_user(word, datap); |
775 | break; | 779 | break; |
776 | 780 | ||
777 | case PTRACE_POKETEXT: | 781 | case PTRACE_POKETEXT: |
778 | case PTRACE_POKEDATA: | 782 | case PTRACE_POKEDATA: |
779 | ret = access_process_vm(child, addr, &data, sizeof(data), 1); | 783 | ret = access_process_vm(child, addr, &data, sizeof(data), 1); |
780 | ret = (ret != sizeof(data) ? -EIO : 0); | 784 | ret = (ret != sizeof(data) ? -EIO : 0); |
781 | break; | 785 | break; |
782 | 786 | ||
783 | case PTRACE_GETEVENTMSG: | 787 | case PTRACE_GETEVENTMSG: |
784 | ret = put_user((compat_ulong_t) child->ptrace_message, datap); | 788 | ret = put_user((compat_ulong_t) child->ptrace_message, datap); |
785 | break; | 789 | break; |
786 | 790 | ||
787 | case PTRACE_GETSIGINFO: | 791 | case PTRACE_GETSIGINFO: |
788 | ret = ptrace_getsiginfo(child, &siginfo); | 792 | ret = ptrace_getsiginfo(child, &siginfo); |
789 | if (!ret) | 793 | if (!ret) |
790 | ret = copy_siginfo_to_user32( | 794 | ret = copy_siginfo_to_user32( |
791 | (struct compat_siginfo __user *) datap, | 795 | (struct compat_siginfo __user *) datap, |
792 | &siginfo); | 796 | &siginfo); |
793 | break; | 797 | break; |
794 | 798 | ||
795 | case PTRACE_SETSIGINFO: | 799 | case PTRACE_SETSIGINFO: |
796 | memset(&siginfo, 0, sizeof siginfo); | 800 | memset(&siginfo, 0, sizeof siginfo); |
797 | if (copy_siginfo_from_user32( | 801 | if (copy_siginfo_from_user32( |
798 | &siginfo, (struct compat_siginfo __user *) datap)) | 802 | &siginfo, (struct compat_siginfo __user *) datap)) |
799 | ret = -EFAULT; | 803 | ret = -EFAULT; |
800 | else | 804 | else |
801 | ret = ptrace_setsiginfo(child, &siginfo); | 805 | ret = ptrace_setsiginfo(child, &siginfo); |
802 | break; | 806 | break; |
803 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK | 807 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK |
804 | case PTRACE_GETREGSET: | 808 | case PTRACE_GETREGSET: |
805 | case PTRACE_SETREGSET: | 809 | case PTRACE_SETREGSET: |
806 | { | 810 | { |
807 | struct iovec kiov; | 811 | struct iovec kiov; |
808 | struct compat_iovec __user *uiov = | 812 | struct compat_iovec __user *uiov = |
809 | (struct compat_iovec __user *) datap; | 813 | (struct compat_iovec __user *) datap; |
810 | compat_uptr_t ptr; | 814 | compat_uptr_t ptr; |
811 | compat_size_t len; | 815 | compat_size_t len; |
812 | 816 | ||
813 | if (!access_ok(VERIFY_WRITE, uiov, sizeof(*uiov))) | 817 | if (!access_ok(VERIFY_WRITE, uiov, sizeof(*uiov))) |
814 | return -EFAULT; | 818 | return -EFAULT; |
815 | 819 | ||
816 | if (__get_user(ptr, &uiov->iov_base) || | 820 | if (__get_user(ptr, &uiov->iov_base) || |
817 | __get_user(len, &uiov->iov_len)) | 821 | __get_user(len, &uiov->iov_len)) |
818 | return -EFAULT; | 822 | return -EFAULT; |
819 | 823 | ||
820 | kiov.iov_base = compat_ptr(ptr); | 824 | kiov.iov_base = compat_ptr(ptr); |
821 | kiov.iov_len = len; | 825 | kiov.iov_len = len; |
822 | 826 | ||
823 | ret = ptrace_regset(child, request, addr, &kiov); | 827 | ret = ptrace_regset(child, request, addr, &kiov); |
824 | if (!ret) | 828 | if (!ret) |
825 | ret = __put_user(kiov.iov_len, &uiov->iov_len); | 829 | ret = __put_user(kiov.iov_len, &uiov->iov_len); |
826 | break; | 830 | break; |
827 | } | 831 | } |
828 | #endif | 832 | #endif |
829 | 833 | ||
830 | default: | 834 | default: |
831 | ret = ptrace_request(child, request, addr, data); | 835 | ret = ptrace_request(child, request, addr, data); |
832 | } | 836 | } |
833 | 837 | ||
834 | return ret; | 838 | return ret; |
835 | } | 839 | } |
836 | 840 | ||
837 | asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, | 841 | asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, |
838 | compat_long_t addr, compat_long_t data) | 842 | compat_long_t addr, compat_long_t data) |
839 | { | 843 | { |
840 | struct task_struct *child; | 844 | struct task_struct *child; |
841 | long ret; | 845 | long ret; |
842 | 846 | ||
843 | if (request == PTRACE_TRACEME) { | 847 | if (request == PTRACE_TRACEME) { |
844 | ret = ptrace_traceme(); | 848 | ret = ptrace_traceme(); |
845 | goto out; | 849 | goto out; |
846 | } | 850 | } |
847 | 851 | ||
848 | child = ptrace_get_task_struct(pid); | 852 | child = ptrace_get_task_struct(pid); |
849 | if (IS_ERR(child)) { | 853 | if (IS_ERR(child)) { |
850 | ret = PTR_ERR(child); | 854 | ret = PTR_ERR(child); |
851 | goto out; | 855 | goto out; |
852 | } | 856 | } |
853 | 857 | ||
854 | if (request == PTRACE_ATTACH) { | 858 | if (request == PTRACE_ATTACH) { |
855 | ret = ptrace_attach(child); | 859 | ret = ptrace_attach(child); |
856 | /* | 860 | /* |
857 | * Some architectures need to do book-keeping after | 861 | * Some architectures need to do book-keeping after |
858 | * a ptrace attach. | 862 | * a ptrace attach. |
859 | */ | 863 | */ |
860 | if (!ret) | 864 | if (!ret) |
861 | arch_ptrace_attach(child); | 865 | arch_ptrace_attach(child); |
862 | goto out_put_task_struct; | 866 | goto out_put_task_struct; |
863 | } | 867 | } |
864 | 868 | ||
865 | ret = ptrace_check_attach(child, request == PTRACE_KILL); | 869 | ret = ptrace_check_attach(child, request == PTRACE_KILL); |
866 | if (!ret) | 870 | if (!ret) |
867 | ret = compat_arch_ptrace(child, request, addr, data); | 871 | ret = compat_arch_ptrace(child, request, addr, data); |
868 | 872 | ||
869 | out_put_task_struct: | 873 | out_put_task_struct: |
870 | put_task_struct(child); | 874 | put_task_struct(child); |
871 | out: | 875 | out: |
872 | return ret; | 876 | return ret; |
873 | } | 877 | } |
874 | #endif /* CONFIG_COMPAT */ | 878 | #endif /* CONFIG_COMPAT */ |
875 | 879 |