Commit acc70885 authored by Daniel Jacobowitz's avatar Daniel Jacobowitz

Factor out common ptrace code and PTRACE_SETOPTIONS

Support PTRACE_O_TRACESYSGOOD on all platforms
parent 1ab068b3
...@@ -383,7 +383,7 @@ sys_ptrace(long request, long pid, long addr, long data, ...@@ -383,7 +383,7 @@ sys_ptrace(long request, long pid, long addr, long data,
goto out; goto out;
default: default:
ret = -EIO; ret = ptrace_request(child, request, addr, data);
goto out; goto out;
} }
out: out:
...@@ -400,7 +400,8 @@ syscall_trace(void) ...@@ -400,7 +400,8 @@ syscall_trace(void)
return; return;
if (!(current->ptrace & PT_PTRACED)) if (!(current->ptrace & PT_PTRACED))
return; return;
current->exit_code = SIGTRAP; current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0);
current->state = TASK_STOPPED; current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD); notify_parent(current, SIGCHLD);
schedule(); schedule();
......
...@@ -629,16 +629,8 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat ...@@ -629,16 +629,8 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
ret = ptrace_setfpregs(child, (void *)data); ret = ptrace_setfpregs(child, (void *)data);
break; break;
case PTRACE_SETOPTIONS:
if (data & PTRACE_O_TRACESYSGOOD)
child->ptrace |= PT_TRACESYSGOOD;
else
child->ptrace &= ~PT_TRACESYSGOOD;
ret = 0;
break;
default: default:
ret = -EIO; ret = ptrace_request(child, request, addr, data);
break; break;
} }
......
...@@ -292,7 +292,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -292,7 +292,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
} }
default: default:
ret = -EIO; ret = ptrace_request(child, request, addr, data);
break; break;
} }
out_tsk: out_tsk:
...@@ -307,10 +307,8 @@ asmlinkage void syscall_trace(void) ...@@ -307,10 +307,8 @@ asmlinkage void syscall_trace(void)
if ((current->ptrace & (PT_PTRACED | PT_TRACESYS)) != if ((current->ptrace & (PT_PTRACED | PT_TRACESYS)) !=
(PT_PTRACED | PT_TRACESYS)) (PT_PTRACED | PT_TRACESYS))
return; return;
/* TODO: make a way to distinguish between a syscall stop and SIGTRAP current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
* delivery like in the i386 port ? ? 0x80 : 0);
*/
current->exit_code = SIGTRAP;
current->state = TASK_STOPPED; current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD); notify_parent(current, SIGCHLD);
schedule(); schedule();
......
...@@ -425,17 +425,8 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -425,17 +425,8 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
break; break;
} }
case PTRACE_SETOPTIONS: {
if (data & PTRACE_O_TRACESYSGOOD)
child->ptrace |= PT_TRACESYSGOOD;
else
child->ptrace &= ~PT_TRACESYSGOOD;
ret = 0;
break;
}
default: default:
ret = -EIO; ret = ptrace_request(child, request, addr, data);
break; break;
} }
out_tsk: out_tsk:
......
...@@ -3084,7 +3084,7 @@ sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data, ...@@ -3084,7 +3084,7 @@ sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data,
break; break;
default: default:
ret = -EIO; ret = ptrace_request(child, request, addr, data);
break; break;
} }
......
...@@ -1268,16 +1268,8 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data, ...@@ -1268,16 +1268,8 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
ret = ptrace_setregs(child, (struct pt_all_user_regs*) data); ret = ptrace_setregs(child, (struct pt_all_user_regs*) data);
goto out_tsk; goto out_tsk;
case PTRACE_SETOPTIONS:
if (data & PTRACE_O_TRACESYSGOOD)
child->ptrace |= PT_TRACESYSGOOD;
else
child->ptrace &= ~PT_TRACESYSGOOD;
ret = 0;
break;
default: default:
ret = -EIO; ret = ptrace_request(child, request, addr, data);
goto out_tsk; goto out_tsk;
} }
out_tsk: out_tsk:
......
...@@ -355,7 +355,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -355,7 +355,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
} }
default: default:
ret = -EIO; ret = ptrace_request(child, request, addr, data);
break; break;
} }
out_tsk: out_tsk:
...@@ -370,7 +370,8 @@ asmlinkage void syscall_trace(void) ...@@ -370,7 +370,8 @@ asmlinkage void syscall_trace(void)
if (!current->thread.work.delayed_trace && if (!current->thread.work.delayed_trace &&
!current->thread.work.syscall_trace) !current->thread.work.syscall_trace)
return; return;
current->exit_code = SIGTRAP; current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0);
current->state = TASK_STOPPED; current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD); notify_parent(current, SIGCHLD);
schedule(); schedule();
......
...@@ -304,16 +304,8 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -304,16 +304,8 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
res = ptrace_detach(child, data); res = ptrace_detach(child, data);
break; break;
case PTRACE_SETOPTIONS:
if (data & PTRACE_O_TRACESYSGOOD)
child->ptrace |= PT_TRACESYSGOOD;
else
child->ptrace &= ~PT_TRACESYSGOOD;
res = 0;
break;
default: default:
res = -EIO; res = ptrace_request(child, request, addr, data);
goto out; goto out;
} }
out_tsk: out_tsk:
......
...@@ -275,17 +275,8 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) ...@@ -275,17 +275,8 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
ret = ptrace_detach(child, data); ret = ptrace_detach(child, data);
break; break;
case PTRACE_SETOPTIONS: {
if (data & PTRACE_O_TRACESYSGOOD)
child->ptrace |= PT_TRACESYSGOOD;
else
child->ptrace &= ~PT_TRACESYSGOOD;
ret = 0;
break;
}
default: default:
ret = -EIO; ret = ptrace_request(child, request, addr, data);
break; break;
} }
...@@ -535,17 +526,8 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -535,17 +526,8 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = ptrace_detach(child, data); ret = ptrace_detach(child, data);
break; break;
case PTRACE_SETOPTIONS: {
if (data & PTRACE_O_TRACESYSGOOD)
child->ptrace |= PT_TRACESYSGOOD;
else
child->ptrace &= ~PT_TRACESYSGOOD;
ret = 0;
break;
}
default: default:
ret = -EIO; ret = ptrace_request(child, request, addr, data);
break; break;
} }
......
...@@ -244,7 +244,7 @@ long sys_ptrace(long request, pid_t pid, long addr, long data) ...@@ -244,7 +244,7 @@ long sys_ptrace(long request, pid_t pid, long addr, long data)
goto out_tsk; goto out_tsk;
default: default:
ret = -EIO; ret = ptrace_request(child, request, addr, data);
goto out_tsk; goto out_tsk;
} }
...@@ -269,7 +269,8 @@ void syscall_trace(void) ...@@ -269,7 +269,8 @@ void syscall_trace(void)
if ((current->ptrace & (PT_PTRACED|PT_TRACESYS)) != if ((current->ptrace & (PT_PTRACED|PT_TRACESYS)) !=
(PT_PTRACED|PT_TRACESYS)) (PT_PTRACED|PT_TRACESYS))
return; return;
current->exit_code = SIGTRAP; current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0);
current->state = TASK_STOPPED; current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD); notify_parent(current, SIGCHLD);
schedule(); schedule();
......
...@@ -342,7 +342,7 @@ int sys_ptrace(long request, long pid, long addr, long data) ...@@ -342,7 +342,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
#endif #endif
default: default:
ret = -EIO; ret = ptrace_request(child, request, addr, data);
break; break;
} }
out_tsk: out_tsk:
...@@ -357,7 +357,8 @@ void do_syscall_trace(void) ...@@ -357,7 +357,8 @@ void do_syscall_trace(void)
if (!test_thread_flag(TIF_SYSCALL_TRACE) if (!test_thread_flag(TIF_SYSCALL_TRACE)
|| !(current->ptrace & PT_PTRACED)) || !(current->ptrace & PT_PTRACED))
return; return;
current->exit_code = SIGTRAP; current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0);
current->state = TASK_STOPPED; current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD); notify_parent(current, SIGCHLD);
schedule(); schedule();
......
...@@ -258,7 +258,7 @@ int sys_ptrace(long request, long pid, long addr, long data) ...@@ -258,7 +258,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
} }
default: default:
ret = -EIO; ret = ptrace_request(child, request, addr, data);
break; break;
} }
out_tsk: out_tsk:
...@@ -274,7 +274,8 @@ void do_syscall_trace(void) ...@@ -274,7 +274,8 @@ void do_syscall_trace(void)
return; return;
if (!(current->ptrace & PT_PTRACED)) if (!(current->ptrace & PT_PTRACED))
return; return;
current->exit_code = SIGTRAP; current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0);
current->state = TASK_STOPPED; current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD); notify_parent(current, SIGCHLD);
schedule(); schedule();
......
...@@ -345,7 +345,7 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data) ...@@ -345,7 +345,7 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
break; break;
default: default:
ret = -EIO; ret = ptrace_request(child, request, addr, data);
break; break;
} }
out_tsk: out_tsk:
......
...@@ -346,16 +346,8 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -346,16 +346,8 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret=copy_user(child,parea.kernel_addr,parea.process_addr, ret=copy_user(child,parea.kernel_addr,parea.process_addr,
parea.len,1,(request==PTRACE_POKEUSR_AREA)); parea.len,1,(request==PTRACE_POKEUSR_AREA));
break; break;
case PTRACE_SETOPTIONS: {
if (data & PTRACE_O_TRACESYSGOOD)
child->ptrace |= PT_TRACESYSGOOD;
else
child->ptrace &= ~PT_TRACESYSGOOD;
ret = 0;
break;
}
default: default:
ret = -EIO; ret = ptrace_request(child, request, addr, data);
break; break;
} }
out_tsk: out_tsk:
......
...@@ -576,16 +576,8 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -576,16 +576,8 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
parea.len,1,(request==PTRACE_POKEUSR_AREA)); parea.len,1,(request==PTRACE_POKEUSR_AREA));
} }
break; break;
case PTRACE_SETOPTIONS: {
if (data & PTRACE_O_TRACESYSGOOD)
child->ptrace |= PT_TRACESYSGOOD;
else
child->ptrace &= ~PT_TRACESYSGOOD;
ret = 0;
break;
}
default: default:
ret = -EIO; ret = ptrace_request(child, request, addr, data);
break; break;
} }
out_tsk: out_tsk:
......
...@@ -356,17 +356,8 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -356,17 +356,8 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = ptrace_detach(child, data); ret = ptrace_detach(child, data);
break; break;
case PTRACE_SETOPTIONS: {
if (data & PTRACE_O_TRACESYSGOOD)
child->ptrace |= PT_TRACESYSGOOD;
else
child->ptrace &= ~PT_TRACESYSGOOD;
ret = 0;
break;
}
default: default:
ret = -EIO; ret = ptrace_request(child, request, addr, data);
break; break;
} }
out_tsk: out_tsk:
......
...@@ -584,10 +584,15 @@ asmlinkage void do_ptrace(struct pt_regs *regs) ...@@ -584,10 +584,15 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
/* PTRACE_DUMPCORE unsupported... */ /* PTRACE_DUMPCORE unsupported... */
default: default: {
pt_error_return(regs, EIO); int err = ptrace_request(child, request, addr, data);
if (err)
pt_error_return(regs, -err);
else
pt_succ_return(regs, 0);
goto out_tsk; goto out_tsk;
} }
}
out_tsk: out_tsk:
if (child) if (child)
put_task_struct(child); put_task_struct(child);
...@@ -604,7 +609,8 @@ asmlinkage void syscall_trace(void) ...@@ -604,7 +609,8 @@ asmlinkage void syscall_trace(void)
return; return;
if (!(current->ptrace & PT_PTRACED)) if (!(current->ptrace & PT_PTRACED))
return; return;
current->exit_code = SIGTRAP; current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0);
current->state = TASK_STOPPED; current->state = TASK_STOPPED;
current->thread.flags ^= MAGIC_CONSTANT; current->thread.flags ^= MAGIC_CONSTANT;
notify_parent(current, SIGCHLD); notify_parent(current, SIGCHLD);
......
...@@ -571,10 +571,15 @@ asmlinkage void do_ptrace(struct pt_regs *regs) ...@@ -571,10 +571,15 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
/* PTRACE_DUMPCORE unsupported... */ /* PTRACE_DUMPCORE unsupported... */
default: default: {
pt_error_return(regs, EIO); int err = ptrace_request(child, request, addr, data);
if (err)
pt_error_return(regs, -err);
else
pt_succ_return(regs, 0);
goto out_tsk; goto out_tsk;
} }
}
flush_and_out: flush_and_out:
{ {
unsigned long va; unsigned long va;
...@@ -612,7 +617,8 @@ asmlinkage void syscall_trace(void) ...@@ -612,7 +617,8 @@ asmlinkage void syscall_trace(void)
return; return;
if (!(current->ptrace & PT_PTRACED)) if (!(current->ptrace & PT_PTRACED))
return; return;
current->exit_code = SIGTRAP; current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0);
current->state = TASK_STOPPED; current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD); notify_parent(current, SIGCHLD);
schedule(); schedule();
......
...@@ -172,17 +172,6 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) ...@@ -172,17 +172,6 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
__u32 val; __u32 val;
switch (request) { switch (request) {
case PTRACE_TRACEME:
case PTRACE_ATTACH:
case PTRACE_SYSCALL:
case PTRACE_CONT:
case PTRACE_KILL:
case PTRACE_SINGLESTEP:
case PTRACE_DETACH:
case PTRACE_SETOPTIONS:
ret = sys_ptrace(request, pid, addr, data);
return ret;
case PTRACE_PEEKTEXT: case PTRACE_PEEKTEXT:
case PTRACE_PEEKDATA: case PTRACE_PEEKDATA:
case PTRACE_POKEDATA: case PTRACE_POKEDATA:
...@@ -198,7 +187,8 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) ...@@ -198,7 +187,8 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
break; break;
default: default:
return -EIO; ret = sys_ptrace(request, pid, addr, data);
return ret;
} }
child = find_target(request, pid, &ret); child = find_target(request, pid, &ret);
......
...@@ -396,17 +396,8 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data) ...@@ -396,17 +396,8 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
break; break;
} }
case PTRACE_SETOPTIONS: {
if (data & PTRACE_O_TRACESYSGOOD)
child->ptrace |= PT_TRACESYSGOOD;
else
child->ptrace &= ~PT_TRACESYSGOOD;
ret = 0;
break;
}
default: default:
ret = -EIO; ret = ptrace_request(child, request, addr, data);
break; break;
} }
out_tsk: out_tsk:
......
...@@ -6,10 +6,7 @@ ...@@ -6,10 +6,7 @@
#define PTRACE_GETFPREGS 14 #define PTRACE_GETFPREGS 14
#define PTRACE_SETFPREGS 15 #define PTRACE_SETFPREGS 15
#define PTRACE_SETOPTIONS 21 #define PTRACE_OLDSETOPTIONS 21
/* options set using PTRACE_SETOPTIONS */
#define PTRACE_O_TRACESYSGOOD 0x00000001
#include <asm/proc/ptrace.h> #include <asm/proc/ptrace.h>
......
...@@ -49,10 +49,7 @@ struct pt_regs { ...@@ -49,10 +49,7 @@ struct pt_regs {
#define PTRACE_GETFPXREGS 18 #define PTRACE_GETFPXREGS 18
#define PTRACE_SETFPXREGS 19 #define PTRACE_SETFPXREGS 19
#define PTRACE_SETOPTIONS 21 #define PTRACE_OLDSETOPTIONS 21
/* options set using PTRACE_SETOPTIONS */
#define PTRACE_O_TRACESYSGOOD 0x00000001
#ifdef __KERNEL__ #ifdef __KERNEL__
#define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs)) #define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs))
......
...@@ -287,9 +287,6 @@ struct pt_all_user_regs { ...@@ -287,9 +287,6 @@ struct pt_all_user_regs {
#define PTRACE_GETREGS 18 /* get all registers (pt_all_user_regs) in one shot */ #define PTRACE_GETREGS 18 /* get all registers (pt_all_user_regs) in one shot */
#define PTRACE_SETREGS 19 /* set all registers (pt_all_user_regs) in one shot */ #define PTRACE_SETREGS 19 /* set all registers (pt_all_user_regs) in one shot */
#define PTRACE_SETOPTIONS 21 #define PTRACE_OLDSETOPTIONS 21
/* options set using PTRACE_SETOPTIONS */
#define PTRACE_O_TRACESYSGOOD 0x00000001
#endif /* _ASM_IA64_PTRACE_H */ #endif /* _ASM_IA64_PTRACE_H */
...@@ -59,10 +59,7 @@ struct pt_regs { ...@@ -59,10 +59,7 @@ struct pt_regs {
/* #define PTRACE_GETFPXREGS 18 */ /* #define PTRACE_GETFPXREGS 18 */
/* #define PTRACE_SETFPXREGS 19 */ /* #define PTRACE_SETFPXREGS 19 */
#define PTRACE_SETOPTIONS 21 #define PTRACE_OLDSETOPTIONS 21
/* options set using PTRACE_SETOPTIONS */
#define PTRACE_O_TRACESYSGOOD 0x00000001
#ifdef _LANGUAGE_ASSEMBLY #ifdef _LANGUAGE_ASSEMBLY
#include <asm/offset.h> #include <asm/offset.h>
......
...@@ -64,10 +64,7 @@ struct pt_regs { ...@@ -64,10 +64,7 @@ struct pt_regs {
/* #define PTRACE_GETFPXREGS 18 */ /* #define PTRACE_GETFPXREGS 18 */
/* #define PTRACE_SETFPXREGS 19 */ /* #define PTRACE_SETFPXREGS 19 */
#define PTRACE_SETOPTIONS 21 #define PTRACE_OLDSETOPTIONS 21
/* options set using PTRACE_SETOPTIONS */
#define PTRACE_O_TRACESYSGOOD 0x00000001
#ifdef _LANGUAGE_ASSEMBLY #ifdef _LANGUAGE_ASSEMBLY
#include <asm/offset.h> #include <asm/offset.h>
......
...@@ -105,10 +105,7 @@ ...@@ -105,10 +105,7 @@
#define STACK_FRAME_OVERHEAD 96 /* size of minimum stack frame */ #define STACK_FRAME_OVERHEAD 96 /* size of minimum stack frame */
#define PTRACE_SETOPTIONS 21 #define PTRACE_OLDSETOPTIONS 21
/* options set using PTRACE_SETOPTIONS */
#define PTRACE_O_TRACESYSGOOD 0x00000001
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <linux/config.h> #include <linux/config.h>
......
...@@ -85,10 +85,7 @@ ...@@ -85,10 +85,7 @@
#define STACK_FRAME_OVERHEAD 160 /* size of minimum stack frame */ #define STACK_FRAME_OVERHEAD 160 /* size of minimum stack frame */
#define PTRACE_SETOPTIONS 21 #define PTRACE_OLDSETOPTIONS 21
/* options set using PTRACE_SETOPTIONS */
#define PTRACE_O_TRACESYSGOOD 0x00000001
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <linux/config.h> #include <linux/config.h>
......
...@@ -44,10 +44,7 @@ ...@@ -44,10 +44,7 @@
#define REG_XDREG14 47 #define REG_XDREG14 47
#define REG_FPSCR 48 #define REG_FPSCR 48
#define PTRACE_SETOPTIONS 21 #define PTRACE_OLDSETOPTIONS 21
/* options set using PTRACE_SETOPTIONS */
#define PTRACE_O_TRACESYSGOOD 0x00000001
/* /*
* This struct defines the way the registers are stored on the * This struct defines the way the registers are stored on the
......
...@@ -32,10 +32,7 @@ ...@@ -32,10 +32,7 @@
/* top of stack page */ /* top of stack page */
#define FRAME_SIZE 168 #define FRAME_SIZE 168
#define PTRACE_SETOPTIONS 21 #define PTRACE_OLDSETOPTIONS 21
/* options set using PTRACE_SETOPTIONS */
#define PTRACE_O_TRACESYSGOOD 0x00000001
/* Dummy values for ptrace */ /* Dummy values for ptrace */
#define FS 1000 #define FS 1000
......
...@@ -23,6 +23,12 @@ ...@@ -23,6 +23,12 @@
#define PTRACE_SYSCALL 24 #define PTRACE_SYSCALL 24
/* 0x4200-0x4300 are reserved for architecture-independent additions. */
#define PTRACE_SETOPTIONS 0x4200
/* options set using PTRACE_SETOPTIONS */
#define PTRACE_O_TRACESYSGOOD 0x00000001
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <linux/sched.h> #include <linux/sched.h>
...@@ -32,6 +38,7 @@ extern int ptrace_attach(struct task_struct *tsk); ...@@ -32,6 +38,7 @@ extern int ptrace_attach(struct task_struct *tsk);
extern int ptrace_detach(struct task_struct *, unsigned int); extern int ptrace_detach(struct task_struct *, unsigned int);
extern void ptrace_disable(struct task_struct *); extern void ptrace_disable(struct task_struct *);
extern int ptrace_check_attach(struct task_struct *task, int kill); extern int ptrace_check_attach(struct task_struct *task, int kill);
extern int ptrace_request(struct task_struct *child, long request, long addr, long data);
extern void __ptrace_link(struct task_struct *child, extern void __ptrace_link(struct task_struct *child,
struct task_struct *new_parent); struct task_struct *new_parent);
extern void __ptrace_unlink(struct task_struct *child); extern void __ptrace_unlink(struct task_struct *child);
......
...@@ -248,3 +248,35 @@ int ptrace_writedata(struct task_struct *tsk, char * src, unsigned long dst, int ...@@ -248,3 +248,35 @@ int ptrace_writedata(struct task_struct *tsk, char * src, unsigned long dst, int
} }
return copied; return copied;
} }
int ptrace_setoptions(struct task_struct *child, long data)
{
if (data & PTRACE_O_TRACESYSGOOD)
child->ptrace |= PT_TRACESYSGOOD;
else
child->ptrace &= ~PT_TRACESYSGOOD;
if ((data & PTRACE_O_TRACESYSGOOD) != data)
return -EINVAL;
return 0;
}
int ptrace_request(struct task_struct *child, long request,
long addr, long data)
{
int ret = -EIO;
switch (request) {
#ifdef PTRACE_OLDSETOPTIONS
case PTRACE_OLDSETOPTIONS:
#endif
case PTRACE_SETOPTIONS:
ret = ptrace_setoptions(child, data);
break;
default:
break;
}
return ret;
}
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