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