فهرست منبع

Merge branch 'maint'

* maint:
  Tell Travis sudo is needed
  Support forward compat for FreeBSD's procctl PROC_TRACE_CTL
  Simplify DEBUG ifdef handling
  Optimize ptrace detection on FreeBSD 10
  Use FreeBSD 10's procctl(PROC_TRACE_CTL) to disable core dumps and tracing.
  Rebuild with latest autoconf
Bryan Drewery 10 سال پیش
والد
کامیت
66c7684a81
6فایلهای تغییر یافته به همراه112 افزوده شده و 41 حذف شده
  1. 3 0
      .travis.yml
  2. 3 2
      build/autotools/configure.ac
  3. 42 29
      configure
  4. 1 0
      doc/UPDATES.md
  5. 11 2
      src/config.h.in
  6. 52 8
      src/shell.cc

+ 3 - 0
.travis.yml

@@ -35,3 +35,6 @@ script:
 
 # Skip install
 install: true
+
+# State we need old build infrastructure for now
+sudo: required

+ 3 - 2
build/autotools/configure.ac

@@ -94,7 +94,8 @@ AC_HEADER_STAT
 #checkpoint
 AC_CACHE_SAVE 
 AC_CHECK_HEADERS([stdarg.h arpa/inet.h fcntl.h limits.h locale.h netdb.h netinet/in.h])
-AC_CHECK_HEADERS([sys/file.h sys/ioctl.h sys/param.h sys/socket.h wchar.h sys/ptrace.h paths.h sys/prctl.h])
+AC_CHECK_HEADERS([sys/file.h sys/ioctl.h sys/param.h sys/socket.h wchar.h])
+AC_CHECK_HEADERS([sys/ptrace.h paths.h sys/prctl.h sys/procctl.h])
 
 #checkpoint
 AC_CACHE_SAVE
@@ -215,7 +216,7 @@ AC_CHECK_FUNCS([clock fsync getrusage isascii getpassphrase posix_madvise madvis
 AC_CHECK_FUNCS([memcpy memmem memset random rename snprintf srandom gettime])
 #checkpoint
 AC_CACHE_SAVE
-AC_CHECK_FUNCS([strcasecmp strncasecmp vsnprintf inet_ntop])
+AC_CHECK_FUNCS([strcasecmp strncasecmp vsnprintf inet_ntop prctl procctl])
 
 #autoscan suggested this....
 #These are recommended by autoscan, but no code supports it currently

+ 42 - 29
configure

@@ -5756,7 +5756,20 @@ fi
 
 done
 
-for ac_header in sys/file.h sys/ioctl.h sys/param.h sys/socket.h wchar.h sys/ptrace.h paths.h sys/prctl.h
+for ac_header in sys/file.h sys/ioctl.h sys/param.h sys/socket.h wchar.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>build/confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in sys/ptrace.h paths.h sys/prctl.h sys/procctl.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -7263,18 +7276,18 @@ else
 /* end build/confdefs.h.  */
 
   /* For now, do not test the preprocessor; as of 2007 there are too many
-         implementations with broken preprocessors.  Perhaps this can
-         be revisited in 2012.  In the meantime, code should not expect
-         #if to work with literals wider than 32 bits.  */
+	 implementations with broken preprocessors.  Perhaps this can
+	 be revisited in 2012.  In the meantime, code should not expect
+	 #if to work with literals wider than 32 bits.  */
       /* Test literals.  */
       long long int ll = 9223372036854775807ll;
       long long int nll = -9223372036854775807LL;
       unsigned long long int ull = 18446744073709551615ULL;
       /* Test constant expressions.   */
       typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
-                     ? 1 : -1)];
+		     ? 1 : -1)];
       typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1
-                     ? 1 : -1)];
+		     ? 1 : -1)];
       int i = 63;
 int
 main ()
@@ -7283,9 +7296,9 @@ main ()
       long long int llmax = 9223372036854775807ll;
       unsigned long long int ullmax = 18446744073709551615ull;
       return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
-              | (llmax / ll) | (llmax % ll)
-              | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i)
-              | (ullmax / ull) | (ullmax % ull));
+	      | (llmax / ll) | (llmax % ll)
+	      | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i)
+	      | (ullmax / ull) | (ullmax % ull));
   ;
   return 0;
 }
@@ -7317,33 +7330,33 @@ if ${ac_cv_type_long_long_int+:} false; then :
 else
   ac_cv_type_long_long_int=yes
       if test "x${ac_cv_prog_cc_c99-no}" = xno; then
-        ac_cv_type_long_long_int=$ac_cv_type_unsigned_long_long_int
-        if test $ac_cv_type_long_long_int = yes; then
-                                        if test "$cross_compiling" = yes; then :
+	ac_cv_type_long_long_int=$ac_cv_type_unsigned_long_long_int
+	if test $ac_cv_type_long_long_int = yes; then
+	  	  	  	  if test "$cross_compiling" = yes; then :
   :
 else
   cat build/confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end build/confdefs.h.  */
 #include <limits.h>
-                 #ifndef LLONG_MAX
-                 # define HALF \
-                          (1LL << (sizeof (long long int) * CHAR_BIT - 2))
-                 # define LLONG_MAX (HALF - 1 + HALF)
-                 #endif
+		 #ifndef LLONG_MAX
+		 # define HALF \
+			  (1LL << (sizeof (long long int) * CHAR_BIT - 2))
+		 # define LLONG_MAX (HALF - 1 + HALF)
+		 #endif
 int
 main ()
 {
 long long int n = 1;
-                 int i;
-                 for (i = 0; ; i++)
-                   {
-                     long long int m = n << i;
-                     if (m >> i != n)
-                       return 1;
-                     if (LLONG_MAX / 2 < m)
-                       break;
-                   }
-                 return 0;
+		 int i;
+		 for (i = 0; ; i++)
+		   {
+		     long long int m = n << i;
+		     if (m >> i != n)
+		       return 1;
+		     if (LLONG_MAX / 2 < m)
+		       break;
+		   }
+		 return 0;
   ;
   return 0;
 }
@@ -7357,7 +7370,7 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
   conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 
-        fi
+	fi
       fi
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_long_int" >&5
@@ -8923,7 +8936,7 @@ $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
   fi
 fi
 rm -f confcache
-for ac_func in strcasecmp strncasecmp vsnprintf inet_ntop
+for ac_func in strcasecmp strncasecmp vsnprintf inet_ntop prctl procctl
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var"

+ 1 - 0
doc/UPDATES.md

@@ -7,6 +7,7 @@
   * Avoid warnings from Debian's FORTIFY_SOURCE
   * Remove an old +take limiter that was forgotten.
   * Use Linux's prctl(PR_SET_DUMPABLE) to disable core dumps and ptrace(2).
+  * Use FreeBSD 10's procctl(PROC_TRACE_CTL) to disable core dumps and tracing.
   * Fix binary compat issue causing ptrace permission errors on Linux 3.4+
 
 # 1.4.6

+ 11 - 2
src/config.h.in

@@ -99,7 +99,7 @@
 /* Define to 1 if you have the <locale.h> header file. */
 #undef HAVE_LOCALE_H
 
-/* Define to 1 if the system has the type 'long long int'. */
+/* Define to 1 if the system has the type `long long int'. */
 #undef HAVE_LONG_LONG_INT
 
 /* Define to 1 if `lstat' has the bug that it succeeds when given the
@@ -143,6 +143,12 @@
 /* Define to 1 if you have the `posix_madvise' function. */
 #undef HAVE_POSIX_MADVISE
 
+/* Define to 1 if you have the `prctl' function. */
+#undef HAVE_PRCTL
+
+/* Define to 1 if you have the `procctl' function. */
+#undef HAVE_PROCCTL
+
 /* Define to 1 if you have the `random' function. */
 #undef HAVE_RANDOM
 
@@ -219,6 +225,9 @@
 /* Define to 1 if you have the <sys/prctl.h> header file. */
 #undef HAVE_SYS_PRCTL_H
 
+/* Define to 1 if you have the <sys/procctl.h> header file. */
+#undef HAVE_SYS_PROCCTL_H
+
 /* Define to 1 if you have the <sys/ptrace.h> header file. */
 #undef HAVE_SYS_PTRACE_H
 
@@ -264,7 +273,7 @@
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
-/* Define to 1 if the system has the type 'unsigned long long int'. */
+/* Define to 1 if the system has the type `unsigned long long int'. */
 #undef HAVE_UNSIGNED_LONG_LONG_INT
 
 /* Define to 1 if you have the `vfork' function. */

+ 52 - 8
src/shell.cc

@@ -60,6 +60,18 @@
 #define PR_SET_PTRACER 0x59616d61
 #endif
 #endif
+#ifdef HAVE_SYS_PROCCTL_H
+#include <sys/procctl.h>
+#ifndef PROC_TRACE_CTL
+#define PROC_TRACE_CTL		7
+#endif
+#ifndef PROC_TRACE_STATUS
+#define PROC_TRACE_STATUS	8
+#endif
+#ifndef PROC_TRACE_CTL_DISABLE
+#define PROC_TRACE_CTL_DISABLE	2
+#endif
+#endif	/* HAVE_SYS_PROCCTL_H */
 #ifdef HAVE_SYS_PTRACE_H
 # include <sys/ptrace.h>
 #endif /* HAVE_SYS_PTRACE_H */
@@ -262,12 +274,14 @@ void check_promisc()
 #endif /* SIOCGIFCONF */
 }
 
+#ifndef DEBUG
 bool traced = 0;
 
 static void got_sigtrap(int z)
 {
   traced = 0;
 }
+#endif
 
 void check_trace(int start)
 {
@@ -277,6 +291,9 @@ void check_trace(int start)
     prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0);
 #endif
   return;
+#else
+#if defined(HAVE_PROCCTL) && defined(PROC_TRACE_CTL)
+  int status = 0;
 #endif
 
   if (start == 0 && trace == DET_IGNORE)
@@ -284,12 +301,26 @@ void check_trace(int start)
 
   pid_t parent = getpid();
 
-  /* we send ourselves a SIGTRAP, if we recieve, we're not being traced, otherwise we are. */
-  signal(SIGTRAP, got_sigtrap);
-  traced = 1;
-  raise(SIGTRAP);
-  /* no longer need this__asm__("INT3"); //SIGTRAP */
-  signal(SIGTRAP, SIG_DFL);
+#if defined(HAVE_PROCCTL) && defined(PROC_TRACE_CTL)
+  /* FreeBSD let's us know if we're being traced already. */
+  if (procctl(P_PID, parent, PROC_TRACE_STATUS, &status) == 0 &&
+      status > 0) {
+    /* status contains the pid of the tracer. Be mean. */
+    kill(status, SIGSEGV);
+    traced = 1;
+  }
+#endif
+
+  if (!traced) {
+    /* we send ourselves a SIGTRAP, if we recieve, we're not being traced,
+     * otherwise we might be. The debugger may smartly just forward the
+     * signal if it knows it didn't request it, such as FreeBSD truss
+     * after r288903. */
+    signal(SIGTRAP, got_sigtrap);
+    traced = 1;
+    raise(SIGTRAP);
+    signal(SIGTRAP, SIG_DFL);
+  }
 
   if (!traced) {
     signal(SIGINT, got_sigtrap);
@@ -308,16 +339,28 @@ void check_trace(int start)
     if (!start)
       return;
 
-#if defined(PR_SET_DUMPABLE) && defined(PR_GET_DUMPABLE) && !defined(DEBUG)
+    int tracing_safe = 0;
+
+#if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) && defined(PR_GET_DUMPABLE)
     /* Try to disable ptrace and core dumping entirely. */
     if (prctl(PR_GET_DUMPABLE) == 0 ||
         (prctl(PR_SET_DUMPABLE, 0) == 0 && prctl(PR_GET_DUMPABLE) == 0)) {
+      tracing_safe = 1;
+    }
+#elif defined(HAVE_PROCCTL) && defined(PROC_TRACE_CTL)
+    if ((procctl(P_PID, parent, PROC_TRACE_STATUS, &status) == 0 &&
+        status == -1) ||
+        (status = PROC_TRACE_CTL_DISABLE,
+        procctl(P_PID, parent, PROC_TRACE_CTL, &status) == 0)) {
+      tracing_safe = 1;
+    }
+#endif
+    if (tracing_safe) {
       /* We're safe! Don't bother with further checks. */
       putlog(LOG_DEBUG, "*", "Ptrace disabled, no longer checking.");
       trace = DET_IGNORE;
       return;
     }
-#endif
 
 #ifndef __sun__
     int x, i, filedes[2];
@@ -372,6 +415,7 @@ void check_trace(int start)
     }
 #endif
   }
+#endif	/* !DEBUG */
 }
 
 int shell_exec(char *cmdline, char *input, char **output, char **erroutput, bool simple)