01917d
http://sourceware.org/ml/gdb-patches/2012-03/msg00171.html
01917d
Subject: [patch 3/3] attach-fail-reasons: SELinux deny_ptrace
01917d
01917d
Hi,
01917d
01917d
and here is the last bit for new SELinux 'deny_ptrace':
01917d
	https://bugzilla.redhat.com/show_bug.cgi?id=786878
01917d
01917d
As even PTRACE_TRACEME fails in such case it needs to install hook for even
01917d
that event.
01917d
01917d
01917d
Thanks,
01917d
Jan
01917d
01917d
01917d
gdb/
01917d
2012-03-06  Jan Kratochvil  <jan.kratochvil@redhat.com>
01917d
01917d
	* common/linux-ptrace.c [HAVE_SELINUX_SELINUX_H]: include
01917d
	selinux/selinux.h.
01917d
	(linux_ptrace_attach_warnings): Call linux_ptrace_create_warnings.
01917d
	(linux_ptrace_create_warnings): New.
01917d
	* common/linux-ptrace.h (linux_ptrace_create_warnings): New declaration.
01917d
	* config.in: Regenerate.
01917d
	* configure: Regenerate.
01917d
	* configure.ac: Check selinux/selinux.h and the selinux library.
01917d
	* inf-ptrace.c (inf_ptrace_me): Check the ptrace result.
01917d
	* linux-nat.c (linux_nat_create_inferior): New variable ex.  Wrap
01917d
	to_create_inferior into TRY_CATCH, call linux_ptrace_create_warnings.
01917d
01917d
gdb/gdbserver/
01917d
	* config.in: Regenerate.
01917d
	* configure: Regenerate.
01917d
	* configure.ac: Check selinux/selinux.h and the selinux library.
01917d
	* linux-low.c (linux_traceme): New function.
01917d
	(linux_create_inferior, linux_tracefork_child): Call it instead of
01917d
	direct ptrace.
01917d
01917d
Index: gdb-7.5.50.20130215/gdb/common/linux-ptrace.c
01917d
===================================================================
01917d
--- gdb-7.5.50.20130215.orig/gdb/common/linux-ptrace.c	2013-01-08 20:38:51.000000000 +0100
01917d
+++ gdb-7.5.50.20130215/gdb/common/linux-ptrace.c	2013-02-15 22:38:05.782456279 +0100
01917d
@@ -29,6 +29,10 @@
01917d
 #include "gdb_assert.h"
01917d
 #include "gdb_wait.h"
01917d
 
01917d
+#ifdef HAVE_SELINUX_SELINUX_H
01917d
+# include <selinux/selinux.h>
01917d
+#endif /* HAVE_SELINUX_SELINUX_H */
01917d
+
01917d
 /* Find all possible reasons we could fail to attach PID and append these
01917d
    newline terminated reason strings to initialized BUFFER.  '\0' termination
01917d
    of BUFFER must be done by the caller.  */
01917d
@@ -48,6 +52,8 @@ linux_ptrace_attach_warnings (pid_t pid,
01917d
     buffer_xml_printf (buffer, _("warning: process %d is a zombie "
01917d
 				 "- the process has already terminated\n"),
01917d
 		       (int) pid);
01917d
+
01917d
+  linux_ptrace_create_warnings (buffer);
01917d
 }
01917d
 
01917d
 #if defined __i386__ || defined __x86_64__
01917d
@@ -243,3 +249,19 @@ linux_ptrace_init_warnings (void)
01917d
 
01917d
   linux_ptrace_test_ret_to_nx ();
01917d
 }
01917d
+
01917d
+/* Print all possible reasons we could fail to create a traced process.  */
01917d
+
01917d
+void
01917d
+linux_ptrace_create_warnings (struct buffer *buffer)
01917d
+{
01917d
+#ifdef HAVE_LIBSELINUX
01917d
+  /* -1 is returned for errors, 0 if it has no effect, 1 if PTRACE_ATTACH is
01917d
+     forbidden.  */
01917d
+  if (security_get_boolean_active ("deny_ptrace") == 1)
01917d
+    buffer_xml_printf (buffer,
01917d
+		       _("the SELinux boolean 'deny_ptrace' is enabled, "
01917d
+			 "you can disable this process attach protection by: "
01917d
+			 "(gdb) shell sudo setsebool deny_ptrace=0"));
01917d
+#endif /* HAVE_LIBSELINUX */
01917d
+}
01917d
Index: gdb-7.5.50.20130215/gdb/common/linux-ptrace.h
01917d
===================================================================
01917d
--- gdb-7.5.50.20130215.orig/gdb/common/linux-ptrace.h	2013-01-01 07:32:54.000000000 +0100
01917d
+++ gdb-7.5.50.20130215/gdb/common/linux-ptrace.h	2013-02-15 22:38:05.782456279 +0100
01917d
@@ -69,5 +69,6 @@ struct buffer;
01917d
 
01917d
 extern void linux_ptrace_attach_warnings (pid_t pid, struct buffer *buffer);
01917d
 extern void linux_ptrace_init_warnings (void);
01917d
+extern void linux_ptrace_create_warnings (struct buffer *buffer);
01917d
 
01917d
 #endif /* COMMON_LINUX_PTRACE_H */
01917d
Index: gdb-7.5.50.20130215/gdb/configure.ac
01917d
===================================================================
01917d
--- gdb-7.5.50.20130215.orig/gdb/configure.ac	2013-02-15 22:37:57.000000000 +0100
01917d
+++ gdb-7.5.50.20130215/gdb/configure.ac	2013-02-15 22:38:05.783456281 +0100
01917d
@@ -2068,6 +2068,10 @@ then
01917d
 	      [Define if you support the personality syscall.])
01917d
 fi
01917d
 
01917d
+dnl Check security_get_boolean_active availability.
01917d
+AC_CHECK_HEADERS(selinux/selinux.h)
01917d
+AC_CHECK_LIB(selinux, security_get_boolean_active)
01917d
+
01917d
 dnl Handle optional features that can be enabled.
01917d
 
01917d
 # Support for --with-sysroot is a copy of GDB_AC_WITH_DIR,
01917d
Index: gdb-7.5.50.20130215/gdb/gdbserver/configure.ac
01917d
===================================================================
01917d
--- gdb-7.5.50.20130215.orig/gdb/gdbserver/configure.ac	2013-01-01 07:33:00.000000000 +0100
01917d
+++ gdb-7.5.50.20130215/gdb/gdbserver/configure.ac	2013-02-15 22:38:05.783456281 +0100
01917d
@@ -451,6 +451,10 @@ if $want_ipa ; then
01917d
    fi
01917d
 fi
01917d
 
01917d
+dnl Check security_get_boolean_active availability.
01917d
+AC_CHECK_HEADERS(selinux/selinux.h)
01917d
+AC_CHECK_LIB(selinux, security_get_boolean_active)
01917d
+
01917d
 AC_SUBST(GDBSERVER_DEPFILES)
01917d
 AC_SUBST(GDBSERVER_LIBS)
01917d
 AC_SUBST(USE_THREAD_DB)
01917d
Index: gdb-7.5.50.20130215/gdb/gdbserver/linux-low.c
01917d
===================================================================
01917d
--- gdb-7.5.50.20130215.orig/gdb/gdbserver/linux-low.c	2013-02-04 18:47:00.000000000 +0100
01917d
+++ gdb-7.5.50.20130215/gdb/gdbserver/linux-low.c	2013-02-15 22:39:54.256591069 +0100
01917d
@@ -602,6 +602,29 @@ add_lwp (ptid_t ptid)
01917d
   return lwp;
01917d
 }
01917d
 
01917d
+/* Execute PTRACE_TRACEME with error checking.  */
01917d
+
01917d
+static void
01917d
+linux_traceme (const char *program)
01917d
+{
01917d
+  int save_errno;
01917d
+  struct buffer buffer;
01917d
+
01917d
+  errno = 0;
01917d
+  if (ptrace (PTRACE_TRACEME, 0,
01917d
+	      (PTRACE_ARG3_TYPE) 0, (PTRACE_ARG4_TYPE) 0) == 0)
01917d
+    return;
01917d
+
01917d
+  save_errno = errno;
01917d
+  buffer_init (&buffer);
01917d
+  linux_ptrace_create_warnings (&buffer);
01917d
+  buffer_grow_str0 (&buffer, "");
01917d
+  fprintf (stderr, _("%sCannot trace created process %s: %s.\n"),
01917d
+	   buffer_finish (&buffer), program, strerror (save_errno));
01917d
+  fflush (stderr);
01917d
+  _exit (0177);
01917d
+}
01917d
+
01917d
 /* Start an inferior process and returns its pid.
01917d
    ALLARGS is a vector of program-name and args. */
01917d
 
01917d
@@ -642,7 +665,7 @@ linux_create_inferior (char *program, ch
01917d
 
01917d
   if (pid == 0)
01917d
     {
01917d
-      ptrace (PTRACE_TRACEME, 0, (PTRACE_ARG3_TYPE) 0, (PTRACE_ARG4_TYPE) 0);
01917d
+      linux_traceme (program);
01917d
 
01917d
 #ifndef __ANDROID__ /* Bionic doesn't use SIGRTMIN the way glibc does.  */
01917d
       signal (__SIGRTMIN + 1, SIG_DFL);
01917d
@@ -4587,7 +4610,7 @@ linux_tracefork_grandchild (void *arg)
01917d
 static int
01917d
 linux_tracefork_child (void *arg)
01917d
 {
01917d
-  ptrace (PTRACE_TRACEME, 0, (PTRACE_ARG3_TYPE) 0, (PTRACE_ARG4_TYPE) 0);
01917d
+  linux_traceme ("PTRACE_O_TRACEFORK test");
01917d
   kill (getpid (), SIGSTOP);
01917d
 
01917d
 #if !(defined(__UCLIBC__) && defined(HAS_NOMMU))
01917d
Index: gdb-7.5.50.20130215/gdb/inf-ptrace.c
01917d
===================================================================
01917d
--- gdb-7.5.50.20130215.orig/gdb/inf-ptrace.c	2013-01-01 07:32:45.000000000 +0100
01917d
+++ gdb-7.5.50.20130215/gdb/inf-ptrace.c	2013-02-15 22:38:05.786456289 +0100
01917d
@@ -104,7 +104,15 @@ static void
01917d
 inf_ptrace_me (void)
01917d
 {
01917d
   /* "Trace me, Dr. Memory!"  */
01917d
+  errno = 0;
01917d
   ptrace (PT_TRACE_ME, 0, (PTRACE_TYPE_ARG3)0, 0);
01917d
+  if (errno != 0)
01917d
+    {
01917d
+      fprintf_unfiltered (gdb_stderr, _("Cannot create process: %s\n"),
01917d
+			  safe_strerror (errno));
01917d
+      gdb_flush (gdb_stderr);
01917d
+      _exit (0177);
01917d
+    }
01917d
 }
01917d
 
01917d
 /* Start a new inferior Unix child process.  EXEC_FILE is the file to
01917d
Index: gdb-7.5.50.20130215/gdb/linux-nat.c
01917d
===================================================================
01917d
--- gdb-7.5.50.20130215.orig/gdb/linux-nat.c	2013-02-15 22:34:44.000000000 +0100
01917d
+++ gdb-7.5.50.20130215/gdb/linux-nat.c	2013-02-15 22:38:05.787456291 +0100
01917d
@@ -1557,6 +1557,7 @@ linux_nat_create_inferior (struct target
01917d
 #ifdef HAVE_PERSONALITY
01917d
   int personality_orig = 0, personality_set = 0;
01917d
 #endif /* HAVE_PERSONALITY */
01917d
+  volatile struct gdb_exception ex;
01917d
 
01917d
   /* The fork_child mechanism is synchronous and calls target_wait, so
01917d
      we have to mask the async mode.  */
01917d
@@ -1581,7 +1582,10 @@ linux_nat_create_inferior (struct target
01917d
   /* Make sure we report all signals during startup.  */
01917d
   linux_nat_pass_signals (0, NULL);
01917d
 
01917d
-  linux_ops->to_create_inferior (ops, exec_file, allargs, env, from_tty);
01917d
+  TRY_CATCH (ex, RETURN_MASK_ERROR)
01917d
+    {
01917d
+      linux_ops->to_create_inferior (ops, exec_file, allargs, env, from_tty);
01917d
+    }
01917d
 
01917d
 #ifdef HAVE_PERSONALITY
01917d
   if (personality_set)
01917d
@@ -1593,6 +1597,24 @@ linux_nat_create_inferior (struct target
01917d
 		 safe_strerror (errno));
01917d
     }
01917d
 #endif /* HAVE_PERSONALITY */
01917d
+
01917d
+  if (ex.reason < 0)
01917d
+    {
01917d
+      struct buffer buffer;
01917d
+      char *message, *buffer_s;
01917d
+
01917d
+      message = xstrdup (ex.message);
01917d
+      make_cleanup (xfree, message);
01917d
+
01917d
+      buffer_init (&buffer);
01917d
+      linux_ptrace_create_warnings (&buffer);
01917d
+
01917d
+      buffer_grow_str0 (&buffer, "");
01917d
+      buffer_s = buffer_finish (&buffer);
01917d
+      make_cleanup (xfree, buffer_s);
01917d
+
01917d
+      throw_error (ex.error, "%s%s", buffer_s, message);
01917d
+    }
01917d
 }
01917d
 
01917d
 static void