[gimp] libgimpbase: in gimp_stack_trace_print(), enable ptrace under Yama



commit 0f2c966c5f83d5370e1b9b507146cab25c833471
Author: Ell <ell_se yahoo com>
Date:   Sun Mar 4 23:26:13 2018 -0500

    libgimpbase: in gimp_stack_trace_print(), enable ptrace under Yama
    
    On Linux, when /proc/sys/kernel/yama/ptrace_scope is 1, a process
    may only ptrace its descendants by default, which prevents the GDB
    process spawned by gimp_stack_trace_print() from attaching to, and
    producing a backtrace for, the calling process.
    
    Use prctl() with PR_SET_PTRACER, when available, in the parent
    process, to allow the child process to ptrace it.

 configure.ac            |    2 +-
 libgimpbase/gimputils.c |   33 ++++++++++++++++++++++++++++++++-
 2 files changed, 33 insertions(+), 2 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 03ddfb9..14c2e20 100644
--- a/configure.ac
+++ b/configure.ac
@@ -562,7 +562,7 @@ AC_HEADER_STDC
 AC_HEADER_SYS_WAIT
 AC_HEADER_TIME
 
-AC_CHECK_HEADERS(execinfo.h sys/param.h sys/time.h sys/times.h sys/wait.h unistd.h)
+AC_CHECK_HEADERS(execinfo.h sys/param.h sys/prctl.h sys/time.h sys/times.h sys/wait.h unistd.h)
 AC_CHECK_FUNCS(backtrace, , AC_CHECK_LIB(execinfo, backtrace))
 
 AC_TYPE_PID_T
diff --git a/libgimpbase/gimputils.c b/libgimpbase/gimputils.c
index c088a9c..745e692 100644
--- a/libgimpbase/gimputils.c
+++ b/libgimpbase/gimputils.c
@@ -48,6 +48,12 @@
 #else /* G_OS_WIN32 */
 /* For waitpid() */
 #include <sys/wait.h>
+#include <unistd.h>
+#include <errno.h>
+
+#ifdef HAVE_SYS_PRCTL_H
+#include <sys/prctl.h>
+#endif
 #endif /* G_OS_WIN32 */
 
 #include "gimpbasetypes.h"
@@ -1159,12 +1165,21 @@ gimp_stack_trace_print (const gchar *prog_name,
   pid_t    pid;
   gchar    buffer[256];
   ssize_t  read_n;
+  int      sync_fd[2];
   int      out_fd[2];
 
   g_snprintf (gimp_pid, 16, "%u", (guint) getpid ());
 
+  if (pipe (sync_fd) == -1)
+    {
+      return FALSE;
+    }
+
   if (pipe (out_fd) == -1)
     {
+      close (sync_fd[0]);
+      close (sync_fd[1]);
+
       return FALSE;
     }
 
@@ -1180,6 +1195,15 @@ gimp_stack_trace_print (const gchar *prog_name,
 
       args[5] = gimp_pid;
 
+      /* Wait until the parent enabled us to ptrace it. */
+      {
+        gchar dummy;
+
+        close (sync_fd[1]);
+        while (read (sync_fd[0], &dummy, 1) < 0 && errno == EINTR);
+        close (sync_fd[0]);
+      }
+
       /* Redirect the debugger output. */
       dup2 (out_fd[1], STDOUT_FILENO);
       close (out_fd[0]);
@@ -1213,7 +1237,12 @@ gimp_stack_trace_print (const gchar *prog_name,
       /* Main process */
       int status;
 
-      waitpid (pid, &status, 0);
+      /* Allow the child to ptrace us, and signal it to start. */
+      close (sync_fd[0]);
+#ifdef PR_SET_PTRACER
+      prctl (PR_SET_PTRACER, pid, 0, 0, 0);
+#endif
+      close (sync_fd[1]);
 
       /* It is important to close the writing side of the pipe, otherwise
        * the read() will wait forever without getting the information that
@@ -1221,6 +1250,8 @@ gimp_stack_trace_print (const gchar *prog_name,
        */
       close (out_fd[1]);
 
+      waitpid (pid, &status, 0);
+
       while ((read_n = read (out_fd[0], buffer, 256)) > 0)
         {
           /* It's hard to know if the debugger was found since it


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]