Re: Incorrect order of last two arguments of ptrace for requests PPC_PTRACE_GETREGS, SETREGS, GETFPREGS, SETFPREGS

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 2006-10-25 at 16:23 +0530, supriya kannery wrote:
> In ptrace, when request is PPC_PTRACE_GETREGS, SETREGS, GETFPREGS and 
> SETFPREGS, order of the last two arguments is not correct.
> 
> General format of ptrace is ptrace (request, pid, addr, data).  For the 
> above mentioned request ids in ppc64, if we use ptrace like
> 
>  long reg[32];
>  ptrace (PPC_PTRACE_GETREGS, pid, 0, &reg[0]);
> 
> the return value is always -1.
> 
> If we exchange the last two arguments like,
> 
>  ptrace (PPC_PTRACE_GETREGS, pid, &reg[0], 0);
> 
> it works!
> 
> This is because PPC_PTRACE_GETREGS option for powerpc is implemented 
> such that general purpose
> registers of the child process get copied to the address variable 
> instead of data variable. Same is
> the case with other PPC request options PPC_PTRACE_SETREGS, GETFPREGS 
> and SETFPREGS.
> 
> Prepared a patch for this problem and tested with 2.6.18-rc6 kernel. 
> This patch can be applied directly to 2.6.19-rc3 kernel.

A more appropriate place to send this would be the linux-ppc development
list.

-- 
dwmw2
diff -Naurp linux-2.6.18-rc6/arch/powerpc/kernel/ptrace.c linux-2.6.18-rc6-mod/arch/powerpc/kernel/ptrace.c
--- linux-2.6.18-rc6/arch/powerpc/kernel/ptrace.c	2006-10-19 18:09:01.000000000 +0530
+++ linux-2.6.18-rc6-mod/arch/powerpc/kernel/ptrace.c	2006-10-19 18:11:37.000000000 +0530
@@ -406,7 +406,7 @@ long arch_ptrace(struct task_struct *chi
 	case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
 		int i;
 		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
-		unsigned long __user *tmp = (unsigned long __user *)addr;
+		unsigned long __user *tmp = (unsigned long __user *)data;
 
 		for (i = 0; i < 32; i++) {
 			ret = put_user(*reg, tmp);
@@ -421,7 +421,7 @@ long arch_ptrace(struct task_struct *chi
 	case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
 		int i;
 		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
-		unsigned long __user *tmp = (unsigned long __user *)addr;
+		unsigned long __user *tmp = (unsigned long __user *)data;
 
 		for (i = 0; i < 32; i++) {
 			ret = get_user(*reg, tmp);
@@ -436,7 +436,7 @@ long arch_ptrace(struct task_struct *chi
 	case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */
 		int i;
 		unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
-		unsigned long __user *tmp = (unsigned long __user *)addr;
+		unsigned long __user *tmp = (unsigned long __user *)data;
 
 		flush_fp_to_thread(child);
 
@@ -453,7 +453,7 @@ long arch_ptrace(struct task_struct *chi
 	case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
 		int i;
 		unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
-		unsigned long __user *tmp = (unsigned long __user *)addr;
+		unsigned long __user *tmp = (unsigned long __user *)data;
 
 		flush_fp_to_thread(child);
 
diff -Naurp linux-2.6.18-rc6/arch/powerpc/kernel/ptrace32.c linux-2.6.18-rc6-mod/arch/powerpc/kernel/ptrace32.c
--- linux-2.6.18-rc6/arch/powerpc/kernel/ptrace32.c	2006-10-19 18:09:01.000000000 +0530
+++ linux-2.6.18-rc6-mod/arch/powerpc/kernel/ptrace32.c	2006-10-19 18:11:41.000000000 +0530
@@ -345,7 +345,7 @@ long compat_sys_ptrace(int request, int 
 	case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
 		int i;
 		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
-		unsigned int __user *tmp = (unsigned int __user *)addr;
+		unsigned int __user *tmp = (unsigned int __user *)data;
 
 		for (i = 0; i < 32; i++) {
 			ret = put_user(*reg, tmp);
@@ -360,7 +360,7 @@ long compat_sys_ptrace(int request, int 
 	case PPC_PTRACE_SETREGS: { /* Set GPRs 0 - 31. */
 		int i;
 		unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
-		unsigned int __user *tmp = (unsigned int __user *)addr;
+		unsigned int __user *tmp = (unsigned int __user *)data;
 
 		for (i = 0; i < 32; i++) {
 			ret = get_user(*reg, tmp);
@@ -375,7 +375,7 @@ long compat_sys_ptrace(int request, int 
 	case PPC_PTRACE_GETFPREGS: { /* Get FPRs 0 - 31. */
 		int i;
 		unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
-		unsigned int __user *tmp = (unsigned int __user *)addr;
+		unsigned int __user *tmp = (unsigned int __user *)data;
 
 		flush_fp_to_thread(child);
 
@@ -392,7 +392,7 @@ long compat_sys_ptrace(int request, int 
 	case PPC_PTRACE_SETFPREGS: { /* Get FPRs 0 - 31. */
 		int i;
 		unsigned long *reg = &((unsigned long *)child->thread.fpr)[0];
-		unsigned int __user *tmp = (unsigned int __user *)addr;
+		unsigned int __user *tmp = (unsigned int __user *)data;
 
 		flush_fp_to_thread(child);
 

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux