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,
/* When I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
tmp = data;
copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 1);
ret = (copied == sizeof(tmp)) ? 0 : -EIO;
ret = generic_ptrace_pokedata(child, addr, data);
break;
case PTRACE_POKEUSR: /* write the specified register */
......
......@@ -677,12 +677,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
*/
case PTRACE_POKETEXT:
case PTRACE_POKEDATA:
ret = access_process_vm(child, addr, &data,
sizeof(unsigned long), 1);
if (ret == sizeof(unsigned long))
ret = 0;
else
ret = -EIO;
ret = generic_ptrace_pokedata(child, addr, data);
break;
case PTRACE_POKEUSR:
......
......@@ -551,12 +551,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
*/
case PTRACE_POKETEXT:
case PTRACE_POKEDATA:
ret = access_process_vm(child, addr, &data,
sizeof(unsigned long), 1);
if (ret == sizeof(unsigned long))
ret = 0;
else
ret = -EIO;
ret = generic_ptrace_pokedata(child, addr, data);
break;
case PTRACE_POKEUSR:
......
......@@ -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 */
case PTRACE_POKETEXT:
case PTRACE_POKEDATA:
ret = access_process_vm(child, addr, &data, sizeof(data), 1);
if (ret == sizeof(data))
ret = 0;
else
ret = -EIO;
ret = generic_ptrace_pokedata(child, addr, data);
break;
case PTRACE_POKEUSR:
......
......@@ -103,12 +103,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
/* Write the word at location address. */
case PTRACE_POKETEXT:
case PTRACE_POKEDATA:
ret = 0;
if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
break;
ret = -EIO;
ret = generic_ptrace_pokedata(child, addr, data);
break;
/* 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)
/* Write the word at location address. */
case PTRACE_POKETEXT:
case PTRACE_POKEDATA:
ret = 0;
if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
break;
ret = -EIO;
ret = generic_ptrace_pokedata(child, addr, data);
break;
/* 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)
ret = -EIO;
if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0)
break;
if (access_process_vm(child, addr, &data, sizeof(data), 1) != sizeof(data))
break;
ret = 0;
ret = generic_ptrace_pokedata(child, addr, data);
break;
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)
/* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
ret = 0;
if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
break;
ret = -EIO;
ret = generic_ptrace_pokedata(child, addr, data);
break;
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)
/* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
ret = 0;
if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
break;
ret = -EIO;
ret = generic_ptrace_pokedata(child, addr, data);
break;
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)
*/
case PTRACE_POKETEXT:
case PTRACE_POKEDATA:
ret = access_process_vm(child, addr, &data, sizeof(data), 1);
if (ret == sizeof(data)) {
ret = 0;
if (request == PTRACE_POKETEXT) {
invalidate_cache();
}
} else {
ret = -EIO;
}
ret = generic_ptrace_pokedata(child, addr, data);
if (ret == 0 && request == PTRACE_POKETEXT)
invalidate_cache();
break;
/*
......
......@@ -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. */
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
if (access_process_vm(child, addr, &data, sizeof(data), 1) != sizeof(data))
goto out_eio;
ret = generic_ptrace_pokedata(child, addr, data);
break;
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)
/* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
ret = 0;
if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
break;
ret = -EIO;
ret = generic_ptrace_pokedata(child, addr, data);
break;
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)
/* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
ret = 0;
if (access_process_vm(child, addr, &data, sizeof(data), 1)
== sizeof(data))
break;
ret = -EIO;
ret = generic_ptrace_pokedata(child, addr, data);
break;
case PTRACE_POKEUSR: {
......
......@@ -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. */
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
ret = 0;
if (access_process_vm(child, addr, &data, sizeof(data), 1)
== sizeof(data))
break;
ret = -EIO;
ret = generic_ptrace_pokedata(child, addr, data);
break;
/* 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)
/* Remove high order bit from address (only for 31 bit). */
addr &= PSW_ADDR_INSN;
/* write the word at location addr. */
copied = access_process_vm(child, addr, &data, sizeof(data),1);
if (copied != sizeof(data))
return -EIO;
return 0;
return generic_ptrace_pokedata(child, addr, data);
case PTRACE_POKEUSR:
/* 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)
/* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
ret = 0;
if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
break;
ret = -EIO;
ret = generic_ptrace_pokedata(child, addr, data);
break;
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)
/* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
ret = 0;
if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
break;
ret = -EIO;
ret = generic_ptrace_pokedata(child, addr, data);
break;
case PTRACE_POKEUSR:
......
......@@ -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. */
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
ret = -EIO;
if (access_process_vm(child, addr, &data, sizeof(data),
1) != sizeof(data))
break;
ret = 0;
ret = generic_ptrace_pokedata(child, addr, data);
break;
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)
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
rval = 0;
if (access_process_vm(child, addr, &data, sizeof(data), 1)
== sizeof(data))
break;
rval = -EIO;
rval = generic_ptrace_pokedata(child, addr, data);
goto out;
/* 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)
/* when I and D space are separate, this will have to be fixed. */
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
ret = 0;
if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
break;
ret = -EIO;
ret = generic_ptrace_pokedata(child, addr, data);
break;
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)
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
if (access_process_vm(child, addr, &data, sizeof(data), 1)
== sizeof(data))
break;
ret = -EIO;
ret = generic_ptrace_pokedata(child, addr, data);
goto out;
case PTRACE_POKEUSR:
......
......@@ -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_pokedata(struct task_struct *tsk, long addr, long data);
#ifndef force_successful_syscall_return
/*
......
......@@ -501,3 +501,11 @@ int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data)
return -EIO;
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