Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F106073705
D4245.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
D4245.diff
View Options
Index: head/share/man/man9/Makefile
===================================================================
--- head/share/man/man9/Makefile
+++ head/share/man/man9/Makefile
@@ -239,6 +239,7 @@
printf.9 \
prison_check.9 \
priv.9 \
+ proc_rwmem.9 \
pseudofs.9 \
psignal.9 \
random.9 \
@@ -1340,6 +1341,8 @@
printf.9 uprintf.9
MLINKS+=priv.9 priv_check.9 \
priv.9 priv_check_cred.9
+MLINKS+=proc_rwmem.9 proc_readmem.9 \
+ proc_rwmem.9 proc_writemem.9
MLINKS+=psignal.9 gsignal.9 \
psignal.9 pgsignal.9 \
psignal.9 tdsignal.9
Index: head/sys/arm/arm/machdep.c
===================================================================
--- head/sys/arm/arm/machdep.c
+++ head/sys/arm/arm/machdep.c
@@ -598,41 +598,21 @@
static int
-ptrace_read_int(struct thread *td, vm_offset_t addr, u_int32_t *v)
+ptrace_read_int(struct thread *td, vm_offset_t addr, uint32_t *v)
{
- struct iovec iov;
- struct uio uio;
- PROC_LOCK_ASSERT(td->td_proc, MA_NOTOWNED);
- iov.iov_base = (caddr_t) v;
- iov.iov_len = sizeof(u_int32_t);
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_offset = (off_t)addr;
- uio.uio_resid = sizeof(u_int32_t);
- uio.uio_segflg = UIO_SYSSPACE;
- uio.uio_rw = UIO_READ;
- uio.uio_td = td;
- return proc_rwmem(td->td_proc, &uio);
+ if (proc_readmem(td, td->td_proc, addr, v, sizeof(*v)) != sizeof(*v))
+ return (ENOMEM);
+ return (0);
}
static int
-ptrace_write_int(struct thread *td, vm_offset_t addr, u_int32_t v)
+ptrace_write_int(struct thread *td, vm_offset_t addr, uint32_t v)
{
- struct iovec iov;
- struct uio uio;
- PROC_LOCK_ASSERT(td->td_proc, MA_NOTOWNED);
- iov.iov_base = (caddr_t) &v;
- iov.iov_len = sizeof(u_int32_t);
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_offset = (off_t)addr;
- uio.uio_resid = sizeof(u_int32_t);
- uio.uio_segflg = UIO_SYSSPACE;
- uio.uio_rw = UIO_WRITE;
- uio.uio_td = td;
- return proc_rwmem(td->td_proc, &uio);
+ if (proc_writemem(td, td->td_proc, addr, &v, sizeof(v)) != sizeof(v))
+ return (ENOMEM);
+ return (0);
}
static u_int
Index: head/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c
===================================================================
--- head/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c
+++ head/sys/cddl/contrib/opensolaris/uts/intel/dtrace/fasttrap_isa.c
@@ -60,43 +60,31 @@
#include <sys/ptrace.h>
static int
-proc_ops(int op, proc_t *p, void *kaddr, off_t uaddr, size_t len)
+uread(proc_t *p, void *kaddr, size_t len, uintptr_t uaddr)
{
- struct iovec iov;
- struct uio uio;
+ ssize_t n;
- iov.iov_base = kaddr;
- iov.iov_len = len;
- uio.uio_offset = uaddr;
- uio.uio_iov = &iov;
- uio.uio_resid = len;
- uio.uio_iovcnt = 1;
- uio.uio_segflg = UIO_SYSSPACE;
- uio.uio_td = curthread;
- uio.uio_rw = op;
PHOLD(p);
- if (proc_rwmem(p, &uio) != 0) {
- PRELE(p);
- return (-1);
- }
+ n = proc_readmem(curthread, p, uaddr, kaddr, len);
PRELE(p);
-
+ if (n != len)
+ return (ENOMEM);
return (0);
}
static int
-uread(proc_t *p, void *kaddr, size_t len, uintptr_t uaddr)
-{
-
- return (proc_ops(UIO_READ, p, kaddr, uaddr, len));
-}
-
-static int
uwrite(proc_t *p, void *kaddr, size_t len, uintptr_t uaddr)
{
+ ssize_t n;
- return (proc_ops(UIO_WRITE, p, kaddr, uaddr, len));
+ PHOLD(p);
+ n = proc_writemem(curthread, p, uaddr, kaddr, len);
+ PRELE(p);
+ if (n != len)
+ return (ENOMEM);
+ return (0);
}
+
#endif /* illumos */
#ifdef __i386__
#define r_rax r_eax
Index: head/sys/cddl/contrib/opensolaris/uts/powerpc/dtrace/fasttrap_isa.c
===================================================================
--- head/sys/cddl/contrib/opensolaris/uts/powerpc/dtrace/fasttrap_isa.c
+++ head/sys/cddl/contrib/opensolaris/uts/powerpc/dtrace/fasttrap_isa.c
@@ -43,44 +43,30 @@
#define OP_RA(x) (((x) & 0x001F0000) >> 16)
#define OP_RB(x) (((x) & 0x0000F100) >> 11)
-
static int
-proc_ops(int op, proc_t *p, void *kaddr, off_t uaddr, size_t len)
+uread(proc_t *p, void *kaddr, size_t len, uintptr_t uaddr)
{
- struct iovec iov;
- struct uio uio;
+ ssize_t n;
- iov.iov_base = kaddr;
- iov.iov_len = len;
- uio.uio_offset = uaddr;
- uio.uio_iov = &iov;
- uio.uio_resid = len;
- uio.uio_iovcnt = 1;
- uio.uio_segflg = UIO_SYSSPACE;
- uio.uio_td = curthread;
- uio.uio_rw = op;
PHOLD(p);
- if (proc_rwmem(p, &uio) != 0) {
- PRELE(p);
- return (-1);
- }
+ n = proc_readmem(curthread, p, uaddr, kaddr, len);
PRELE(p);
-
+ if (n <= 0 || n < len)
+ return (ENOMEM);
return (0);
}
static int
-uread(proc_t *p, void *kaddr, size_t len, uintptr_t uaddr)
-{
-
- return (proc_ops(UIO_READ, p, kaddr, uaddr, len));
-}
-
-static int
uwrite(proc_t *p, void *kaddr, size_t len, uintptr_t uaddr)
{
+ ssize_t n;
- return (proc_ops(UIO_WRITE, p, kaddr, uaddr, len));
+ PHOLD(p);
+ n = proc_writemem(curthread, p, uaddr, kaddr, len);
+ PRELE(p);
+ if (n <= 0 || n < len)
+ return (ENOMEM);
+ return (0);
}
int
Index: head/sys/kern/kern_proc.c
===================================================================
--- head/sys/kern/kern_proc.c
+++ head/sys/kern/kern_proc.c
@@ -1526,50 +1526,20 @@
}
static int
-proc_read_mem(struct thread *td, struct proc *p, vm_offset_t offset, void* buf,
- size_t len)
-{
- struct iovec iov;
- struct uio uio;
-
- iov.iov_base = (caddr_t)buf;
- iov.iov_len = len;
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_offset = offset;
- uio.uio_resid = (ssize_t)len;
- uio.uio_segflg = UIO_SYSSPACE;
- uio.uio_rw = UIO_READ;
- uio.uio_td = td;
-
- return (proc_rwmem(p, &uio));
-}
-
-static int
proc_read_string(struct thread *td, struct proc *p, const char *sptr, char *buf,
size_t len)
{
- size_t i;
- int error;
+ ssize_t n;
- error = proc_read_mem(td, p, (vm_offset_t)sptr, buf, len);
/*
- * Reading the chunk may validly return EFAULT if the string is shorter
- * than the chunk and is aligned at the end of the page, assuming the
- * next page is not mapped. So if EFAULT is returned do a fallback to
- * one byte read loop.
+ * This may return a short read if the string is shorter than the chunk
+ * and is aligned at the end of the page, and the following page is not
+ * mapped.
*/
- if (error == EFAULT) {
- for (i = 0; i < len; i++, buf++, sptr++) {
- error = proc_read_mem(td, p, (vm_offset_t)sptr, buf, 1);
- if (error != 0)
- return (error);
- if (*buf == '\0')
- break;
- }
- error = 0;
- }
- return (error);
+ n = proc_readmem(td, p, (vm_offset_t)sptr, buf, len);
+ if (n <= 0)
+ return (ENOMEM);
+ return (0);
}
#define PROC_AUXV_MAX 256 /* Safety limit on auxv size. */
@@ -1593,10 +1563,10 @@
size_t vsize, size;
int i, error;
- error = proc_read_mem(td, p, (vm_offset_t)(p->p_sysent->sv_psstrings),
- &pss, sizeof(pss));
- if (error != 0)
- return (error);
+ error = 0;
+ if (proc_readmem(td, p, (vm_offset_t)p->p_sysent->sv_psstrings, &pss,
+ sizeof(pss)) != sizeof(pss))
+ return (ENOMEM);
switch (type) {
case PROC_ARG:
vptr = (vm_offset_t)PTRIN(pss.ps_argvstr);
@@ -1618,9 +1588,9 @@
if (vptr % 4 != 0)
return (ENOEXEC);
for (ptr = vptr, i = 0; i < PROC_AUXV_MAX; i++) {
- error = proc_read_mem(td, p, ptr, &aux, sizeof(aux));
- if (error != 0)
- return (error);
+ if (proc_readmem(td, p, ptr, &aux, sizeof(aux)) !=
+ sizeof(aux))
+ return (ENOMEM);
if (aux.a_type == AT_NULL)
break;
ptr += sizeof(aux);
@@ -1635,9 +1605,10 @@
return (EINVAL);
}
proc_vector32 = malloc(size, M_TEMP, M_WAITOK);
- error = proc_read_mem(td, p, vptr, proc_vector32, size);
- if (error != 0)
+ if (proc_readmem(td, p, vptr, proc_vector32, size) != size) {
+ error = ENOMEM;
goto done;
+ }
if (type == PROC_AUX) {
*proc_vectorp = (char **)proc_vector32;
*vsizep = vsize;
@@ -1663,16 +1634,15 @@
vm_offset_t vptr, ptr;
char **proc_vector;
size_t vsize, size;
- int error, i;
+ int i;
#ifdef COMPAT_FREEBSD32
if (SV_PROC_FLAG(p, SV_ILP32) != 0)
return (get_proc_vector32(td, p, proc_vectorp, vsizep, type));
#endif
- error = proc_read_mem(td, p, (vm_offset_t)(p->p_sysent->sv_psstrings),
- &pss, sizeof(pss));
- if (error != 0)
- return (error);
+ if (proc_readmem(td, p, (vm_offset_t)p->p_sysent->sv_psstrings, &pss,
+ sizeof(pss)) != sizeof(pss))
+ return (ENOMEM);
switch (type) {
case PROC_ARG:
vptr = (vm_offset_t)pss.ps_argvstr;
@@ -1709,9 +1679,9 @@
* to the allocated proc_vector.
*/
for (ptr = vptr, i = 0; i < PROC_AUXV_MAX; i++) {
- error = proc_read_mem(td, p, ptr, &aux, sizeof(aux));
- if (error != 0)
- return (error);
+ if (proc_readmem(td, p, ptr, &aux, sizeof(aux)) !=
+ sizeof(aux))
+ return (ENOMEM);
if (aux.a_type == AT_NULL)
break;
ptr += sizeof(aux);
@@ -1732,12 +1702,9 @@
return (EINVAL); /* In case we are built without INVARIANTS. */
}
proc_vector = malloc(size, M_TEMP, M_WAITOK);
- if (proc_vector == NULL)
- return (ENOMEM);
- error = proc_read_mem(td, p, vptr, proc_vector, size);
- if (error != 0) {
+ if (proc_readmem(td, p, vptr, proc_vector, size) != size) {
free(proc_vector, M_TEMP);
- return (error);
+ return (ENOMEM);
}
*proc_vectorp = proc_vector;
*vsizep = vsize;
Index: head/sys/kern/sys_process.c
===================================================================
--- head/sys/kern/sys_process.c
+++ head/sys/kern/sys_process.c
@@ -252,6 +252,7 @@
* from exiting out from under us until this operation completes.
*/
PROC_ASSERT_HELD(p);
+ PROC_LOCK_ASSERT(p, MA_NOTOWNED);
/*
* The map we want...
@@ -327,6 +328,49 @@
return (error);
}
+static ssize_t
+proc_iop(struct thread *td, struct proc *p, vm_offset_t va, void *buf,
+ size_t len, enum uio_rw rw)
+{
+ struct iovec iov;
+ struct uio uio;
+ ssize_t slen;
+ int error;
+
+ MPASS(len < SSIZE_MAX);
+ slen = (ssize_t)len;
+
+ iov.iov_base = (caddr_t)buf;
+ iov.iov_len = len;
+ uio.uio_iov = &iov;
+ uio.uio_iovcnt = 1;
+ uio.uio_offset = va;
+ uio.uio_resid = slen;
+ uio.uio_segflg = UIO_SYSSPACE;
+ uio.uio_rw = rw;
+ uio.uio_td = td;
+ error = proc_rwmem(p, &uio);
+ if (uio.uio_resid == slen)
+ return (-1);
+ return (slen - uio.uio_resid);
+}
+
+ssize_t
+proc_readmem(struct thread *td, struct proc *p, vm_offset_t va, void *buf,
+ size_t len)
+{
+
+ return (proc_iop(td, p, va, buf, len, UIO_READ));
+}
+
+ssize_t
+proc_writemem(struct thread *td, struct proc *p, vm_offset_t va, void *buf,
+ size_t len)
+{
+
+ return (proc_iop(td, p, va, buf, len, UIO_WRITE));
+}
+
static int
ptrace_vm_entry(struct thread *td, struct proc *p, struct ptrace_vm_entry *pve)
{
@@ -644,7 +688,7 @@
struct thread *td2 = NULL, *td3;
struct ptrace_io_desc *piod = NULL;
struct ptrace_lwpinfo *pl;
- int error, write, tmp, num;
+ int error, num, tmp;
int proctree_locked = 0;
lwpid_t tid = 0, *buf;
#ifdef COMPAT_FREEBSD32
@@ -674,7 +718,6 @@
break;
}
- write = 0;
if (req == PT_TRACE_ME) {
p = td->td_proc;
PROC_LOCK(p);
@@ -1033,46 +1076,28 @@
case PT_WRITE_I:
case PT_WRITE_D:
td2->td_dbgflags |= TDB_USERWR;
- write = 1;
- /* FALLTHROUGH */
+ PROC_UNLOCK(p);
+ error = 0;
+ if (proc_writemem(td, p, (off_t)(uintptr_t)addr, &data,
+ sizeof(int)) != sizeof(int))
+ error = ENOMEM;
+ else
+ CTR3(KTR_PTRACE, "PT_WRITE: pid %d: %p <= %#x",
+ p->p_pid, addr, data);
+ PROC_LOCK(p);
+ break;
+
case PT_READ_I:
case PT_READ_D:
PROC_UNLOCK(p);
- tmp = 0;
- /* write = 0 set above */
- iov.iov_base = write ? (caddr_t)&data : (caddr_t)&tmp;
- iov.iov_len = sizeof(int);
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_offset = (off_t)(uintptr_t)addr;
- uio.uio_resid = sizeof(int);
- uio.uio_segflg = UIO_SYSSPACE; /* i.e.: the uap */
- uio.uio_rw = write ? UIO_WRITE : UIO_READ;
- uio.uio_td = td;
- error = proc_rwmem(p, &uio);
- if (uio.uio_resid != 0) {
- /*
- * XXX proc_rwmem() doesn't currently return ENOSPC,
- * so I think write() can bogusly return 0.
- * XXX what happens for short writes? We don't want
- * to write partial data.
- * XXX proc_rwmem() returns EPERM for other invalid
- * addresses. Convert this to EINVAL. Does this
- * clobber returns of EPERM for other reasons?
- */
- if (error == 0 || error == ENOSPC || error == EPERM)
- error = EINVAL; /* EOF */
- }
- if (!write)
- td->td_retval[0] = tmp;
- if (error == 0) {
- if (write)
- CTR3(KTR_PTRACE, "PT_WRITE: pid %d: %p <= %#x",
- p->p_pid, addr, data);
- else
- CTR3(KTR_PTRACE, "PT_READ: pid %d: %p >= %#x",
- p->p_pid, addr, tmp);
- }
+ error = tmp = 0;
+ if (proc_readmem(td, p, (off_t)(uintptr_t)addr, &tmp,
+ sizeof(int)) != sizeof(int))
+ error = ENOMEM;
+ else
+ CTR3(KTR_PTRACE, "PT_READ: pid %d: %p >= %#x",
+ p->p_pid, addr, tmp);
+ td->td_retval[0] = tmp;
PROC_LOCK(p);
break;
Index: head/sys/mips/mips/pm_machdep.c
===================================================================
--- head/sys/mips/mips/pm_machdep.c
+++ head/sys/mips/mips/pm_machdep.c
@@ -214,39 +214,19 @@
static int
ptrace_read_int(struct thread *td, off_t addr, int *v)
{
- struct iovec iov;
- struct uio uio;
- PROC_LOCK_ASSERT(td->td_proc, MA_NOTOWNED);
- iov.iov_base = (caddr_t) v;
- iov.iov_len = sizeof(int);
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_offset = (off_t)addr;
- uio.uio_resid = sizeof(int);
- uio.uio_segflg = UIO_SYSSPACE;
- uio.uio_rw = UIO_READ;
- uio.uio_td = td;
- return proc_rwmem(td->td_proc, &uio);
+ if (proc_readmem(td, td->td_proc, addr, v, sizeof(*v)) != sizeof(*v))
+ return (ENOMEM);
+ return (0);
}
static int
ptrace_write_int(struct thread *td, off_t addr, int v)
{
- struct iovec iov;
- struct uio uio;
- PROC_LOCK_ASSERT(td->td_proc, MA_NOTOWNED);
- iov.iov_base = (caddr_t) &v;
- iov.iov_len = sizeof(int);
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_offset = (off_t)addr;
- uio.uio_resid = sizeof(int);
- uio.uio_segflg = UIO_SYSSPACE;
- uio.uio_rw = UIO_WRITE;
- uio.uio_td = td;
- return proc_rwmem(td->td_proc, &uio);
+ if (proc_writemem(td, td->td_proc, addr, &v, sizeof(v)) != sizeof(v))
+ return (ENOMEM);
+ return (0);
}
int
Index: head/sys/sys/ptrace.h
===================================================================
--- head/sys/sys/ptrace.h
+++ head/sys/sys/ptrace.h
@@ -166,6 +166,10 @@
int proc_write_dbregs(struct thread *_td, struct dbreg *_dbreg);
int proc_sstep(struct thread *_td);
int proc_rwmem(struct proc *_p, struct uio *_uio);
+ssize_t proc_readmem(struct thread *_td, struct proc *_p, vm_offset_t _va,
+ void *_buf, size_t _len);
+ssize_t proc_writemem(struct thread *_td, struct proc *_p, vm_offset_t _va,
+ void *_buf, size_t _len);
#ifdef COMPAT_FREEBSD32
struct reg32;
struct fpreg32;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Dec 25, 11:06 PM (11 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15599320
Default Alt Text
D4245.diff (14 KB)
Attached To
Mode
D4245: add proc_readmem() and proc_writemem() interfaces
Attached
Detach File
Event Timeline
Log In to Comment