linux-ptrace.c revision 1.9 1 1.1 christos /* Linux-specific ptrace manipulation routines.
2 1.9 christos Copyright (C) 2012-2024 Free Software Foundation, Inc.
3 1.1 christos
4 1.1 christos This file is part of GDB.
5 1.1 christos
6 1.1 christos This program is free software; you can redistribute it and/or modify
7 1.1 christos it under the terms of the GNU General Public License as published by
8 1.1 christos the Free Software Foundation; either version 3 of the License, or
9 1.1 christos (at your option) any later version.
10 1.1 christos
11 1.1 christos This program is distributed in the hope that it will be useful,
12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 1.1 christos GNU General Public License for more details.
15 1.1 christos
16 1.1 christos You should have received a copy of the GNU General Public License
17 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 1.1 christos
19 1.1 christos #include "linux-ptrace.h"
20 1.1 christos #include "linux-procfs.h"
21 1.1 christos #include "linux-waitpid.h"
22 1.5 christos #ifdef HAVE_SYS_PROCFS_H
23 1.4 christos #include <sys/procfs.h>
24 1.5 christos #endif
25 1.1 christos
26 1.3 christos /* Stores the ptrace options supported by the running kernel.
27 1.3 christos A value of -1 means we did not check for features yet. A value
28 1.3 christos of 0 means there are no supported features. */
29 1.3 christos static int supported_ptrace_options = -1;
30 1.1 christos
31 1.6 christos /* Find all possible reasons we could fail to attach PID and return these
32 1.6 christos as a string. An empty string is returned if we didn't find any reason. */
33 1.1 christos
34 1.6 christos std::string
35 1.6 christos linux_ptrace_attach_fail_reason (pid_t pid)
36 1.1 christos {
37 1.6 christos pid_t tracerpid = linux_proc_get_tracerpid_nowarn (pid);
38 1.6 christos std::string result;
39 1.1 christos
40 1.1 christos if (tracerpid > 0)
41 1.6 christos string_appendf (result,
42 1.6 christos _("process %d is already traced by process %d"),
43 1.6 christos (int) pid, (int) tracerpid);
44 1.1 christos
45 1.1 christos if (linux_proc_pid_is_zombie_nowarn (pid))
46 1.6 christos string_appendf (result,
47 1.6 christos _("process %d is a zombie - the process has already "
48 1.6 christos "terminated"),
49 1.6 christos (int) pid);
50 1.6 christos
51 1.6 christos return result;
52 1.1 christos }
53 1.1 christos
54 1.1 christos /* See linux-ptrace.h. */
55 1.1 christos
56 1.6 christos std::string
57 1.1 christos linux_ptrace_attach_fail_reason_string (ptid_t ptid, int err)
58 1.1 christos {
59 1.6 christos long lwpid = ptid.lwp ();
60 1.6 christos std::string reason = linux_ptrace_attach_fail_reason (lwpid);
61 1.6 christos
62 1.6 christos if (!reason.empty ())
63 1.6 christos return string_printf ("%s (%d), %s", safe_strerror (err), err,
64 1.6 christos reason.c_str ());
65 1.1 christos else
66 1.6 christos return string_printf ("%s (%d)", safe_strerror (err), err);
67 1.1 christos }
68 1.1 christos
69 1.1 christos #if defined __i386__ || defined __x86_64__
70 1.1 christos
71 1.1 christos /* Address of the 'ret' instruction in asm code block below. */
72 1.9 christos extern "C" void linux_ptrace_test_ret_to_nx_instr (void);
73 1.1 christos
74 1.1 christos #include <sys/reg.h>
75 1.1 christos #include <sys/mman.h>
76 1.1 christos #include <signal.h>
77 1.1 christos
78 1.1 christos #endif /* defined __i386__ || defined __x86_64__ */
79 1.1 christos
80 1.6 christos /* Kill CHILD. WHO is used to report warnings. */
81 1.6 christos
82 1.6 christos static void
83 1.6 christos kill_child (pid_t child, const char *who)
84 1.6 christos {
85 1.6 christos pid_t got_pid;
86 1.6 christos int kill_status;
87 1.6 christos
88 1.6 christos if (kill (child, SIGKILL) != 0)
89 1.6 christos {
90 1.6 christos warning (_("%s: failed to kill child pid %ld %s"),
91 1.6 christos who, (long) child, safe_strerror (errno));
92 1.6 christos return;
93 1.6 christos }
94 1.6 christos
95 1.6 christos errno = 0;
96 1.6 christos got_pid = my_waitpid (child, &kill_status, 0);
97 1.6 christos if (got_pid != child)
98 1.6 christos {
99 1.6 christos warning (_("%s: "
100 1.6 christos "kill waitpid returned %ld: %s"),
101 1.6 christos who, (long) got_pid, safe_strerror (errno));
102 1.6 christos return;
103 1.6 christos }
104 1.6 christos if (!WIFSIGNALED (kill_status))
105 1.6 christos {
106 1.6 christos warning (_("%s: "
107 1.6 christos "kill status %d is not WIFSIGNALED!"),
108 1.6 christos who, kill_status);
109 1.6 christos return;
110 1.6 christos }
111 1.6 christos }
112 1.6 christos
113 1.1 christos /* Test broken off-trunk Linux kernel patchset for NX support on i386. It was
114 1.1 christos removed in Fedora kernel 88fa1f0332d188795ed73d7ac2b1564e11a0b4cd.
115 1.1 christos
116 1.1 christos Test also x86_64 arch for PaX support. */
117 1.1 christos
118 1.1 christos static void
119 1.1 christos linux_ptrace_test_ret_to_nx (void)
120 1.1 christos {
121 1.1 christos #if defined __i386__ || defined __x86_64__
122 1.1 christos pid_t child, got_pid;
123 1.1 christos gdb_byte *return_address, *pc;
124 1.1 christos long l;
125 1.6 christos int status;
126 1.4 christos elf_gregset_t regs;
127 1.1 christos
128 1.4 christos return_address
129 1.4 christos = (gdb_byte *) mmap (NULL, 2, PROT_READ | PROT_WRITE,
130 1.1 christos MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
131 1.1 christos if (return_address == MAP_FAILED)
132 1.1 christos {
133 1.1 christos warning (_("linux_ptrace_test_ret_to_nx: Cannot mmap: %s"),
134 1.3 christos safe_strerror (errno));
135 1.1 christos return;
136 1.1 christos }
137 1.1 christos
138 1.1 christos /* Put there 'int3'. */
139 1.1 christos *return_address = 0xcc;
140 1.1 christos
141 1.1 christos child = fork ();
142 1.1 christos switch (child)
143 1.1 christos {
144 1.1 christos case -1:
145 1.1 christos warning (_("linux_ptrace_test_ret_to_nx: Cannot fork: %s"),
146 1.3 christos safe_strerror (errno));
147 1.1 christos return;
148 1.1 christos
149 1.1 christos case 0:
150 1.1 christos l = ptrace (PTRACE_TRACEME, 0, (PTRACE_TYPE_ARG3) NULL,
151 1.1 christos (PTRACE_TYPE_ARG4) NULL);
152 1.1 christos if (l != 0)
153 1.1 christos warning (_("linux_ptrace_test_ret_to_nx: Cannot PTRACE_TRACEME: %s"),
154 1.3 christos safe_strerror (errno));
155 1.1 christos else
156 1.1 christos {
157 1.1 christos #if defined __i386__
158 1.1 christos asm volatile ("pushl %0;"
159 1.1 christos ".globl linux_ptrace_test_ret_to_nx_instr;"
160 1.1 christos "linux_ptrace_test_ret_to_nx_instr:"
161 1.1 christos "ret"
162 1.6 christos : : "r" (return_address) : "memory");
163 1.1 christos #elif defined __x86_64__
164 1.1 christos asm volatile ("pushq %0;"
165 1.1 christos ".globl linux_ptrace_test_ret_to_nx_instr;"
166 1.1 christos "linux_ptrace_test_ret_to_nx_instr:"
167 1.1 christos "ret"
168 1.1 christos : : "r" ((uint64_t) (uintptr_t) return_address)
169 1.6 christos : "memory");
170 1.1 christos #else
171 1.1 christos # error "!__i386__ && !__x86_64__"
172 1.1 christos #endif
173 1.1 christos gdb_assert_not_reached ("asm block did not terminate");
174 1.1 christos }
175 1.1 christos
176 1.1 christos _exit (1);
177 1.1 christos }
178 1.1 christos
179 1.1 christos errno = 0;
180 1.1 christos got_pid = waitpid (child, &status, 0);
181 1.1 christos if (got_pid != child)
182 1.1 christos {
183 1.1 christos warning (_("linux_ptrace_test_ret_to_nx: waitpid returned %ld: %s"),
184 1.3 christos (long) got_pid, safe_strerror (errno));
185 1.1 christos return;
186 1.1 christos }
187 1.1 christos
188 1.1 christos if (WIFSIGNALED (status))
189 1.1 christos {
190 1.1 christos if (WTERMSIG (status) != SIGKILL)
191 1.1 christos warning (_("linux_ptrace_test_ret_to_nx: WTERMSIG %d is not SIGKILL!"),
192 1.1 christos (int) WTERMSIG (status));
193 1.1 christos else
194 1.1 christos warning (_("Cannot call inferior functions, Linux kernel PaX "
195 1.1 christos "protection forbids return to non-executable pages!"));
196 1.1 christos return;
197 1.1 christos }
198 1.1 christos
199 1.1 christos if (!WIFSTOPPED (status))
200 1.1 christos {
201 1.1 christos warning (_("linux_ptrace_test_ret_to_nx: status %d is not WIFSTOPPED!"),
202 1.1 christos status);
203 1.6 christos kill_child (child, "linux_ptrace_test_ret_to_nx");
204 1.1 christos return;
205 1.1 christos }
206 1.1 christos
207 1.1 christos /* We may get SIGSEGV due to missing PROT_EXEC of the return_address. */
208 1.1 christos if (WSTOPSIG (status) != SIGTRAP && WSTOPSIG (status) != SIGSEGV)
209 1.1 christos {
210 1.1 christos warning (_("linux_ptrace_test_ret_to_nx: "
211 1.1 christos "WSTOPSIG %d is neither SIGTRAP nor SIGSEGV!"),
212 1.1 christos (int) WSTOPSIG (status));
213 1.6 christos kill_child (child, "linux_ptrace_test_ret_to_nx");
214 1.1 christos return;
215 1.1 christos }
216 1.1 christos
217 1.4 christos if (ptrace (PTRACE_GETREGS, child, (PTRACE_TYPE_ARG3) 0,
218 1.4 christos (PTRACE_TYPE_ARG4) ®s) < 0)
219 1.4 christos {
220 1.4 christos warning (_("linux_ptrace_test_ret_to_nx: Cannot PTRACE_GETREGS: %s"),
221 1.4 christos safe_strerror (errno));
222 1.4 christos }
223 1.1 christos #if defined __i386__
224 1.4 christos pc = (gdb_byte *) (uintptr_t) regs[EIP];
225 1.1 christos #elif defined __x86_64__
226 1.4 christos pc = (gdb_byte *) (uintptr_t) regs[RIP];
227 1.1 christos #else
228 1.1 christos # error "!__i386__ && !__x86_64__"
229 1.1 christos #endif
230 1.1 christos
231 1.6 christos kill_child (child, "linux_ptrace_test_ret_to_nx");
232 1.1 christos
233 1.1 christos /* + 1 is there as x86* stops after the 'int3' instruction. */
234 1.1 christos if (WSTOPSIG (status) == SIGTRAP && pc == return_address + 1)
235 1.1 christos {
236 1.1 christos /* PASS */
237 1.1 christos return;
238 1.1 christos }
239 1.1 christos
240 1.1 christos /* We may get SIGSEGV due to missing PROT_EXEC of the RETURN_ADDRESS page. */
241 1.1 christos if (WSTOPSIG (status) == SIGSEGV && pc == return_address)
242 1.1 christos {
243 1.1 christos /* PASS */
244 1.1 christos return;
245 1.1 christos }
246 1.1 christos
247 1.1 christos if ((void (*) (void)) pc != &linux_ptrace_test_ret_to_nx_instr)
248 1.1 christos warning (_("linux_ptrace_test_ret_to_nx: PC %p is neither near return "
249 1.1 christos "address %p nor is the return instruction %p!"),
250 1.1 christos pc, return_address, &linux_ptrace_test_ret_to_nx_instr);
251 1.1 christos else
252 1.1 christos warning (_("Cannot call inferior functions on this system - "
253 1.1 christos "Linux kernel with broken i386 NX (non-executable pages) "
254 1.1 christos "support detected!"));
255 1.1 christos #endif /* defined __i386__ || defined __x86_64__ */
256 1.1 christos }
257 1.1 christos
258 1.1 christos /* Helper function to fork a process and make the child process call
259 1.1 christos the function FUNCTION, passing CHILD_STACK as parameter.
260 1.1 christos
261 1.1 christos For MMU-less targets, clone is used instead of fork, and
262 1.1 christos CHILD_STACK is used as stack space for the cloned child. If NULL,
263 1.1 christos stack space is allocated via malloc (and subsequently passed to
264 1.1 christos FUNCTION). For MMU targets, CHILD_STACK is ignored. */
265 1.1 christos
266 1.1 christos static int
267 1.4 christos linux_fork_to_function (gdb_byte *child_stack, int (*function) (void *))
268 1.1 christos {
269 1.1 christos int child_pid;
270 1.1 christos
271 1.1 christos /* Sanity check the function pointer. */
272 1.1 christos gdb_assert (function != NULL);
273 1.1 christos
274 1.1 christos #if defined(__UCLIBC__) && defined(HAS_NOMMU)
275 1.1 christos #define STACK_SIZE 4096
276 1.1 christos
277 1.1 christos if (child_stack == NULL)
278 1.6 christos child_stack = (gdb_byte *) xmalloc (STACK_SIZE * 4);
279 1.1 christos
280 1.1 christos /* Use CLONE_VM instead of fork, to support uClinux (no MMU). */
281 1.1 christos #ifdef __ia64__
282 1.1 christos child_pid = __clone2 (function, child_stack, STACK_SIZE,
283 1.1 christos CLONE_VM | SIGCHLD, child_stack + STACK_SIZE * 2);
284 1.1 christos #else /* !__ia64__ */
285 1.1 christos child_pid = clone (function, child_stack + STACK_SIZE,
286 1.1 christos CLONE_VM | SIGCHLD, child_stack + STACK_SIZE * 2);
287 1.1 christos #endif /* !__ia64__ */
288 1.1 christos #else /* !defined(__UCLIBC) && defined(HAS_NOMMU) */
289 1.1 christos child_pid = fork ();
290 1.1 christos
291 1.1 christos if (child_pid == 0)
292 1.1 christos function (NULL);
293 1.1 christos #endif /* defined(__UCLIBC) && defined(HAS_NOMMU) */
294 1.1 christos
295 1.1 christos if (child_pid == -1)
296 1.1 christos perror_with_name (("fork"));
297 1.1 christos
298 1.1 christos return child_pid;
299 1.1 christos }
300 1.1 christos
301 1.1 christos /* A helper function for linux_check_ptrace_features, called after
302 1.1 christos the parent process forks a child. The child allows itself to
303 1.1 christos be traced by its parent. */
304 1.1 christos
305 1.4 christos static int
306 1.4 christos linux_child_function (void *child_stack)
307 1.1 christos {
308 1.1 christos ptrace (PTRACE_TRACEME, 0, (PTRACE_TYPE_ARG3) 0, (PTRACE_TYPE_ARG4) 0);
309 1.1 christos kill (getpid (), SIGSTOP);
310 1.1 christos
311 1.9 christos /* This code is only reachable by the child (grandchild's parent)
312 1.1 christos process. */
313 1.1 christos _exit (0);
314 1.1 christos }
315 1.1 christos
316 1.1 christos static void linux_test_for_exitkill (int child_pid);
317 1.1 christos
318 1.1 christos /* Determine ptrace features available on this target. */
319 1.1 christos
320 1.3 christos void
321 1.1 christos linux_check_ptrace_features (void)
322 1.1 christos {
323 1.1 christos int child_pid, ret, status;
324 1.1 christos
325 1.8 christos /* Initialize the options. We consider that these options are always
326 1.8 christos supported. */
327 1.8 christos supported_ptrace_options
328 1.8 christos = (PTRACE_O_TRACESYSGOOD
329 1.8 christos | PTRACE_O_TRACECLONE
330 1.8 christos | PTRACE_O_TRACEFORK
331 1.8 christos | PTRACE_O_TRACEVFORK
332 1.8 christos | PTRACE_O_TRACEVFORKDONE
333 1.8 christos | PTRACE_O_TRACEEXEC);
334 1.1 christos
335 1.1 christos /* Fork a child so we can do some testing. The child will call
336 1.1 christos linux_child_function and will get traced. The child will
337 1.1 christos eventually fork a grandchild so we can test fork event
338 1.1 christos reporting. */
339 1.1 christos child_pid = linux_fork_to_function (NULL, linux_child_function);
340 1.1 christos
341 1.1 christos ret = my_waitpid (child_pid, &status, 0);
342 1.1 christos if (ret == -1)
343 1.1 christos perror_with_name (("waitpid"));
344 1.1 christos else if (ret != child_pid)
345 1.1 christos error (_("linux_check_ptrace_features: waitpid: unexpected result %d."),
346 1.1 christos ret);
347 1.1 christos if (! WIFSTOPPED (status))
348 1.1 christos error (_("linux_check_ptrace_features: waitpid: unexpected status %d."),
349 1.1 christos status);
350 1.1 christos
351 1.1 christos linux_test_for_exitkill (child_pid);
352 1.1 christos
353 1.6 christos /* Kill child_pid. */
354 1.6 christos kill_child (child_pid, "linux_check_ptrace_features");
355 1.1 christos }
356 1.1 christos
357 1.1 christos /* Determine if PTRACE_O_EXITKILL can be used. */
358 1.1 christos
359 1.1 christos static void
360 1.1 christos linux_test_for_exitkill (int child_pid)
361 1.1 christos {
362 1.1 christos int ret;
363 1.1 christos
364 1.1 christos ret = ptrace (PTRACE_SETOPTIONS, child_pid, (PTRACE_TYPE_ARG3) 0,
365 1.1 christos (PTRACE_TYPE_ARG4) PTRACE_O_EXITKILL);
366 1.1 christos
367 1.1 christos if (ret == 0)
368 1.3 christos supported_ptrace_options |= PTRACE_O_EXITKILL;
369 1.1 christos }
370 1.1 christos
371 1.1 christos /* Enable reporting of all currently supported ptrace events.
372 1.3 christos OPTIONS is a bit mask of extended features we want enabled,
373 1.3 christos if supported by the kernel. PTRACE_O_TRACECLONE is always
374 1.3 christos enabled, if supported. */
375 1.1 christos
376 1.1 christos void
377 1.3 christos linux_enable_event_reporting (pid_t pid, int options)
378 1.1 christos {
379 1.1 christos /* Check if we have initialized the ptrace features for this
380 1.1 christos target. If not, do it now. */
381 1.3 christos if (supported_ptrace_options == -1)
382 1.1 christos linux_check_ptrace_features ();
383 1.1 christos
384 1.3 christos /* We always want clone events. */
385 1.3 christos options |= PTRACE_O_TRACECLONE;
386 1.3 christos
387 1.3 christos /* Filter out unsupported options. */
388 1.3 christos options &= supported_ptrace_options;
389 1.1 christos
390 1.1 christos /* Set the options. */
391 1.1 christos ptrace (PTRACE_SETOPTIONS, pid, (PTRACE_TYPE_ARG3) 0,
392 1.3 christos (PTRACE_TYPE_ARG4) (uintptr_t) options);
393 1.1 christos }
394 1.1 christos
395 1.1 christos /* Disable reporting of all currently supported ptrace events. */
396 1.1 christos
397 1.1 christos void
398 1.1 christos linux_disable_event_reporting (pid_t pid)
399 1.1 christos {
400 1.1 christos /* Set the options. */
401 1.1 christos ptrace (PTRACE_SETOPTIONS, pid, (PTRACE_TYPE_ARG3) 0, 0);
402 1.1 christos }
403 1.1 christos
404 1.1 christos /* Display possible problems on this system. Display them only once per GDB
405 1.1 christos execution. */
406 1.1 christos
407 1.1 christos void
408 1.1 christos linux_ptrace_init_warnings (void)
409 1.1 christos {
410 1.1 christos static int warned = 0;
411 1.1 christos
412 1.1 christos if (warned)
413 1.1 christos return;
414 1.1 christos warned = 1;
415 1.1 christos
416 1.1 christos linux_ptrace_test_ret_to_nx ();
417 1.1 christos }
418 1.1 christos
419 1.1 christos /* Extract extended ptrace event from wait status. */
420 1.1 christos
421 1.1 christos int
422 1.1 christos linux_ptrace_get_extended_event (int wstat)
423 1.1 christos {
424 1.1 christos return (wstat >> 16);
425 1.1 christos }
426 1.1 christos
427 1.1 christos /* Determine whether wait status denotes an extended event. */
428 1.1 christos
429 1.1 christos int
430 1.1 christos linux_is_extended_waitstatus (int wstat)
431 1.1 christos {
432 1.1 christos return (linux_ptrace_get_extended_event (wstat) != 0);
433 1.1 christos }
434 1.3 christos
435 1.3 christos /* Return true if the event in LP may be caused by breakpoint. */
436 1.3 christos
437 1.3 christos int
438 1.3 christos linux_wstatus_maybe_breakpoint (int wstat)
439 1.3 christos {
440 1.3 christos return (WIFSTOPPED (wstat)
441 1.3 christos && (WSTOPSIG (wstat) == SIGTRAP
442 1.3 christos /* SIGILL and SIGSEGV are also treated as traps in case a
443 1.3 christos breakpoint is inserted at the current PC. */
444 1.3 christos || WSTOPSIG (wstat) == SIGILL
445 1.3 christos || WSTOPSIG (wstat) == SIGSEGV));
446 1.3 christos }
447