aboutsummaryrefslogtreecommitdiff
path: root/sys/cddl/contrib/opensolaris/uts/common/dtrace
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2015-12-07 21:44:05 +0000
committerMark Johnston <markj@FreeBSD.org>2015-12-07 21:44:05 +0000
commit6e0f204c3f46e7b71b855f32920e8df767ea298b (patch)
tree8f09ddeaee99dc12f093b0d7b20524da12d14535 /sys/cddl/contrib/opensolaris/uts/common/dtrace
parent711fbd17ecb5c73100aeb4991e158efcd50b8e7b (diff)
downloadsrc-6e0f204c3f46e7b71b855f32920e8df767ea298b.tar.gz
src-6e0f204c3f46e7b71b855f32920e8df767ea298b.zip
Modify DTRACEHIOC_ADDDOF to copy the DOF section from the target process.
r281257 added support for lazyload mode by allowing dtrace(1) to register a DOF section on behalf of a traced process. This was implemented by having libdtrace copy the DOF section into a heap-allocated buffer and passing its address to the ioctl handler. However, DTrace uses the DOF section address as a lookup key in certain cases, so the ioctl handler should be given the target process' DOF section address instead. This change modifies the ADDDOF handler to copy the DOF section in from the target process, rather than from dtrace(1).
Notes
Notes: svn path=/head/; revision=291962
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/dtrace')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c83
1 files changed, 65 insertions, 18 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
index 4b356d7b1a45..076d3f298ff0 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
@@ -120,13 +120,17 @@
#include <sys/kdb.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
-#include <sys/sysctl.h>
#include <sys/lock.h>
#include <sys/mutex.h>
+#include <sys/ptrace.h>
#include <sys/rwlock.h>
#include <sys/sx.h>
+#include <sys/sysctl.h>
+
#include <sys/dtrace_bsd.h>
+
#include <netinet/in.h>
+
#include "dtrace_cddl.h"
#include "dtrace_debug.c"
#endif
@@ -13030,9 +13034,60 @@ dtrace_dof_copyin(uintptr_t uarg, int *errp)
return (dof);
}
-#ifndef illumos
+#ifdef __FreeBSD__
+static dof_hdr_t *
+dtrace_dof_copyin_proc(struct proc *p, uintptr_t uarg, int *errp)
+{
+ dof_hdr_t hdr, *dof;
+ struct thread *td;
+ size_t loadsz;
+
+ ASSERT(!MUTEX_HELD(&dtrace_lock));
+
+ td = curthread;
+
+ /*
+ * First, we're going to copyin() the sizeof (dof_hdr_t).
+ */
+ if (proc_readmem(td, p, uarg, &hdr, sizeof(hdr)) != sizeof(hdr)) {
+ dtrace_dof_error(NULL, "failed to copyin DOF header");
+ *errp = EFAULT;
+ return (NULL);
+ }
+
+ /*
+ * Now we'll allocate the entire DOF and copy it in -- provided
+ * that the length isn't outrageous.
+ */
+ if (hdr.dofh_loadsz >= dtrace_dof_maxsize) {
+ dtrace_dof_error(&hdr, "load size exceeds maximum");
+ *errp = E2BIG;
+ return (NULL);
+ }
+ loadsz = (size_t)hdr.dofh_loadsz;
+
+ if (loadsz < sizeof (hdr)) {
+ dtrace_dof_error(&hdr, "invalid load size");
+ *errp = EINVAL;
+ return (NULL);
+ }
+
+ dof = kmem_alloc(loadsz, KM_SLEEP);
+
+ if (proc_readmem(td, p, uarg, dof, loadsz) != loadsz ||
+ dof->dofh_loadsz != loadsz) {
+ kmem_free(dof, hdr.dofh_loadsz);
+ *errp = EFAULT;
+ return (NULL);
+ }
+
+ return (dof);
+}
+
static __inline uchar_t
-dtrace_dof_char(char c) {
+dtrace_dof_char(char c)
+{
+
switch (c) {
case '0':
case '1':
@@ -13063,7 +13118,7 @@ dtrace_dof_char(char c) {
/* Should not reach here. */
return (0);
}
-#endif
+#endif /* __FreeBSD__ */
static dof_hdr_t *
dtrace_dof_property(const char *name)
@@ -15967,31 +16022,23 @@ dtrace_helper_provider_validate(dof_hdr_t *dof, dof_sec_t *sec)
}
static int
+#ifdef __FreeBSD__
+dtrace_helper_slurp(dof_hdr_t *dof, dof_helper_t *dhp, struct proc *p)
+#else
dtrace_helper_slurp(dof_hdr_t *dof, dof_helper_t *dhp)
+#endif
{
dtrace_helpers_t *help;
dtrace_vstate_t *vstate;
dtrace_enabling_t *enab = NULL;
+#ifndef __FreeBSD__
proc_t *p = curproc;
+#endif
int i, gen, rv, nhelpers = 0, nprovs = 0, destroy = 1;
uintptr_t daddr = (uintptr_t)dof;
ASSERT(MUTEX_HELD(&dtrace_lock));
-#ifdef __FreeBSD__
- if (dhp->dofhp_pid != p->p_pid) {
- if ((p = pfind(dhp->dofhp_pid)) == NULL)
- return (-1);
- if (!P_SHOULDSTOP(p) ||
- (p->p_flag & P_TRACED) == 0 ||
- p->p_pptr->p_pid != curproc->p_pid) {
- PROC_UNLOCK(p);
- return (-1);
- }
- PROC_UNLOCK(p);
- }
-#endif
-
if ((help = p->p_dtrace_helpers) == NULL)
help = dtrace_helpers_create(p);