summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarkj <markj@FreeBSD.org>2014-08-04 15:36:22 +0000
committermarkj <markj@FreeBSD.org>2014-08-04 15:36:22 +0000
commit2fd28e23736da641dbe3990391f997fb55353b17 (patch)
treeeb6788ffbddddf0e243de1acbb43ecdc0a774121
parentbde3467611213433dffde86fe37fa1ba8c021b09 (diff)
downloadFreeBSD-src-2fd28e23736da641dbe3990391f997fb55353b17.zip
FreeBSD-src-2fd28e23736da641dbe3990391f997fb55353b17.tar.gz
MFC r256571:
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().
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c4
-rw-r--r--cddl/lib/libdtrace/psinfo.d3
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c45
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h1
-rw-r--r--sys/cddl/dev/dtrace/dtrace_sysctl.c3
5 files changed, 55 insertions, 1 deletions
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
index cf6f2e9..01cf804 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c
@@ -323,6 +323,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,
diff --git a/cddl/lib/libdtrace/psinfo.d b/cddl/lib/libdtrace/psinfo.d
index 068e72e..c2219f7 100644
--- a/cddl/lib/libdtrace/psinfo.d
+++ b/cddl/lib/libdtrace/psinfo.d
@@ -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;
};
diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
index 401ccd5..56bea28 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
@@ -184,6 +184,9 @@ hrtime_t dtrace_deadman_interval = NANOSEC;
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
@@ -5807,6 +5810,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));
@@ -10033,6 +10075,9 @@ dtrace_difo_validate_helper(dtrace_difo_t *dp)
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;
diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
index 831143f..ff8355e 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
@@ -311,6 +311,7 @@ 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_GETF 52
#define DIF_SUBR_JSON 53
#define DIF_SUBR_STRTOLL 54
diff --git a/sys/cddl/dev/dtrace/dtrace_sysctl.c b/sys/cddl/dev/dtrace/dtrace_sysctl.c
index 073de9f..a2a4d10 100644
--- a/sys/cddl/dev/dtrace/dtrace_sysctl.c
+++ b/sys/cddl/dev/dtrace/dtrace_sysctl.c
@@ -89,3 +89,6 @@ SYSCTL_LONG(_kern_dtrace, OID_AUTO, dof_maxsize, CTLFLAG_RW,
SYSCTL_LONG(_kern_dtrace, OID_AUTO, helper_actions_max, CTLFLAG_RW,
&dtrace_helper_actions_max, 0, "maximum number of allowed helper actions");
+
+SYSCTL_INT(_kern_dtrace, OID_AUTO, memstr_max, CTLFLAG_RW, &dtrace_memstr_max,
+ 0, "largest allowed argument to memstr(), 0 indicates no limit");
OpenPOWER on IntegriCloud