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

PTRACE_POKEDATA consolidation

Identical implementations of PTRACE_POKEDATA go into generic_ptrace_pokedata()
function.

AFAICS, fix bug on xtensa where successful PTRACE_POKEDATA will nevertheless
return EPERM.
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 76647323
...@@ -315,9 +315,7 @@ do_sys_ptrace(long request, long pid, long addr, long data, ...@@ -315,9 +315,7 @@ do_sys_ptrace(long request, long pid, long addr, long data,
/* When I and D space are separate, this will have to be fixed. */ /* When I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA: case PTRACE_POKEDATA:
tmp = data; ret = generic_ptrace_pokedata(child, addr, data);
copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 1);
ret = (copied == sizeof(tmp)) ? 0 : -EIO;
break; break;
case PTRACE_POKEUSR: /* write the specified register */ case PTRACE_POKEUSR: /* write the specified register */
......
...@@ -677,12 +677,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -677,12 +677,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
*/ */
case PTRACE_POKETEXT: case PTRACE_POKETEXT:
case PTRACE_POKEDATA: case PTRACE_POKEDATA:
ret = access_process_vm(child, addr, &data, ret = generic_ptrace_pokedata(child, addr, data);
sizeof(unsigned long), 1);
if (ret == sizeof(unsigned long))
ret = 0;
else
ret = -EIO;
break; break;
case PTRACE_POKEUSR: case PTRACE_POKEUSR:
......
...@@ -551,12 +551,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -551,12 +551,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
*/ */
case PTRACE_POKETEXT: case PTRACE_POKETEXT:
case PTRACE_POKEDATA: case PTRACE_POKEDATA:
ret = access_process_vm(child, addr, &data, ret = generic_ptrace_pokedata(child, addr, data);
sizeof(unsigned long), 1);
if (ret == sizeof(unsigned long))
ret = 0;
else
ret = -EIO;
break; break;
case PTRACE_POKEUSR: case PTRACE_POKEUSR:
......
...@@ -176,11 +176,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -176,11 +176,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
/* Write the word in data at location addr */ /* Write the word in data at location addr */
case PTRACE_POKETEXT: case PTRACE_POKETEXT:
case PTRACE_POKEDATA: case PTRACE_POKEDATA:
ret = access_process_vm(child, addr, &data, sizeof(data), 1); ret = generic_ptrace_pokedata(child, addr, data);
if (ret == sizeof(data))
ret = 0;
else
ret = -EIO;
break; break;
case PTRACE_POKEUSR: case PTRACE_POKEUSR:
......
...@@ -103,12 +103,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -103,12 +103,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
/* Write the word at location address. */ /* Write the word at location address. */
case PTRACE_POKETEXT: case PTRACE_POKETEXT:
case PTRACE_POKEDATA: case PTRACE_POKEDATA:
ret = 0; ret = generic_ptrace_pokedata(child, addr, data);
if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
break;
ret = -EIO;
break; break;
/* Write the word at location address in the USER area. */ /* Write the word at location address in the USER area. */
......
...@@ -146,12 +146,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -146,12 +146,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
/* Write the word at location address. */ /* Write the word at location address. */
case PTRACE_POKETEXT: case PTRACE_POKETEXT:
case PTRACE_POKEDATA: case PTRACE_POKEDATA:
ret = 0; ret = generic_ptrace_pokedata(child, addr, data);
if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
break;
ret = -EIO;
break; break;
/* Write the word at location address in the USER area. */ /* Write the word at location address in the USER area. */
......
...@@ -168,9 +168,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -168,9 +168,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
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;
if (access_process_vm(child, addr, &data, sizeof(data), 1) != sizeof(data)) ret = generic_ptrace_pokedata(child, addr, data);
break;
ret = 0;
break; break;
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
......
...@@ -111,10 +111,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -111,10 +111,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
/* when I and D space are separate, this will have to be fixed. */ /* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA: case PTRACE_POKEDATA:
ret = 0; ret = generic_ptrace_pokedata(child, addr, data);
if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
break;
ret = -EIO;
break; break;
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
......
...@@ -387,10 +387,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -387,10 +387,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
/* when I and D space are separate, this will have to be fixed. */ /* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA: case PTRACE_POKEDATA:
ret = 0; ret = generic_ptrace_pokedata(child, addr, data);
if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
break;
ret = -EIO;
break; break;
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
......
...@@ -619,15 +619,9 @@ do_ptrace(long request, struct task_struct *child, long addr, long data) ...@@ -619,15 +619,9 @@ do_ptrace(long request, struct task_struct *child, long addr, long data)
*/ */
case PTRACE_POKETEXT: case PTRACE_POKETEXT:
case PTRACE_POKEDATA: case PTRACE_POKEDATA:
ret = access_process_vm(child, addr, &data, sizeof(data), 1); ret = generic_ptrace_pokedata(child, addr, data);
if (ret == sizeof(data)) { if (ret == 0 && request == PTRACE_POKETEXT)
ret = 0; invalidate_cache();
if (request == PTRACE_POKETEXT) {
invalidate_cache();
}
} else {
ret = -EIO;
}
break; break;
/* /*
......
...@@ -157,8 +157,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -157,8 +157,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
/* when I and D space are separate, this will have to be fixed. */ /* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA: case PTRACE_POKEDATA:
if (access_process_vm(child, addr, &data, sizeof(data), 1) != sizeof(data)) ret = generic_ptrace_pokedata(child, addr, data);
goto out_eio;
break; break;
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
......
...@@ -151,10 +151,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -151,10 +151,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
/* when I and D space are separate, this will have to be fixed. */ /* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA: case PTRACE_POKEDATA:
ret = 0; ret = generic_ptrace_pokedata(child, addr, data);
if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
break;
ret = -EIO;
break; break;
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
......
...@@ -305,11 +305,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -305,11 +305,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
/* when I and D space are separate, this will have to be fixed. */ /* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA: case PTRACE_POKEDATA:
ret = 0; ret = generic_ptrace_pokedata(child, addr, data);
if (access_process_vm(child, addr, &data, sizeof(data), 1)
== sizeof(data))
break;
ret = -EIO;
break; break;
case PTRACE_POKEUSR: { case PTRACE_POKEUSR: {
......
...@@ -413,11 +413,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -413,11 +413,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
/* If I and D space are separate, this will have to be fixed. */ /* If I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA: case PTRACE_POKEDATA:
ret = 0; ret = generic_ptrace_pokedata(child, addr, data);
if (access_process_vm(child, addr, &data, sizeof(data), 1)
== sizeof(data))
break;
ret = -EIO;
break; break;
/* write the word at location addr in the USER area */ /* write the word at location addr in the USER area */
......
...@@ -314,10 +314,7 @@ do_ptrace_normal(struct task_struct *child, long request, long addr, long data) ...@@ -314,10 +314,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;
/* write the word at location addr. */ /* write the word at location addr. */
copied = access_process_vm(child, addr, &data, sizeof(data),1); return generic_ptrace_pokedata(child, addr, data);
if (copied != sizeof(data))
return -EIO;
return 0;
case PTRACE_POKEUSR: case PTRACE_POKEUSR:
/* write the word at location addr in the USER area */ /* write the word at location addr in the USER area */
......
...@@ -126,10 +126,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -126,10 +126,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
/* when I and D space are separate, this will have to be fixed. */ /* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA: case PTRACE_POKEDATA:
ret = 0; ret = generic_ptrace_pokedata(child, addr, data);
if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
break;
ret = -EIO;
break; break;
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
......
...@@ -158,10 +158,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -158,10 +158,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
/* when I and D space are separate, this will have to be fixed. */ /* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA: case PTRACE_POKEDATA:
ret = 0; ret = generic_ptrace_pokedata(child, addr, data);
if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
break;
ret = -EIO;
break; break;
case PTRACE_POKEUSR: case PTRACE_POKEUSR:
......
...@@ -64,11 +64,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -64,11 +64,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
/* when I and D space are separate, this will have to be fixed. */ /* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA: case PTRACE_POKEDATA:
ret = -EIO; ret = generic_ptrace_pokedata(child, addr, data);
if (access_process_vm(child, addr, &data, sizeof(data),
1) != sizeof(data))
break;
ret = 0;
break; break;
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
......
...@@ -126,11 +126,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -126,11 +126,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA: case PTRACE_POKEDATA:
rval = 0; rval = generic_ptrace_pokedata(child, addr, data);
if (access_process_vm(child, addr, &data, sizeof(data), 1)
== sizeof(data))
break;
rval = -EIO;
goto out; goto out;
/* Read/write the word at location ADDR in the registers. */ /* Read/write the word at location ADDR in the registers. */
......
...@@ -359,10 +359,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -359,10 +359,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
/* when I and D space are separate, this will have to be fixed. */ /* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA: case PTRACE_POKEDATA:
ret = 0; ret = generic_ptrace_pokedata(child, addr, data);
if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
break;
ret = -EIO;
break; break;
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
......
...@@ -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)
case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA: case PTRACE_POKEDATA:
if (access_process_vm(child, addr, &data, sizeof(data), 1) ret = generic_ptrace_pokedata(child, addr, data);
== sizeof(data))
break;
ret = -EIO;
goto out; goto out;
case PTRACE_POKEUSR: case PTRACE_POKEUSR:
......
...@@ -111,6 +111,7 @@ static inline void ptrace_unlink(struct task_struct *child) ...@@ -111,6 +111,7 @@ static inline void ptrace_unlink(struct task_struct *child)
} }
int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data); int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data);
int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data);
#ifndef force_successful_syscall_return #ifndef force_successful_syscall_return
/* /*
......
...@@ -501,3 +501,11 @@ int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data) ...@@ -501,3 +501,11 @@ int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data)
return -EIO; return -EIO;
return put_user(tmp, (unsigned long __user *)data); return put_user(tmp, (unsigned long __user *)data);
} }
int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data)
{
int copied;
copied = access_process_vm(tsk, addr, &data, sizeof(data), 1);
return (copied == sizeof(data)) ? 0 : -EIO;
}
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