Commit 76647323 authored by Alexey Dobriyan's avatar Alexey Dobriyan Committed by Linus Torvalds

PTRACE_PEEKDATA consolidation

Identical implementations of PTRACE_PEEKDATA go into generic_ptrace_peekdata()
function.
Signed-off-by: default avatarAlexey Dobriyan <adobriyan@gmail.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: <linux-arch@vger.kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent bcdcd8e7
...@@ -657,7 +657,6 @@ static int ptrace_setcrunchregs(struct task_struct *tsk, void __user *ufp) ...@@ -657,7 +657,6 @@ static int ptrace_setcrunchregs(struct task_struct *tsk, void __user *ufp)
long arch_ptrace(struct task_struct *child, long request, long addr, long data) long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{ {
unsigned long tmp;
int ret; int ret;
switch (request) { switch (request) {
...@@ -666,12 +665,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -666,12 +665,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
*/ */
case PTRACE_PEEKTEXT: case PTRACE_PEEKTEXT:
case PTRACE_PEEKDATA: case PTRACE_PEEKDATA:
ret = access_process_vm(child, addr, &tmp, ret = generic_ptrace_peekdata(child, addr, data);
sizeof(unsigned long), 0);
if (ret == sizeof(unsigned long))
ret = put_user(tmp, (unsigned long __user *) data);
else
ret = -EIO;
break; break;
case PTRACE_PEEKUSR: case PTRACE_PEEKUSR:
......
...@@ -531,7 +531,6 @@ static int ptrace_setfpregs(struct task_struct *tsk, void *ufp) ...@@ -531,7 +531,6 @@ static int ptrace_setfpregs(struct task_struct *tsk, void *ufp)
long arch_ptrace(struct task_struct *child, long request, long addr, long data) long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{ {
unsigned long tmp;
int ret; int ret;
switch (request) { switch (request) {
...@@ -540,12 +539,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -540,12 +539,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
*/ */
case PTRACE_PEEKTEXT: case PTRACE_PEEKTEXT:
case PTRACE_PEEKDATA: case PTRACE_PEEKDATA:
ret = access_process_vm(child, addr, &tmp, ret = generic_ptrace_peekdata(child, addr, data);
sizeof(unsigned long), 0);
if (ret == sizeof(unsigned long))
ret = put_user(tmp, (unsigned long *) data);
else
ret = -EIO;
break; break;
case PTRACE_PEEKUSR: case PTRACE_PEEKUSR:
......
...@@ -153,7 +153,6 @@ static int ptrace_setregs(struct task_struct *tsk, const void __user *uregs) ...@@ -153,7 +153,6 @@ static int ptrace_setregs(struct task_struct *tsk, const void __user *uregs)
long arch_ptrace(struct task_struct *child, long request, long addr, long data) long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{ {
unsigned long tmp;
int ret; int ret;
pr_debug("arch_ptrace(%ld, %d, %#lx, %#lx)\n", pr_debug("arch_ptrace(%ld, %d, %#lx, %#lx)\n",
...@@ -166,11 +165,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -166,11 +165,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
/* Read the word at location addr in the child process */ /* Read the word at location addr in the child process */
case PTRACE_PEEKTEXT: case PTRACE_PEEKTEXT:
case PTRACE_PEEKDATA: case PTRACE_PEEKDATA:
ret = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); ret = generic_ptrace_peekdata(child, addr, data);
if (ret == sizeof(tmp))
ret = put_user(tmp, (unsigned long __user *)data);
else
ret = -EIO;
break; break;
case PTRACE_PEEKUSR: case PTRACE_PEEKUSR:
......
...@@ -83,20 +83,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -83,20 +83,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
switch (request) { switch (request) {
/* Read word at location address. */ /* Read word at location address. */
case PTRACE_PEEKTEXT: case PTRACE_PEEKTEXT:
case PTRACE_PEEKDATA: { case PTRACE_PEEKDATA:
unsigned long tmp; ret = generic_ptrace_peekdata(child, addr, data);
int copied;
copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
ret = -EIO;
if (copied != sizeof(tmp))
break; break;
ret = put_user(tmp,datap);
break;
}
/* Read the word at location address in the USER area. */ /* Read the word at location address in the USER area. */
case PTRACE_PEEKUSR: { case PTRACE_PEEKUSR: {
unsigned long tmp; unsigned long tmp;
......
...@@ -112,21 +112,13 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -112,21 +112,13 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
switch (request) { switch (request) {
/* when I and D space are separate, these will need to be fixed. */ /* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: { case PTRACE_PEEKDATA:
int copied;
ret = -EIO; ret = -EIO;
if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0) if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0)
break; break;
ret = generic_ptrace_peekdata(child, addr, data);
copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
if (copied != sizeof(tmp))
break; break;
ret = put_user(tmp,(unsigned long *) data);
break;
}
/* read the word at location addr in the USER area. */ /* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: { case PTRACE_PEEKUSR: {
tmp = 0; tmp = 0;
......
...@@ -358,17 +358,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -358,17 +358,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
switch (request) { switch (request) {
/* when I and D space are separate, these will need to be fixed. */ /* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: { case PTRACE_PEEKDATA:
unsigned long tmp; ret = generic_ptrace_peekdata(child, addr, data);
int copied;
copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
ret = -EIO;
if (copied != sizeof(tmp))
break; break;
ret = put_user(tmp, datap);
break;
}
/* read the word at location addr in the USER area. */ /* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: { case PTRACE_PEEKUSR: {
......
...@@ -595,7 +595,6 @@ void ptrace_disable(struct task_struct *child) ...@@ -595,7 +595,6 @@ void ptrace_disable(struct task_struct *child)
static int static int
do_ptrace(long request, struct task_struct *child, long addr, long data) do_ptrace(long request, struct task_struct *child, long addr, long data)
{ {
unsigned long tmp;
int ret; int ret;
switch (request) { switch (request) {
...@@ -604,11 +603,7 @@ do_ptrace(long request, struct task_struct *child, long addr, long data) ...@@ -604,11 +603,7 @@ do_ptrace(long request, struct task_struct *child, long addr, long data)
*/ */
case PTRACE_PEEKTEXT: case PTRACE_PEEKTEXT:
case PTRACE_PEEKDATA: case PTRACE_PEEKDATA:
ret = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); ret = generic_ptrace_peekdata(child, addr, data);
if (ret == sizeof(tmp))
ret = put_user(tmp,(unsigned long __user *) data);
else
ret = -EIO;
break; break;
/* /*
......
...@@ -128,10 +128,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -128,10 +128,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
/* when I and D space are separate, these will need to be fixed. */ /* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: case PTRACE_PEEKDATA:
i = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); ret = generic_ptrace_peekdata(child, addr, data);
if (i != sizeof(tmp))
goto out_eio;
ret = put_user(tmp, (unsigned long *)data);
break; break;
/* read the word at location addr in the USER area. */ /* read the word at location addr in the USER area. */
......
...@@ -106,17 +106,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -106,17 +106,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
switch (request) { switch (request) {
/* when I and D space are separate, these will need to be fixed. */ /* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: { case PTRACE_PEEKDATA:
unsigned long tmp; ret = generic_ptrace_peekdata(child, addr, data);
int copied;
copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
ret = -EIO;
if (copied != sizeof(tmp))
break; break;
ret = put_user(tmp,(unsigned long *) data);
break;
}
/* read the word at location addr in the USER area. */ /* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: { case PTRACE_PEEKUSR: {
......
...@@ -174,17 +174,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -174,17 +174,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
switch (request) { switch (request) {
/* when I and D space are separate, these will need to be fixed. */ /* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: { case PTRACE_PEEKDATA:
unsigned long tmp; ret = generic_ptrace_peekdata(child, addr, data);
int copied;
copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
ret = -EIO;
if (copied != sizeof(tmp))
break; break;
ret = put_user(tmp,(unsigned long __user *) data);
break;
}
/* Read the word at location addr in the USER area. */ /* Read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: { case PTRACE_PEEKUSR: {
......
...@@ -87,10 +87,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -87,10 +87,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
switch (request) { switch (request) {
case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: { case PTRACE_PEEKDATA: {
int copied;
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
if (__is_compat_task(child)) { if (__is_compat_task(child)) {
int copied;
unsigned int tmp; unsigned int tmp;
addr &= 0xffffffffL; addr &= 0xffffffffL;
...@@ -105,15 +104,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -105,15 +104,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
} }
else else
#endif #endif
{ ret = generic_ptrace_peekdata(child, addr, data);
unsigned long tmp;
copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
ret = -EIO;
if (copied != sizeof(tmp))
goto out_tsk;
ret = put_user(tmp,(unsigned long *) data);
}
goto out_tsk; goto out_tsk;
} }
......
...@@ -379,17 +379,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -379,17 +379,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
switch (request) { switch (request) {
/* when I and D space are separate, these will need to be fixed. */ /* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: { case PTRACE_PEEKDATA:
unsigned long tmp; ret = generic_ptrace_peekdata(child, addr, data);
int copied;
copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
ret = -EIO;
if (copied != sizeof(tmp))
break; break;
ret = put_user(tmp,(unsigned long __user *) data);
break;
}
/* read the word at location addr in the USER area. */ /* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: { case PTRACE_PEEKUSR: {
......
...@@ -294,7 +294,6 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data) ...@@ -294,7 +294,6 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data)
static int static int
do_ptrace_normal(struct task_struct *child, long request, long addr, long data) do_ptrace_normal(struct task_struct *child, long request, long addr, long data)
{ {
unsigned long tmp;
ptrace_area parea; ptrace_area parea;
int copied, ret; int copied, ret;
...@@ -304,10 +303,7 @@ do_ptrace_normal(struct task_struct *child, long request, long addr, long data) ...@@ -304,10 +303,7 @@ do_ptrace_normal(struct task_struct *child, long request, long addr, long data)
/* Remove high order bit from address (only for 31 bit). */ /* Remove high order bit from address (only for 31 bit). */
addr &= PSW_ADDR_INSN; addr &= PSW_ADDR_INSN;
/* read word at location addr. */ /* read word at location addr. */
copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); return generic_ptrace_peekdata(child, addr, data);
if (copied != sizeof(tmp))
return -EIO;
return put_user(tmp, (unsigned long __force __user *) data);
case PTRACE_PEEKUSR: case PTRACE_PEEKUSR:
/* read the word at location addr in the USER area. */ /* read the word at location addr in the USER area. */
......
...@@ -91,17 +91,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -91,17 +91,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
switch (request) { switch (request) {
/* when I and D space are separate, these will need to be fixed. */ /* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: { case PTRACE_PEEKDATA:
unsigned long tmp; ret = generic_ptrace_peekdata(child, addr, data);
int copied;
copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
ret = -EIO;
if (copied != sizeof(tmp))
break;
ret = put_user(tmp,(unsigned long __user *) data);
break;
}
/* read the word at location addr in the USER area. */ /* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: { case PTRACE_PEEKUSR: {
......
...@@ -129,17 +129,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -129,17 +129,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
switch (request) { switch (request) {
/* when I and D space are separate, these will need to be fixed. */ /* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: { case PTRACE_PEEKDATA:
unsigned long tmp; ret = generic_ptrace_peekdata(child, addr, data);
int copied;
copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
ret = -EIO;
if (copied != sizeof(tmp))
break; break;
ret = put_user(tmp,(unsigned long *) data);
break;
}
/* read the word at location addr in the USER area. */ /* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: { case PTRACE_PEEKUSR: {
......
...@@ -52,17 +52,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -52,17 +52,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
switch (request) { switch (request) {
/* when I and D space are separate, these will need to be fixed. */ /* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: { case PTRACE_PEEKDATA:
unsigned long tmp; ret = generic_ptrace_peekdata(child, addr, data);
int copied;
ret = -EIO;
copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
if (copied != sizeof(tmp))
break; break;
ret = put_user(tmp, p);
break;
}
/* read the word at location addr in the USER area. */ /* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: case PTRACE_PEEKUSR:
......
...@@ -117,15 +117,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -117,15 +117,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
int rval; int rval;
switch (request) { switch (request) {
unsigned long val, copied; unsigned long val;
case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: case PTRACE_PEEKDATA:
copied = access_process_vm(child, addr, &val, sizeof(val), 0); rval = generic_ptrace_peekdata(child, addr, data);
rval = -EIO;
if (copied != sizeof(val))
break;
rval = put_user(val, (unsigned long *)data);
goto out; goto out;
case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKETEXT: /* write the word at location addr. */
......
...@@ -313,17 +313,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -313,17 +313,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
switch (request) { switch (request) {
/* when I and D space are separate, these will need to be fixed. */ /* when I and D space are separate, these will need to be fixed. */
case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: { case PTRACE_PEEKDATA:
unsigned long tmp; ret = generic_ptrace_peekdata(child, addr, data);
int copied;
copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
ret = -EIO;
if (copied != sizeof(tmp))
break; break;
ret = put_user(tmp,(unsigned long __user *) data);
break;
}
/* read the word at location addr in the USER area. */ /* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: { case PTRACE_PEEKUSR: {
......
...@@ -50,18 +50,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -50,18 +50,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
switch (request) { switch (request) {
case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: case PTRACE_PEEKDATA:
{ ret = generic_ptrace_peekdata(child, addr, data);
unsigned long tmp;
int copied;
copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
ret = -EIO;
if (copied != sizeof(tmp))
break;
ret = put_user(tmp,(unsigned long *) data);
goto out; goto out;
}
/* Read the word at location addr in the USER area. */ /* Read the word at location addr in the USER area. */
......
...@@ -110,6 +110,7 @@ static inline void ptrace_unlink(struct task_struct *child) ...@@ -110,6 +110,7 @@ static inline void ptrace_unlink(struct task_struct *child)
__ptrace_unlink(child); __ptrace_unlink(child);
} }
int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data);
#ifndef force_successful_syscall_return #ifndef force_successful_syscall_return
/* /*
......
...@@ -490,3 +490,14 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data) ...@@ -490,3 +490,14 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
return ret; return ret;
} }
#endif /* __ARCH_SYS_PTRACE */ #endif /* __ARCH_SYS_PTRACE */
int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data)
{
unsigned long tmp;
int copied;
copied = access_process_vm(tsk, addr, &tmp, sizeof(tmp), 0);
if (copied != sizeof(tmp))
return -EIO;
return put_user(tmp, (unsigned long __user *)data);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment