svn commit: r256571 - in head: cddl/contrib/opensolaris/lib/libdtrace/common cddl/lib/libdtrace sys/cddl/contrib/opensolaris/uts/common/dtrace sys/cddl/contrib/opensolaris/uts/common/sys sys/cddl/d...

Mark Johnston markj at FreeBSD.org
Wed Oct 16 01:39:27 UTC 2013


Author: markj
Date: Wed Oct 16 01:39:26 2013
New Revision: 256571
URL: http://svnweb.freebsd.org/changeset/base/256571

Log:
  Add a function, memstr, which can be used to convert a buffer of
  null-separated strings to a single string. This can be used to print the
  full arguments of a process using execsnoop (from the DTrace toolkit) or
  with the following one-liner:
  
  dtrace -n 'syscall::execve:return {trace(curpsinfo->pr_psargs);}'
  
  Note that this relies on the process arguments being cached via the struct
  proc, which means that it will not work for argvs longer than
  kern.ps_arg_cache_limit. However, the following rather non-portable
  script can be used to extract any argv at exec time:
  
  fbt::kern_execve:entry
  {
      printf("%s", memstr(args[1]->begin_argv, ' ',
          args[1]->begin_envv - args[1]->begin_argv));
  }
  
  The debug.dtrace.memstr_max sysctl limits the maximum argument size to
  memstr(). Thanks to Brendan Gregg for helpful comments on freebsd-dtrace.
  
  Tested by:	Fabian Keil (earlier version)
  MFC after:	2 weeks

Modified:
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
  head/cddl/lib/libdtrace/psinfo.d
  head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
  head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
  head/sys/cddl/dev/dtrace/dtrace_sysctl.c

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c	Wed Oct 16 00:58:47 2013	(r256570)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c	Wed Oct 16 01:39:26 2013	(r256571)
@@ -311,6 +311,10 @@ static const dt_ident_t _dtrace_globals[
 	&dt_idops_func, "void(@)" },
 { "memref", DT_IDENT_FUNC, 0, DIF_SUBR_MEMREF, DT_ATTR_STABCMN, DT_VERS_1_1,
 	&dt_idops_func, "uintptr_t *(void *, size_t)" },
+#if !defined(sun)
+{ "memstr", DT_IDENT_FUNC, 0, DIF_SUBR_MEMSTR, DT_ATTR_STABCMN, DT_VERS_1_0,
+	&dt_idops_func, "string(void *, char, size_t)" },
+#endif
 { "min", DT_IDENT_AGGFUNC, 0, DTRACEAGG_MIN, DT_ATTR_STABCMN, DT_VERS_1_0,
 	&dt_idops_func, "void(@)" },
 { "mod", DT_IDENT_ACTFUNC, 0, DT_ACT_MOD, DT_ATTR_STABCMN,

Modified: head/cddl/lib/libdtrace/psinfo.d
==============================================================================
--- head/cddl/lib/libdtrace/psinfo.d	Wed Oct 16 00:58:47 2013	(r256570)
+++ head/cddl/lib/libdtrace/psinfo.d	Wed Oct 16 01:39:26 2013	(r256571)
@@ -57,7 +57,8 @@ translator psinfo_t < struct proc *T > {
 	pr_gid = T->p_ucred->cr_rgid;
 	pr_egid = T->p_ucred->cr_groups[0];
 	pr_addr = 0;
-	pr_psargs = stringof(T->p_args->ar_args);
+	pr_psargs = (T->p_args->ar_args == 0) ? "" :
+	    memstr(T->p_args->ar_args, ' ', T->p_args->ar_length);
 	pr_arglen = T->p_args->ar_length;
 	pr_jailid = T->p_ucred->cr_prison->pr_id;
 };

Modified: head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c	Wed Oct 16 00:58:47 2013	(r256570)
+++ head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c	Wed Oct 16 01:39:26 2013	(r256571)
@@ -185,6 +185,9 @@ hrtime_t	dtrace_deadman_interval = NANOS
 hrtime_t	dtrace_deadman_timeout = (hrtime_t)10 * NANOSEC;
 hrtime_t	dtrace_deadman_user = (hrtime_t)30 * NANOSEC;
 hrtime_t	dtrace_unregister_defunct_reap = (hrtime_t)60 * NANOSEC;
+#if !defined(sun)
+int		dtrace_memstr_max = 4096;
+#endif
 
 /*
  * DTrace External Variables
@@ -4920,6 +4923,45 @@ inetout:	regs[rd] = (uintptr_t)end + 1;
 		break;
 	}
 
+#if !defined(sun)
+	case DIF_SUBR_MEMSTR: {
+		char *str = (char *)mstate->dtms_scratch_ptr;
+		uintptr_t mem = tupregs[0].dttk_value;
+		char c = tupregs[1].dttk_value;
+		size_t size = tupregs[2].dttk_value;
+		uint8_t n;
+		int i;
+
+		regs[rd] = 0;
+
+		if (size == 0)
+			break;
+
+		if (!dtrace_canload(mem, size - 1, mstate, vstate))
+			break;
+
+		if (!DTRACE_INSCRATCH(mstate, size)) {
+			DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
+			break;
+		}
+
+		if (dtrace_memstr_max != 0 && size > dtrace_memstr_max) {
+			*flags |= CPU_DTRACE_ILLOP;
+			break;
+		}
+
+		for (i = 0; i < size - 1; i++) {
+			n = dtrace_load8(mem++);
+			str[i] = (n == 0) ? c : n;
+		}
+		str[size - 1] = 0;
+
+		regs[rd] = (uintptr_t)str;
+		mstate->dtms_scratch_ptr += size;
+		break;
+	}
+#endif
+
 	case DIF_SUBR_TYPEREF: {
 		uintptr_t size = 4 * sizeof(uintptr_t);
 		uintptr_t *typeref = (uintptr_t *) P2ROUNDUP(mstate->dtms_scratch_ptr, sizeof(uintptr_t));
@@ -9102,6 +9144,9 @@ dtrace_difo_validate_helper(dtrace_difo_
 			    subr == DIF_SUBR_NTOHL ||
 			    subr == DIF_SUBR_NTOHLL ||
 			    subr == DIF_SUBR_MEMREF ||
+#if !defined(sun)
+			    subr == DIF_SUBR_MEMSTR ||
+#endif
 			    subr == DIF_SUBR_TYPEREF)
 				break;
 

Modified: head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h	Wed Oct 16 00:58:47 2013	(r256570)
+++ head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h	Wed Oct 16 01:39:26 2013	(r256571)
@@ -311,8 +311,9 @@ typedef enum dtrace_probespec {
 #define	DIF_SUBR_SX_SHARED_HELD		48
 #define	DIF_SUBR_SX_EXCLUSIVE_HELD	49
 #define	DIF_SUBR_SX_ISEXCLUSIVE		50
+#define	DIF_SUBR_MEMSTR			51
 
-#define	DIF_SUBR_MAX			50	/* max subroutine value */
+#define	DIF_SUBR_MAX			51	/* max subroutine value */
 
 typedef uint32_t dif_instr_t;
 

Modified: head/sys/cddl/dev/dtrace/dtrace_sysctl.c
==============================================================================
--- head/sys/cddl/dev/dtrace/dtrace_sysctl.c	Wed Oct 16 00:58:47 2013	(r256570)
+++ head/sys/cddl/dev/dtrace/dtrace_sysctl.c	Wed Oct 16 01:39:26 2013	(r256571)
@@ -80,3 +80,5 @@ sysctl_dtrace_providers(SYSCTL_HANDLER_A
 SYSCTL_PROC(_debug_dtrace, OID_AUTO, providers, CTLTYPE_STRING | CTLFLAG_RD,
     0, 0, sysctl_dtrace_providers, "A", "");
 
+SYSCTL_INT(_debug_dtrace, OID_AUTO, memstr_max, CTLFLAG_RW, &dtrace_memstr_max,
+    0, "largest allowed argument to memstr(), 0 indicates no limit");


More information about the svn-src-all mailing list