summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c50
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c83
-rw-r--r--sys/cddl/dev/dtrace/dtrace_ioctl.c54
3 files changed, 107 insertions, 80 deletions
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c
index c61a710..5444477 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c
@@ -571,12 +571,6 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname)
prsyminfo_t sip;
dof_helper_t dh;
GElf_Half e_type;
-#ifdef __FreeBSD__
- dof_hdr_t hdr;
- size_t sz;
- uint64_t dofmax;
- void *dof;
-#endif
const char *mname;
const char *syms[] = { "___SUNW_dof", "__SUNW_dof" };
int i, fd = -1;
@@ -606,61 +600,25 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname)
continue;
}
-#ifdef __FreeBSD__
+ dh.dofhp_dof = sym.st_value;
dh.dofhp_addr = (e_type == ET_EXEC) ? 0 : pmp->pr_vaddr;
- if (Pread(P, &hdr, sizeof (hdr), sym.st_value) !=
- sizeof (hdr)) {
- dt_dprintf("read of DOF header failed\n");
- continue;
- }
-
- sz = sizeof(dofmax);
- if (sysctlbyname("kern.dtrace.dof_maxsize", &dofmax, &sz,
- NULL, 0) != 0) {
- dt_dprintf("failed to read dof_maxsize: %s\n",
- strerror(errno));
- continue;
- }
- if (dofmax < hdr.dofh_loadsz) {
- dt_dprintf("DOF load size exceeds maximum\n");
- continue;
- }
-
- if ((dof = malloc(hdr.dofh_loadsz)) == NULL)
- return (-1);
-
- if (Pread(P, dof, hdr.dofh_loadsz, sym.st_value) !=
- hdr.dofh_loadsz) {
- free(dof);
- dt_dprintf("read of DOF section failed\n");
- continue;
- }
-
- dh.dofhp_dof = (uintptr_t)dof;
- dh.dofhp_pid = proc_getpid(P);
dt_pid_objname(dh.dofhp_mod, sizeof (dh.dofhp_mod),
sip.prs_lmid, mname);
+#ifdef __FreeBSD__
+ dh.dofhp_pid = proc_getpid(P);
+
if (fd == -1 &&
(fd = open("/dev/dtrace/helper", O_RDWR, 0)) < 0) {
dt_dprintf("open of helper device failed: %s\n",
strerror(errno));
- free(dof);
return (-1); /* errno is set for us */
}
if (ioctl(fd, DTRACEHIOC_ADDDOF, &dh, sizeof (dh)) < 0)
dt_dprintf("DOF was rejected for %s\n", dh.dofhp_mod);
-
- free(dof);
#else
- dh.dofhp_dof = sym.st_value;
- dh.dofhp_addr = (e_type == ET_EXEC) ? 0 : pmp->pr_vaddr;
-
- dt_pid_objname(dh.dofhp_mod, sizeof (dh.dofhp_mod),
- sip.prs_lmid, mname);
-
if (fd == -1 &&
(fd = pr_open(P, "/dev/dtrace/helper", O_RDWR, 0)) < 0) {
dt_dprintf("pr_open of helper device failed: %s\n",
diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
index 4b356d7..076d3f2 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);
diff --git a/sys/cddl/dev/dtrace/dtrace_ioctl.c b/sys/cddl/dev/dtrace/dtrace_ioctl.c
index 524e937..666c077 100644
--- a/sys/cddl/dev/dtrace/dtrace_ioctl.c
+++ b/sys/cddl/dev/dtrace/dtrace_ioctl.c
@@ -32,25 +32,47 @@ static int
dtrace_ioctl_helper(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
struct thread *td)
{
- dof_helper_t *dhp = NULL;
- dof_hdr_t *dof = NULL;
+ struct proc *p;
+ dof_helper_t *dhp;
+ dof_hdr_t *dof;
int rval;
+ dhp = NULL;
+ dof = NULL;
+ rval = 0;
switch (cmd) {
case DTRACEHIOC_ADDDOF:
dhp = (dof_helper_t *)addr;
- /* XXX all because dofhp_dof is 64 bit */
- addr = (caddr_t)(vm_offset_t)dhp->dofhp_dof;
+ addr = (caddr_t)(uintptr_t)dhp->dofhp_dof;
/* FALLTHROUGH */
case DTRACEHIOC_ADD:
- dof = dtrace_dof_copyin((intptr_t)addr, &rval);
+ p = curproc;
+ if (p->p_pid == dhp->dofhp_pid) {
+ dof = dtrace_dof_copyin((uintptr_t)addr, &rval);
+ } else {
+ p = pfind(dhp->dofhp_pid);
+ if (p == NULL)
+ return (EINVAL);
+ if (!P_SHOULDSTOP(p) ||
+ (p->p_flag & P_TRACED|P_WEXIT) == 0 ||
+ p->p_pptr != curproc) {
+ PROC_UNLOCK(p);
+ return (EINVAL);
+ }
+ _PHOLD(p);
+ PROC_UNLOCK(p);
+ dof = dtrace_dof_copyin_proc(p, (uintptr_t)addr, &rval);
+ }
- if (dof == NULL)
- return (rval);
+ if (dof == NULL) {
+ if (p != curproc)
+ PRELE(p);
+ break;
+ }
mutex_enter(&dtrace_lock);
- if ((rval = dtrace_helper_slurp((dof_hdr_t *)dof, dhp)) != -1) {
- if (dhp) {
+ if ((rval = dtrace_helper_slurp(dof, dhp, p)) != -1) {
+ if (dhp != NULL) {
dhp->dofhp_gen = rval;
copyout(dhp, addr, sizeof(*dhp));
}
@@ -59,19 +81,19 @@ dtrace_ioctl_helper(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
rval = EINVAL;
}
mutex_exit(&dtrace_lock);
-
- return (rval);
+ if (p != curproc)
+ PRELE(p);
+ break;
case DTRACEHIOC_REMOVE:
mutex_enter(&dtrace_lock);
- rval = dtrace_helper_destroygen(NULL, (int)*addr);
+ rval = dtrace_helper_destroygen(NULL, *(int *)(uintptr_t)addr);
mutex_exit(&dtrace_lock);
-
- return (rval);
+ break;
default:
+ rval = ENOTTY;
break;
}
-
- return (ENOTTY);
+ return (rval);
}
/* ARGSUSED */
OpenPOWER on IntegriCloud