1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
diff -Naur linux-2.6.34-utrace/include/linux/ptrace.h linux-2.6.34-utrace-vm1/include/linux/ptrace.h
--- linux-2.6.34-utrace/include/linux/ptrace.h 2010-06-14 15:54:04.000000000 +0200
+++ linux-2.6.34-utrace-vm1/include/linux/ptrace.h 2010-06-14 15:55:13.000000000 +0200
@@ -66,6 +66,11 @@
#define PTRACE_EVENT_VFORK_DONE 5
#define PTRACE_EVENT_EXIT 6
+/* options for new PTRACE_SYSCALL syntax*/
+#define PTRACE_SYSCALL_SKIPEXIT 0x2
+#define PTRACE_SYSCALL_SKIPCALL 0x6
+#define PTRACE_SYSCALL_MASK 0x00000006
+
#include <asm/ptrace.h>
#ifdef __KERNEL__
@@ -88,6 +93,11 @@
#define PT_TRACE_VFORK_DONE 0x00000100
#define PT_TRACE_EXIT 0x00000200
+#define PT_SYSCALL_SKIPEXIT 0x60000000
+#define PT_SYSCALL_SKIPCALL 0x40000000
+#define PT_SYSCALL_MASK 0x60000000
+#define PTRACE2PT_SYSCALL(X) (((X) & PTRACE_SYSCALL_MASK) << 28)
+
#define PT_TRACE_MASK 0x000003f4
/* single stepping state bits (used on ARM and PA-RISC) */
diff -Naur linux-2.6.34-utrace/include/linux/tracehook.h linux-2.6.34-utrace-vm1/include/linux/tracehook.h
--- linux-2.6.34-utrace/include/linux/tracehook.h 2010-06-14 15:53:58.000000000 +0200
+++ linux-2.6.34-utrace-vm1/include/linux/tracehook.h 2010-06-14 15:55:13.000000000 +0200
@@ -118,7 +118,7 @@
utrace_report_syscall_entry(regs))
return 1;
ptrace_report_syscall(regs);
- return 0;
+ return (task_ptrace(current) & PT_SYSCALL_SKIPCALL) ? 1 : 0;
}
/**
@@ -150,7 +150,8 @@
return;
}
- ptrace_report_syscall(regs);
+ if (!(task_ptrace(current) & PT_SYSCALL_SKIPEXIT))
+ ptrace_report_syscall(regs);
}
/**
diff -Naur linux-2.6.34-utrace/kernel/ptrace-utrace.c linux-2.6.34-utrace-vm1/kernel/ptrace-utrace.c
--- linux-2.6.34-utrace/kernel/ptrace-utrace.c 2010-06-14 15:54:04.000000000 +0200
+++ linux-2.6.34-utrace-vm1/kernel/ptrace-utrace.c 2010-06-14 15:56:23.000000000 +0200
@@ -69,6 +69,7 @@
#define PT_UTRACED 0x00001000
#define PTRACE_O_SYSEMU 0x100
+#define PTRACE_O_SKIPCALL 0x200
#define PTRACE_EVENT_SYSCALL (1 << 16)
#define PTRACE_EVENT_SIGTRAP (2 << 16)
@@ -385,7 +386,7 @@
* We already reported the first time.
* Nothing more to do now.
*/
- if (unlikely(ctx->options & PTRACE_O_SYSEMU))
+ if (unlikely(ctx->options & (PTRACE_O_SYSEMU || PTRACE_O_SKIPCALL)))
return UTRACE_SYSCALL_ABORT | UTRACE_REPORT;
return utrace_syscall_action(action) | UTRACE_RESUME;
}
@@ -833,13 +834,13 @@
}
static int ptrace_resume_action(struct task_struct *tracee,
- struct utrace_engine *engine, long request)
+ struct utrace_engine *engine, long request, long addr)
{
struct ptrace_context *ctx = ptrace_context(engine);
unsigned long events;
int action;
- ctx->options &= ~PTRACE_O_SYSEMU;
+ ctx->options &= ~(PTRACE_O_SYSEMU | PTRACE_O_SKIPCALL);
events = engine->flags & ~UTRACE_EVENT_SYSCALL;
action = UTRACE_RESUME;
@@ -874,7 +875,12 @@
#endif
case PTRACE_SYSCALL:
- events |= UTRACE_EVENT_SYSCALL;
+ if (addr & PTRACE_SYSCALL_SKIPCALL)
+ ctx->options |= PTRACE_O_SKIPCALL;
+ if (addr & PTRACE_SYSCALL_SKIPEXIT)
+ events |= UTRACE_EVENT(SYSCALL_ENTRY);
+ else
+ events |= UTRACE_EVENT_SYSCALL;
break;
case PTRACE_CONT:
@@ -892,7 +898,7 @@
static int ptrace_resume(struct task_struct *tracee,
struct utrace_engine *engine,
- long request, long data)
+ long request, long addr, long data)
{
struct ptrace_context *ctx = ptrace_context(engine);
int action;
@@ -900,7 +906,7 @@
if (!valid_signal(data))
return -EIO;
- action = ptrace_resume_action(tracee, engine, request);
+ action = ptrace_resume_action(tracee, engine, request, addr);
if (action < 0)
return action;
@@ -1005,7 +1011,7 @@
case PTRACE_KILL:
/* Ugly historical behaviour. */
if (task_is_traced(child))
- ptrace_resume(child, engine, PTRACE_CONT, SIGKILL);
+ ptrace_resume(child, engine, PTRACE_CONT, addr, SIGKILL);
ret = 0;
break;
@@ -1029,7 +1035,7 @@
}
default:
- ret = ptrace_resume(child, engine, request, data);
+ ret = ptrace_resume(child, engine, request, addr, data);
break;
}
diff -Naur linux-2.6.34-utrace/kernel/ptrace.c linux-2.6.34-utrace-vm1/kernel/ptrace.c
--- linux-2.6.34-utrace/kernel/ptrace.c 2010-06-14 15:54:04.000000000 +0200
+++ linux-2.6.34-utrace-vm1/kernel/ptrace.c 2010-06-14 15:55:13.000000000 +0200
@@ -649,7 +649,8 @@
#define is_sysemu_singlestep(request) 0
#endif
-static int ptrace_resume(struct task_struct *child, long request, long data)
+static int ptrace_resume(struct task_struct *child, long request,
+ long addr, long data)
{
if (!valid_signal(data))
return -EIO;
@@ -678,6 +679,9 @@
user_disable_single_step(child);
}
+ child->ptrace &= ~PT_SYSCALL_MASK;
+ child->ptrace |= PTRACE2PT_SYSCALL(addr);
+
child->exit_code = data;
wake_up_process(child);
@@ -739,12 +743,12 @@
#endif
case PTRACE_SYSCALL:
case PTRACE_CONT:
- return ptrace_resume(child, request, data);
+ return ptrace_resume(child, request, addr, data);
case PTRACE_KILL:
if (child->exit_state) /* already dead */
return 0;
- return ptrace_resume(child, request, SIGKILL);
+ return ptrace_resume(child, request, addr, SIGKILL);
#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
case PTRACE_GETREGSET:
|