Several places in sys_ptrace() don't decrease the page count where they should. This will cause memory leak later when the traced task is freed. This patch is initially brought up by Sony people and modified by Drow and me. Jun
diff -Nru linux/arch/mips/kernel/ptrace.c.orig linux/arch/mips/kernel/ptrace.c --- linux/arch/mips/kernel/ptrace.c.orig Thu Nov 7 14:05:33 2002 +++ linux/arch/mips/kernel/ptrace.c Wed Mar 12 17:28:34 2003 @@ -72,7 +72,7 @@ ret = -EPERM; if (pid == 1) /* you may not mess with init */ - goto out; + goto out_tsk; if (request == PTRACE_ATTACH) { ret = ptrace_attach(child); @@ -94,8 +94,7 @@ if (copied != sizeof(tmp)) break; ret = put_user(tmp,(unsigned long *) data); - - goto out; + break; } /* Read the word at location addr in the USER area. */ @@ -164,10 +163,10 @@ default: tmp = 0; ret = -EIO; - goto out; + goto out_tsk; } ret = put_user(tmp, (unsigned long *) data); - goto out; + break; } case PTRACE_POKETEXT: /* write the word at location addr. */ @@ -177,7 +176,7 @@ == sizeof(data)) break; ret = -EIO; - goto out; + break; case PTRACE_POKEUSR: { struct pt_regs *regs; @@ -277,7 +276,7 @@ default: ret = -EIO; - goto out; + break; } out_tsk: free_task_struct(child); diff -Nru linux/arch/mips64/kernel/ptrace.c.orig linux/arch/mips64/kernel/ptrace.c --- linux/arch/mips64/kernel/ptrace.c.orig Wed Jan 29 15:33:04 2003 +++ linux/arch/mips64/kernel/ptrace.c Wed Mar 12 17:34:33 2003 @@ -206,7 +206,7 @@ ret = -EIO; break; } - goto out; + break; } case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ case PTRACE_CONT: { /* restart after signal. */ @@ -293,7 +293,7 @@ ret = -EPERM; if (pid == 1) /* you may not mess with init */ - goto out; + goto out_tsk; if (request == PTRACE_ATTACH) { ret = ptrace_attach(child); @@ -427,7 +427,7 @@ ret = -EIO; break; } - goto out; + break; } case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ case PTRACE_CONT: { /* restart after signal. */
diff -Nru linux/arch/mips/kernel/ptrace.c.orig linux/arch/mips/kernel/ptrace.c --- linux/arch/mips/kernel/ptrace.c.orig Thu Dec 12 13:58:26 2002 +++ linux/arch/mips/kernel/ptrace.c Wed Mar 12 17:41:56 2003 @@ -73,7 +73,7 @@ ret = -EPERM; if (pid == 1) /* you may not mess with init */ - goto out; + goto out_tsk; if (request == PTRACE_ATTACH) { ret = ptrace_attach(child); @@ -95,8 +95,7 @@ if (copied != sizeof(tmp)) break; ret = put_user(tmp,(unsigned long *) data); - - goto out; + break; } /* Read the word at location addr in the USER area. */ @@ -165,10 +164,10 @@ default: tmp = 0; ret = -EIO; - goto out; + goto out_tsk; } ret = put_user(tmp, (unsigned long *) data); - goto out; + break; } case PTRACE_POKETEXT: /* write the word at location addr. */ @@ -178,7 +177,7 @@ == sizeof(data)) break; ret = -EIO; - goto out; + break; case PTRACE_POKEUSR: { struct pt_regs *regs; diff -Nru linux/arch/mips64/kernel/ptrace.c.orig linux/arch/mips64/kernel/ptrace.c --- linux/arch/mips64/kernel/ptrace.c.orig Thu Feb 13 11:37:35 2003 +++ linux/arch/mips64/kernel/ptrace.c Wed Mar 12 17:41:56 2003 @@ -206,7 +206,7 @@ ret = -EIO; break; } - goto out; + break; } case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ case PTRACE_CONT: { /* restart after signal. */ @@ -286,7 +286,7 @@ ret = -EPERM; if (pid == 1) /* you may not mess with init */ - goto out; + goto out_tsk; if (request == PTRACE_ATTACH) { ret = ptrace_attach(child); @@ -420,7 +420,7 @@ ret = -EIO; break; } - goto out; + break; } case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ case PTRACE_CONT: { /* restart after signal. */