mirror of
https://github.com/torvalds/linux
synced 2024-09-06 18:01:05 +00:00
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: Alexey Dobriyan <adobriyan@gmail.com> Cc: Christoph Hellwig <hch@lst.de> Cc: <linux-arch@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
7664732315
commit
f284ce7269
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue