utrace update
This commit is contained in:
parent
2eddc8a9bb
commit
c496c71d98
@ -1984,6 +1984,9 @@ fi
|
|||||||
# ||----w |
|
# ||----w |
|
||||||
# || ||
|
# || ||
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Jan 19 2011 Roland McGrath <roland@redhat.com>
|
||||||
|
- utrace update
|
||||||
|
|
||||||
* Tue Jan 11 2011 Matthew Garrett <mjg@redhat.com>
|
* Tue Jan 11 2011 Matthew Garrett <mjg@redhat.com>
|
||||||
- linux-2.6-ehci-check-port-status.patch - fix USB resume on some AMD systems
|
- linux-2.6-ehci-check-port-status.patch - fix USB resume on some AMD systems
|
||||||
|
|
||||||
|
@ -20,10 +20,10 @@ Signed-off-by: Roland McGrath <roland@redhat.com>
|
|||||||
5 files changed, 10 insertions(+), 8 deletions(-)
|
5 files changed, 10 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
|
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
|
||||||
index 4272521..a85fb41 100644
|
index 092a04f..619cdf0 100644
|
||||||
--- a/include/linux/ptrace.h
|
--- a/include/linux/ptrace.h
|
||||||
+++ b/include/linux/ptrace.h
|
+++ b/include/linux/ptrace.h
|
||||||
@@ -105,6 +105,7 @@ extern int ptrace_traceme(void);
|
@@ -106,6 +106,7 @@ extern int ptrace_traceme(void);
|
||||||
extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len);
|
extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len);
|
||||||
extern int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len);
|
extern int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len);
|
||||||
extern int ptrace_attach(struct task_struct *tsk);
|
extern int ptrace_attach(struct task_struct *tsk);
|
||||||
@ -32,10 +32,10 @@ index 4272521..a85fb41 100644
|
|||||||
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);
|
||||||
diff --git a/include/linux/sched.h b/include/linux/sched.h
|
diff --git a/include/linux/sched.h b/include/linux/sched.h
|
||||||
index ce160d6..5e7cc95 100644
|
index 2238745..09f26df 100644
|
||||||
--- a/include/linux/sched.h
|
--- a/include/linux/sched.h
|
||||||
+++ b/include/linux/sched.h
|
+++ b/include/linux/sched.h
|
||||||
@@ -2030,6 +2030,7 @@ extern int kill_pgrp(struct pid *pid, in
|
@@ -2061,6 +2061,7 @@ extern int kill_pgrp(struct pid *pid, in
|
||||||
extern int kill_pid(struct pid *pid, int sig, int priv);
|
extern int kill_pid(struct pid *pid, int sig, int priv);
|
||||||
extern int kill_proc_info(int, struct siginfo *, pid_t);
|
extern int kill_proc_info(int, struct siginfo *, pid_t);
|
||||||
extern int do_notify_parent(struct task_struct *, int);
|
extern int do_notify_parent(struct task_struct *, int);
|
||||||
@ -44,7 +44,7 @@ index ce160d6..5e7cc95 100644
|
|||||||
extern void force_sig(int, struct task_struct *);
|
extern void force_sig(int, struct task_struct *);
|
||||||
extern int send_sig(int, struct task_struct *, int);
|
extern int send_sig(int, struct task_struct *, int);
|
||||||
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
|
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
|
||||||
index 10db010..c78b2f4 100644
|
index 3a2e66d..98917e9 100644
|
||||||
--- a/include/linux/tracehook.h
|
--- a/include/linux/tracehook.h
|
||||||
+++ b/include/linux/tracehook.h
|
+++ b/include/linux/tracehook.h
|
||||||
@@ -134,7 +134,7 @@ static inline __must_check int tracehook
|
@@ -134,7 +134,7 @@ static inline __must_check int tracehook
|
||||||
@ -93,7 +93,7 @@ index 10db010..c78b2f4 100644
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
|
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
|
||||||
index f34d798..8049cb5 100644
|
index 99bbaa3..84d9f8f 100644
|
||||||
--- a/kernel/ptrace.c
|
--- a/kernel/ptrace.c
|
||||||
+++ b/kernel/ptrace.c
|
+++ b/kernel/ptrace.c
|
||||||
@@ -270,7 +270,7 @@ static int ignoring_children(struct sigh
|
@@ -270,7 +270,7 @@ static int ignoring_children(struct sigh
|
||||||
@ -106,10 +106,10 @@ index f34d798..8049cb5 100644
|
|||||||
__ptrace_unlink(p);
|
__ptrace_unlink(p);
|
||||||
|
|
||||||
diff --git a/kernel/signal.c b/kernel/signal.c
|
diff --git a/kernel/signal.c b/kernel/signal.c
|
||||||
index bded651..6d13d9f 100644
|
index 4e3cff1..b74324d 100644
|
||||||
--- a/kernel/signal.c
|
--- a/kernel/signal.c
|
||||||
+++ b/kernel/signal.c
|
+++ b/kernel/signal.c
|
||||||
@@ -1521,7 +1521,7 @@ int do_notify_parent(struct task_struct
|
@@ -1522,7 +1522,7 @@ int do_notify_parent(struct task_struct
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ index bded651..6d13d9f 100644
|
|||||||
{
|
{
|
||||||
struct siginfo info;
|
struct siginfo info;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
@@ -1791,7 +1791,7 @@ static int do_signal_stop(int signr)
|
@@ -1794,7 +1794,7 @@ static int do_signal_stop(int signr)
|
||||||
static int ptrace_signal(int signr, siginfo_t *info,
|
static int ptrace_signal(int signr, siginfo_t *info,
|
||||||
struct pt_regs *regs, void *cookie)
|
struct pt_regs *regs, void *cookie)
|
||||||
{
|
{
|
||||||
|
@ -12,28 +12,27 @@ change to userland when CONFIG_UTRACE is enabled.
|
|||||||
Signed-off-by: Roland McGrath <roland@redhat.com>
|
Signed-off-by: Roland McGrath <roland@redhat.com>
|
||||||
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
|
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
|
||||||
---
|
---
|
||||||
include/linux/ptrace.h | 2 +-
|
include/linux/ptrace.h | 1 +
|
||||||
kernel/Makefile | 1 +
|
kernel/Makefile | 1 +
|
||||||
kernel/ptrace-utrace.c | 1138 ++++++++++++++++++++++++++++++++++++++++++++++++
|
kernel/ptrace-utrace.c | 1187 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
kernel/ptrace.c | 688 ++++++++++++++---------------
|
kernel/ptrace.c | 690 ++++++++++++++--------------
|
||||||
kernel/utrace.c | 16 +
|
kernel/utrace.c | 16 +
|
||||||
5 files changed, 1494 insertions(+), 351 deletions(-)
|
5 files changed, 1544 insertions(+), 351 deletions(-)
|
||||||
|
|
||||||
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
|
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
|
||||||
index a85fb41..235c1b0 100644
|
index 619cdf0..e391bdb 100644
|
||||||
--- a/include/linux/ptrace.h
|
--- a/include/linux/ptrace.h
|
||||||
+++ b/include/linux/ptrace.h
|
+++ b/include/linux/ptrace.h
|
||||||
@@ -99,7 +99,7 @@
|
@@ -100,6 +100,7 @@
|
||||||
#include <linux/compiler.h> /* For unlikely. */
|
|
||||||
#include <linux/sched.h> /* For struct task_struct. */
|
#include <linux/sched.h> /* For struct task_struct. */
|
||||||
|
|
||||||
-
|
|
||||||
+extern void ptrace_notify_stop(struct task_struct *tracee);
|
+extern void ptrace_notify_stop(struct task_struct *tracee);
|
||||||
extern long arch_ptrace(struct task_struct *child, long request,
|
extern long arch_ptrace(struct task_struct *child, long request,
|
||||||
unsigned long addr, unsigned long data);
|
unsigned long addr, unsigned long data);
|
||||||
extern int ptrace_traceme(void);
|
extern int ptrace_traceme(void);
|
||||||
diff --git a/kernel/Makefile b/kernel/Makefile
|
diff --git a/kernel/Makefile b/kernel/Makefile
|
||||||
index 6004913..b09c9a5 100644
|
index 1172528..9a815a5 100644
|
||||||
--- a/kernel/Makefile
|
--- a/kernel/Makefile
|
||||||
+++ b/kernel/Makefile
|
+++ b/kernel/Makefile
|
||||||
@@ -71,6 +71,7 @@ obj-$(CONFIG_RESOURCE_COUNTERS) += res_c
|
@@ -71,6 +71,7 @@ obj-$(CONFIG_RESOURCE_COUNTERS) += res_c
|
||||||
@ -46,10 +45,10 @@ index 6004913..b09c9a5 100644
|
|||||||
obj-$(CONFIG_AUDIT_WATCH) += audit_watch.o
|
obj-$(CONFIG_AUDIT_WATCH) += audit_watch.o
|
||||||
diff --git a/kernel/ptrace-utrace.c b/kernel/ptrace-utrace.c
|
diff --git a/kernel/ptrace-utrace.c b/kernel/ptrace-utrace.c
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index ...a90078d 100644
|
index ...a5bcb9e 100644
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/kernel/ptrace-utrace.c
|
+++ b/kernel/ptrace-utrace.c
|
||||||
@@ -0,0 +1,1138 @@
|
@@ -0,0 +1,1187 @@
|
||||||
+/*
|
+/*
|
||||||
+ * linux/kernel/ptrace.c
|
+ * linux/kernel/ptrace.c
|
||||||
+ *
|
+ *
|
||||||
@ -119,6 +118,7 @@ index ...a90078d 100644
|
|||||||
+#define PT_UTRACED 0x00001000
|
+#define PT_UTRACED 0x00001000
|
||||||
+
|
+
|
||||||
+#define PTRACE_O_SYSEMU 0x100
|
+#define PTRACE_O_SYSEMU 0x100
|
||||||
|
+#define PTRACE_O_DETACHED 0x200
|
||||||
+
|
+
|
||||||
+#define PTRACE_EVENT_SYSCALL (1 << 16)
|
+#define PTRACE_EVENT_SYSCALL (1 << 16)
|
||||||
+#define PTRACE_EVENT_SIGTRAP (2 << 16)
|
+#define PTRACE_EVENT_SIGTRAP (2 << 16)
|
||||||
@ -155,6 +155,19 @@ index ...a90078d 100644
|
|||||||
+ &ptrace_utrace_ops, NULL);
|
+ &ptrace_utrace_ops, NULL);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
|
+static int utrace_barrier_uninterruptible(struct task_struct *target,
|
||||||
|
+ struct utrace_engine *engine)
|
||||||
|
+{
|
||||||
|
+ for (;;) {
|
||||||
|
+ int err = utrace_barrier(target, engine);
|
||||||
|
+
|
||||||
|
+ if (err != -ERESTARTSYS)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
+ schedule_timeout_uninterruptible(1);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
+static struct utrace_engine *
|
+static struct utrace_engine *
|
||||||
+ptrace_reuse_engine(struct task_struct *tracee)
|
+ptrace_reuse_engine(struct task_struct *tracee)
|
||||||
+{
|
+{
|
||||||
@ -167,7 +180,7 @@ index ...a90078d 100644
|
|||||||
+ return engine;
|
+ return engine;
|
||||||
+
|
+
|
||||||
+ ctx = ptrace_context(engine);
|
+ ctx = ptrace_context(engine);
|
||||||
+ if (unlikely(ctx->resume == UTRACE_DETACH)) {
|
+ if (unlikely(ctx->options == PTRACE_O_DETACHED)) {
|
||||||
+ /*
|
+ /*
|
||||||
+ * Try to reuse this self-detaching engine.
|
+ * Try to reuse this self-detaching engine.
|
||||||
+ * The only caller which can hit this case is ptrace_attach(),
|
+ * The only caller which can hit this case is ptrace_attach(),
|
||||||
@ -181,12 +194,16 @@ index ...a90078d 100644
|
|||||||
+ if (!err || err == -EINPROGRESS) {
|
+ if (!err || err == -EINPROGRESS) {
|
||||||
+ ctx->resume = UTRACE_RESUME;
|
+ ctx->resume = UTRACE_RESUME;
|
||||||
+ /* synchronize with ptrace_report_signal() */
|
+ /* synchronize with ptrace_report_signal() */
|
||||||
+ err = utrace_barrier(tracee, engine);
|
+ err = utrace_barrier_uninterruptible(tracee, engine);
|
||||||
+ }
|
+ }
|
||||||
+ WARN_ON(!err != (engine->ops == &ptrace_utrace_ops));
|
|
||||||
+
|
+
|
||||||
+ if (!err)
|
+ if (!err) {
|
||||||
|
+ WARN_ON(engine->ops != &ptrace_utrace_ops &&
|
||||||
|
+ !tracee->exit_state);
|
||||||
+ return engine;
|
+ return engine;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ WARN_ON(engine->ops == &ptrace_utrace_ops);
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ utrace_engine_put(engine);
|
+ utrace_engine_put(engine);
|
||||||
@ -296,32 +313,60 @@ index ...a90078d 100644
|
|||||||
+ * If true, the caller is PTRACE_DETACH, otherwise
|
+ * If true, the caller is PTRACE_DETACH, otherwise
|
||||||
+ * the tracer detaches implicitly during exit.
|
+ * the tracer detaches implicitly during exit.
|
||||||
+ */
|
+ */
|
||||||
+ bool voluntary = (sig >= 0);
|
+ bool explicit = (sig >= 0);
|
||||||
+ struct utrace_engine *engine = ptrace_lookup_engine(tracee);
|
+ struct utrace_engine *engine = ptrace_lookup_engine(tracee);
|
||||||
+ enum utrace_resume_action action = UTRACE_DETACH;
|
+ enum utrace_resume_action action = UTRACE_DETACH;
|
||||||
|
+ struct ptrace_context *ctx;
|
||||||
+
|
+
|
||||||
+ if (unlikely(IS_ERR(engine)))
|
+ if (unlikely(IS_ERR(engine)))
|
||||||
+ return;
|
+ return;
|
||||||
+
|
+
|
||||||
+ if (sig) {
|
+ ctx = ptrace_context(engine);
|
||||||
+ struct ptrace_context *ctx = ptrace_context(engine);
|
|
||||||
+
|
+
|
||||||
|
+ if (!explicit) {
|
||||||
|
+ int err;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * We are going to detach, the tracee can be running.
|
||||||
|
+ * Ensure ptrace_report_signal() won't report a signal.
|
||||||
|
+ */
|
||||||
|
+ ctx->resume = UTRACE_DETACH;
|
||||||
|
+ err = utrace_barrier_uninterruptible(tracee, engine);
|
||||||
|
+
|
||||||
|
+ if (!err && ctx->siginfo) {
|
||||||
|
+ /*
|
||||||
|
+ * The tracee has already reported a signal
|
||||||
|
+ * before utrace_barrier().
|
||||||
|
+ *
|
||||||
|
+ * Resume it like we do in PTRACE_EVENT_SIGNAL
|
||||||
|
+ * case below. The difference is that we can race
|
||||||
|
+ * with ptrace_report_signal() if the tracee is
|
||||||
|
+ * running but this doesn't matter. In any case
|
||||||
|
+ * UTRACE_SIGNAL_REPORT must be pending and it
|
||||||
|
+ * can return nothing but UTRACE_DETACH.
|
||||||
|
+ */
|
||||||
|
+ action = UTRACE_RESUME;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ } else if (sig) {
|
||||||
+ switch (get_stop_event(ctx)) {
|
+ switch (get_stop_event(ctx)) {
|
||||||
+ case PTRACE_EVENT_SYSCALL:
|
+ case PTRACE_EVENT_SYSCALL:
|
||||||
+ if (voluntary)
|
+ send_sig_info(sig, SEND_SIG_PRIV, tracee);
|
||||||
+ send_sig_info(sig, SEND_SIG_PRIV, tracee);
|
|
||||||
+ break;
|
+ break;
|
||||||
+
|
+
|
||||||
+ case PTRACE_EVENT_SIGNAL:
|
+ case PTRACE_EVENT_SIGNAL:
|
||||||
+ if (voluntary)
|
+ ctx->signr = sig;
|
||||||
+ ctx->signr = sig;
|
|
||||||
+ ctx->resume = UTRACE_DETACH;
|
+ ctx->resume = UTRACE_DETACH;
|
||||||
+ action = UTRACE_RESUME;
|
+ action = UTRACE_RESUME;
|
||||||
+ break;
|
+ break;
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ ptrace_wake_up(tracee, engine, action, voluntary);
|
+ ptrace_wake_up(tracee, engine, action, explicit);
|
||||||
|
+
|
||||||
|
+ if (action != UTRACE_DETACH)
|
||||||
|
+ ctx->options = PTRACE_O_DETACHED;
|
||||||
|
+
|
||||||
+ utrace_engine_put(engine);
|
+ utrace_engine_put(engine);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
@ -453,6 +498,11 @@ index ...a90078d 100644
|
|||||||
+ return UTRACE_SYSCALL_RUN | UTRACE_STOP;
|
+ return UTRACE_SYSCALL_RUN | UTRACE_STOP;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
|
+static inline bool is_step_resume(enum utrace_resume_action resume)
|
||||||
|
+{
|
||||||
|
+ return resume == UTRACE_BLOCKSTEP || resume == UTRACE_SINGLESTEP;
|
||||||
|
+}
|
||||||
|
+
|
||||||
+static u32 ptrace_report_syscall_exit(u32 action, struct utrace_engine *engine,
|
+static u32 ptrace_report_syscall_exit(u32 action, struct utrace_engine *engine,
|
||||||
+ struct pt_regs *regs)
|
+ struct pt_regs *regs)
|
||||||
+{
|
+{
|
||||||
@ -461,11 +511,7 @@ index ...a90078d 100644
|
|||||||
+ if (ptrace_event_pending(ctx))
|
+ if (ptrace_event_pending(ctx))
|
||||||
+ return UTRACE_STOP;
|
+ return UTRACE_STOP;
|
||||||
+
|
+
|
||||||
+ if (ctx->resume != UTRACE_RESUME) {
|
+ if (is_step_resume(ctx->resume)) {
|
||||||
+ WARN_ON(ctx->resume != UTRACE_BLOCKSTEP &&
|
|
||||||
+ ctx->resume != UTRACE_SINGLESTEP);
|
|
||||||
+ ctx->resume = UTRACE_RESUME;
|
|
||||||
+
|
|
||||||
+ ctx->signr = SIGTRAP;
|
+ ctx->signr = SIGTRAP;
|
||||||
+ return UTRACE_INTERRUPT;
|
+ return UTRACE_INTERRUPT;
|
||||||
+ }
|
+ }
|
||||||
@ -553,10 +599,7 @@ index ...a90078d 100644
|
|||||||
+ if (WARN_ON(ctx->siginfo))
|
+ if (WARN_ON(ctx->siginfo))
|
||||||
+ ctx->siginfo = NULL;
|
+ ctx->siginfo = NULL;
|
||||||
+
|
+
|
||||||
+ if (resume != UTRACE_RESUME) {
|
+ if (is_step_resume(resume)) {
|
||||||
+ WARN_ON(resume != UTRACE_BLOCKSTEP &&
|
|
||||||
+ resume != UTRACE_SINGLESTEP);
|
|
||||||
+
|
|
||||||
+ set_stop_code(ctx, PTRACE_EVENT_SIGTRAP);
|
+ set_stop_code(ctx, PTRACE_EVENT_SIGTRAP);
|
||||||
+ return UTRACE_STOP | UTRACE_SIGNAL_IGN;
|
+ return UTRACE_STOP | UTRACE_SIGNAL_IGN;
|
||||||
+ }
|
+ }
|
||||||
@ -583,6 +626,11 @@ index ...a90078d 100644
|
|||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ WARN_ON(ctx->siginfo);
|
+ WARN_ON(ctx->siginfo);
|
||||||
|
+
|
||||||
|
+ /* Raced with the exiting tracer ? */
|
||||||
|
+ if (resume == UTRACE_DETACH)
|
||||||
|
+ return action;
|
||||||
|
+
|
||||||
+ ctx->siginfo = info;
|
+ ctx->siginfo = info;
|
||||||
+ /*
|
+ /*
|
||||||
+ * ctx->siginfo points to the caller's stack.
|
+ * ctx->siginfo points to the caller's stack.
|
||||||
@ -811,7 +859,7 @@ index ...a90078d 100644
|
|||||||
+static int ptrace_set_options(struct task_struct *tracee,
|
+static int ptrace_set_options(struct task_struct *tracee,
|
||||||
+ struct utrace_engine *engine, long data)
|
+ struct utrace_engine *engine, long data)
|
||||||
+{
|
+{
|
||||||
+ BUILD_BUG_ON(PTRACE_O_MASK & PTRACE_O_SYSEMU);
|
+ BUILD_BUG_ON(PTRACE_O_MASK & (PTRACE_O_SYSEMU | PTRACE_O_DETACHED));
|
||||||
+
|
+
|
||||||
+ ptrace_set_events(tracee, engine, data & PTRACE_O_MASK);
|
+ ptrace_set_events(tracee, engine, data & PTRACE_O_MASK);
|
||||||
+ return (data & ~PTRACE_O_MASK) ? -EINVAL : 0;
|
+ return (data & ~PTRACE_O_MASK) ? -EINVAL : 0;
|
||||||
@ -1189,7 +1237,7 @@ index ...a90078d 100644
|
|||||||
+}
|
+}
|
||||||
+#endif /* CONFIG_COMPAT */
|
+#endif /* CONFIG_COMPAT */
|
||||||
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
|
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
|
||||||
index 23bde94..daed9e8 100644
|
index e275608..72ea65c 100644
|
||||||
--- a/kernel/ptrace.c
|
--- a/kernel/ptrace.c
|
||||||
+++ b/kernel/ptrace.c
|
+++ b/kernel/ptrace.c
|
||||||
@@ -15,7 +15,6 @@
|
@@ -15,7 +15,6 @@
|
||||||
@ -1200,7 +1248,7 @@ index 23bde94..daed9e8 100644
|
|||||||
#include <linux/security.h>
|
#include <linux/security.h>
|
||||||
#include <linux/signal.h>
|
#include <linux/signal.h>
|
||||||
#include <linux/audit.h>
|
#include <linux/audit.h>
|
||||||
@@ -24,7 +23,317 @@
|
@@ -24,7 +23,320 @@
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <linux/regset.h>
|
#include <linux/regset.h>
|
||||||
|
|
||||||
@ -1412,7 +1460,8 @@ index 23bde94..daed9e8 100644
|
|||||||
+#define arch_ptrace_attach(child) do { } while (0)
|
+#define arch_ptrace_attach(child) do { } while (0)
|
||||||
+#endif
|
+#endif
|
||||||
+
|
+
|
||||||
+SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr, unsigned long, data)
|
+SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr,
|
||||||
|
+ unsigned long, data)
|
||||||
+{
|
+{
|
||||||
+ struct task_struct *child;
|
+ struct task_struct *child;
|
||||||
+ long ret;
|
+ long ret;
|
||||||
@ -1423,13 +1472,13 @@ index 23bde94..daed9e8 100644
|
|||||||
+ arch_ptrace_attach(current);
|
+ arch_ptrace_attach(current);
|
||||||
+ goto out;
|
+ goto out;
|
||||||
+ }
|
+ }
|
||||||
+
|
|
||||||
+ child = ptrace_get_task_struct(pid);
|
+ child = ptrace_get_task_struct(pid);
|
||||||
+ if (IS_ERR(child)) {
|
+ if (IS_ERR(child)) {
|
||||||
+ ret = PTR_ERR(child);
|
+ ret = PTR_ERR(child);
|
||||||
+ goto out;
|
+ goto out;
|
||||||
+ }
|
+ }
|
||||||
|
+
|
||||||
+ if (request == PTRACE_ATTACH) {
|
+ if (request == PTRACE_ATTACH) {
|
||||||
+ ret = ptrace_attach(child);
|
+ ret = ptrace_attach(child);
|
||||||
+ /*
|
+ /*
|
||||||
@ -1453,7 +1502,8 @@ index 23bde94..daed9e8 100644
|
|||||||
+ return ret;
|
+ return ret;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+int generic_ptrace_peekdata(struct task_struct *tsk, unsigned long addr, unsigned long data)
|
+int generic_ptrace_peekdata(struct task_struct *tsk, unsigned long addr,
|
||||||
|
+ unsigned long data)
|
||||||
+{
|
+{
|
||||||
+ unsigned long tmp;
|
+ unsigned long tmp;
|
||||||
+ int copied;
|
+ int copied;
|
||||||
@ -1464,7 +1514,8 @@ index 23bde94..daed9e8 100644
|
|||||||
+ return put_user(tmp, (unsigned long __user *)data);
|
+ return put_user(tmp, (unsigned long __user *)data);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr, unsigned long data)
|
+int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr,
|
||||||
|
+ unsigned long data)
|
||||||
+{
|
+{
|
||||||
+ int copied;
|
+ int copied;
|
||||||
+
|
+
|
||||||
@ -1518,7 +1569,7 @@ index 23bde94..daed9e8 100644
|
|||||||
/*
|
/*
|
||||||
* ptrace a task: make the debugger its new parent and
|
* ptrace a task: make the debugger its new parent and
|
||||||
* move it to the ptrace list.
|
* move it to the ptrace list.
|
||||||
@@ -117,61 +426,6 @@ int ptrace_check_attach(struct task_stru
|
@@ -117,61 +429,6 @@ int ptrace_check_attach(struct task_stru
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1580,7 +1631,7 @@ index 23bde94..daed9e8 100644
|
|||||||
int ptrace_attach(struct task_struct *task)
|
int ptrace_attach(struct task_struct *task)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
@@ -195,8 +449,6 @@ int ptrace_attach(struct task_struct *ta
|
@@ -195,8 +452,6 @@ int ptrace_attach(struct task_struct *ta
|
||||||
|
|
||||||
task_lock(task);
|
task_lock(task);
|
||||||
retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH);
|
retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH);
|
||||||
@ -1589,13 +1640,10 @@ index 23bde94..daed9e8 100644
|
|||||||
task_unlock(task);
|
task_unlock(task);
|
||||||
if (retval)
|
if (retval)
|
||||||
goto unlock_creds;
|
goto unlock_creds;
|
||||||
@@ -217,94 +469,40 @@ int ptrace_attach(struct task_struct *ta
|
@@ -220,91 +475,37 @@ unlock_tasklist:
|
||||||
|
write_unlock_irq(&tasklist_lock);
|
||||||
retval = 0;
|
unlock_creds:
|
||||||
unlock_tasklist:
|
mutex_unlock(&task->signal->cred_guard_mutex);
|
||||||
- write_unlock_irq(&tasklist_lock);
|
|
||||||
-unlock_creds:
|
|
||||||
- mutex_unlock(&task->signal->cred_guard_mutex);
|
|
||||||
-out:
|
-out:
|
||||||
- return retval;
|
- return retval;
|
||||||
-}
|
-}
|
||||||
@ -1654,9 +1702,6 @@ index 23bde94..daed9e8 100644
|
|||||||
- * If it's a zombie, our attachedness prevented normal parent notification
|
- * If it's a zombie, our attachedness prevented normal parent notification
|
||||||
- * or self-reaping. Do notification now if it would have happened earlier.
|
- * or self-reaping. Do notification now if it would have happened earlier.
|
||||||
- * If it should reap itself, return true.
|
- * If it should reap itself, return true.
|
||||||
+ write_unlock_irq(&tasklist_lock);
|
|
||||||
+unlock_creds:
|
|
||||||
+ mutex_unlock(&task->signal->cred_guard_mutex);
|
|
||||||
+out:
|
+out:
|
||||||
+ return retval;
|
+ return retval;
|
||||||
+}
|
+}
|
||||||
@ -1711,7 +1756,7 @@ index 23bde94..daed9e8 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ptrace_detach(struct task_struct *child, unsigned int data)
|
int ptrace_detach(struct task_struct *child, unsigned int data)
|
||||||
@@ -366,56 +564,6 @@ void exit_ptrace(struct task_struct *tra
|
@@ -368,57 +569,7 @@ void exit_ptrace(struct task_struct *tra
|
||||||
write_lock_irq(&tasklist_lock);
|
write_lock_irq(&tasklist_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1765,10 +1810,12 @@ index 23bde94..daed9e8 100644
|
|||||||
- return copied;
|
- return copied;
|
||||||
-}
|
-}
|
||||||
-
|
-
|
||||||
static int ptrace_setoptions(struct task_struct *child, unsigned long data)
|
-static int ptrace_setoptions(struct task_struct *child, unsigned long data)
|
||||||
|
+static int ptrace_setoptions(struct task_struct *child, long data)
|
||||||
{
|
{
|
||||||
child->ptrace &= ~PT_TRACE_MASK;
|
child->ptrace &= ~PT_TRACE_MASK;
|
||||||
@@ -530,47 +677,6 @@ static int ptrace_resume(struct task_str
|
|
||||||
|
@@ -533,47 +683,6 @@ static int ptrace_resume(struct task_str
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1816,7 +1863,7 @@ index 23bde94..daed9e8 100644
|
|||||||
int ptrace_request(struct task_struct *child, long request,
|
int ptrace_request(struct task_struct *child, long request,
|
||||||
unsigned long addr, unsigned long data)
|
unsigned long addr, unsigned long data)
|
||||||
{
|
{
|
||||||
@@ -686,91 +792,7 @@ int ptrace_request(struct task_struct *c
|
@@ -689,91 +798,7 @@ int ptrace_request(struct task_struct *c
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1908,7 +1955,7 @@ index 23bde94..daed9e8 100644
|
|||||||
int compat_ptrace_request(struct task_struct *child, compat_long_t request,
|
int compat_ptrace_request(struct task_struct *child, compat_long_t request,
|
||||||
compat_ulong_t addr, compat_ulong_t data)
|
compat_ulong_t addr, compat_ulong_t data)
|
||||||
{
|
{
|
||||||
@@ -845,42 +870,5 @@ int compat_ptrace_request(struct task_st
|
@@ -851,42 +876,5 @@ int compat_ptrace_request(struct task_st
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1953,10 +2000,10 @@ index 23bde94..daed9e8 100644
|
|||||||
#endif /* CONFIG_COMPAT */
|
#endif /* CONFIG_COMPAT */
|
||||||
+#endif /* CONFIG_UTRACE */
|
+#endif /* CONFIG_UTRACE */
|
||||||
diff --git a/kernel/utrace.c b/kernel/utrace.c
|
diff --git a/kernel/utrace.c b/kernel/utrace.c
|
||||||
index 43f38b7..fd21b7b 100644
|
index 26d6faf..37dce16 100644
|
||||||
--- a/kernel/utrace.c
|
--- a/kernel/utrace.c
|
||||||
+++ b/kernel/utrace.c
|
+++ b/kernel/utrace.c
|
||||||
@@ -809,6 +809,22 @@ relock:
|
@@ -816,6 +816,22 @@ relock:
|
||||||
spin_unlock_irq(&task->sighand->siglock);
|
spin_unlock_irq(&task->sighand->siglock);
|
||||||
spin_unlock(&utrace->lock);
|
spin_unlock(&utrace->lock);
|
||||||
|
|
||||||
|
@ -35,11 +35,11 @@ Signed-off-by: Roland McGrath <roland@redhat.com>
|
|||||||
kernel/Makefile | 1 +
|
kernel/Makefile | 1 +
|
||||||
kernel/fork.c | 3 +
|
kernel/fork.c | 3 +
|
||||||
kernel/ptrace.c | 14 +
|
kernel/ptrace.c | 14 +
|
||||||
kernel/utrace.c | 2434 +++++++++++++++++++++++++++++++++++++
|
kernel/utrace.c | 2440 +++++++++++++++++++++++++++++++++++++
|
||||||
11 files changed, 3837 insertions(+), 2 deletions(-)
|
11 files changed, 3843 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
|
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
|
||||||
index 34929f2..884c36b 100644
|
index 8b6e00a..2740633 100644
|
||||||
--- a/Documentation/DocBook/Makefile
|
--- a/Documentation/DocBook/Makefile
|
||||||
+++ b/Documentation/DocBook/Makefile
|
+++ b/Documentation/DocBook/Makefile
|
||||||
@@ -14,7 +14,7 @@ DOCBOOKS := z8530book.xml mcabook.xml de
|
@@ -14,7 +14,7 @@ DOCBOOKS := z8530book.xml mcabook.xml de
|
||||||
@ -668,10 +668,10 @@ index fff6572..a67bd83 100644
|
|||||||
if (p->files)
|
if (p->files)
|
||||||
fdt = files_fdtable(p->files);
|
fdt = files_fdtable(p->files);
|
||||||
diff --git a/include/linux/sched.h b/include/linux/sched.h
|
diff --git a/include/linux/sched.h b/include/linux/sched.h
|
||||||
index 5e7cc95..66a1ec8 100644
|
index 09f26df..e6fa5e9 100644
|
||||||
--- a/include/linux/sched.h
|
--- a/include/linux/sched.h
|
||||||
+++ b/include/linux/sched.h
|
+++ b/include/linux/sched.h
|
||||||
@@ -1339,6 +1339,11 @@ struct task_struct {
|
@@ -1357,6 +1357,11 @@ struct task_struct {
|
||||||
#endif
|
#endif
|
||||||
seccomp_t seccomp;
|
seccomp_t seccomp;
|
||||||
|
|
||||||
@ -684,7 +684,7 @@ index 5e7cc95..66a1ec8 100644
|
|||||||
u32 parent_exec_id;
|
u32 parent_exec_id;
|
||||||
u32 self_exec_id;
|
u32 self_exec_id;
|
||||||
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
|
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
|
||||||
index c78b2f4..71fa250 100644
|
index 98917e9..afba8f8 100644
|
||||||
--- a/include/linux/tracehook.h
|
--- a/include/linux/tracehook.h
|
||||||
+++ b/include/linux/tracehook.h
|
+++ b/include/linux/tracehook.h
|
||||||
@@ -49,6 +49,7 @@
|
@@ -49,6 +49,7 @@
|
||||||
@ -1620,10 +1620,10 @@ index ...f251efe 100644
|
|||||||
+
|
+
|
||||||
+#endif /* linux/utrace.h */
|
+#endif /* linux/utrace.h */
|
||||||
diff --git a/init/Kconfig b/init/Kconfig
|
diff --git a/init/Kconfig b/init/Kconfig
|
||||||
index 2de5b1c..a283086 100644
|
index c972899..17483b7 100644
|
||||||
--- a/init/Kconfig
|
--- a/init/Kconfig
|
||||||
+++ b/init/Kconfig
|
+++ b/init/Kconfig
|
||||||
@@ -332,6 +332,15 @@ config AUDIT_TREE
|
@@ -339,6 +339,15 @@ config AUDIT_TREE
|
||||||
depends on AUDITSYSCALL
|
depends on AUDITSYSCALL
|
||||||
select FSNOTIFY
|
select FSNOTIFY
|
||||||
|
|
||||||
@ -1640,7 +1640,7 @@ index 2de5b1c..a283086 100644
|
|||||||
|
|
||||||
menu "RCU Subsystem"
|
menu "RCU Subsystem"
|
||||||
diff --git a/kernel/Makefile b/kernel/Makefile
|
diff --git a/kernel/Makefile b/kernel/Makefile
|
||||||
index 0b72d1a..6004913 100644
|
index 0b5ff08..1172528 100644
|
||||||
--- a/kernel/Makefile
|
--- a/kernel/Makefile
|
||||||
+++ b/kernel/Makefile
|
+++ b/kernel/Makefile
|
||||||
@@ -70,6 +70,7 @@ obj-$(CONFIG_IKCONFIG) += configs.o
|
@@ -70,6 +70,7 @@ obj-$(CONFIG_IKCONFIG) += configs.o
|
||||||
@ -1652,10 +1652,10 @@ index 0b72d1a..6004913 100644
|
|||||||
obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
|
obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
|
||||||
obj-$(CONFIG_AUDIT_WATCH) += audit_watch.o
|
obj-$(CONFIG_AUDIT_WATCH) += audit_watch.o
|
||||||
diff --git a/kernel/fork.c b/kernel/fork.c
|
diff --git a/kernel/fork.c b/kernel/fork.c
|
||||||
index 98b4508..3ceff6f 100644
|
index 5447dc7..10a39fe 100644
|
||||||
--- a/kernel/fork.c
|
--- a/kernel/fork.c
|
||||||
+++ b/kernel/fork.c
|
+++ b/kernel/fork.c
|
||||||
@@ -161,6 +161,7 @@ void free_task(struct task_struct *tsk)
|
@@ -162,6 +162,7 @@ void free_task(struct task_struct *tsk)
|
||||||
free_thread_info(tsk->stack);
|
free_thread_info(tsk->stack);
|
||||||
rt_mutex_debug_task_free(tsk);
|
rt_mutex_debug_task_free(tsk);
|
||||||
ftrace_graph_exit_task(tsk);
|
ftrace_graph_exit_task(tsk);
|
||||||
@ -1663,7 +1663,7 @@ index 98b4508..3ceff6f 100644
|
|||||||
free_task_struct(tsk);
|
free_task_struct(tsk);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(free_task);
|
EXPORT_SYMBOL(free_task);
|
||||||
@@ -1008,6 +1009,8 @@ static struct task_struct *copy_process(
|
@@ -1018,6 +1019,8 @@ static struct task_struct *copy_process(
|
||||||
if (!p)
|
if (!p)
|
||||||
goto fork_out;
|
goto fork_out;
|
||||||
|
|
||||||
@ -1673,7 +1673,7 @@ index 98b4508..3ceff6f 100644
|
|||||||
|
|
||||||
rt_mutex_init_task(p);
|
rt_mutex_init_task(p);
|
||||||
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
|
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
|
||||||
index 8049cb5..23bde94 100644
|
index 84d9f8f..e275608 100644
|
||||||
--- a/kernel/ptrace.c
|
--- a/kernel/ptrace.c
|
||||||
+++ b/kernel/ptrace.c
|
+++ b/kernel/ptrace.c
|
||||||
@@ -15,6 +15,7 @@
|
@@ -15,6 +15,7 @@
|
||||||
@ -1720,10 +1720,10 @@ index 8049cb5..23bde94 100644
|
|||||||
if (!current->ptrace) {
|
if (!current->ptrace) {
|
||||||
diff --git a/kernel/utrace.c b/kernel/utrace.c
|
diff --git a/kernel/utrace.c b/kernel/utrace.c
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index ...43f38b7 100644
|
index ...26d6faf 100644
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/kernel/utrace.c
|
+++ b/kernel/utrace.c
|
||||||
@@ -0,0 +1,2434 @@
|
@@ -0,0 +1,2440 @@
|
||||||
+/*
|
+/*
|
||||||
+ * utrace infrastructure interface for debugging user processes
|
+ * utrace infrastructure interface for debugging user processes
|
||||||
+ *
|
+ *
|
||||||
@ -2440,8 +2440,15 @@ index ...43f38b7 100644
|
|||||||
+ /*
|
+ /*
|
||||||
+ * If no more engines want it stopped, wake it up.
|
+ * If no more engines want it stopped, wake it up.
|
||||||
+ */
|
+ */
|
||||||
+ if (task_is_traced(task) && !(flags & ENGINE_STOP))
|
+ if (task_is_traced(task) && !(flags & ENGINE_STOP)) {
|
||||||
|
+ /*
|
||||||
|
+ * It just resumes, so make sure single-step
|
||||||
|
+ * is not left set.
|
||||||
|
+ */
|
||||||
|
+ if (utrace->resume == UTRACE_RESUME)
|
||||||
|
+ user_disable_single_step(task);
|
||||||
+ utrace_wakeup(task, utrace);
|
+ utrace_wakeup(task, utrace);
|
||||||
|
+ }
|
||||||
+
|
+
|
||||||
+ /*
|
+ /*
|
||||||
+ * In theory spin_lock() doesn't imply rcu_read_lock().
|
+ * In theory spin_lock() doesn't imply rcu_read_lock().
|
||||||
@ -2865,14 +2872,7 @@ index ...43f38b7 100644
|
|||||||
+ break;
|
+ break;
|
||||||
+
|
+
|
||||||
+ case UTRACE_RESUME:
|
+ case UTRACE_RESUME:
|
||||||
+ /*
|
|
||||||
+ * This and all other cases imply resuming if stopped.
|
|
||||||
+ * There might not be another report before it just
|
|
||||||
+ * resumes, so make sure single-step is not left set.
|
|
||||||
+ */
|
|
||||||
+ clear_engine_wants_stop(engine);
|
+ clear_engine_wants_stop(engine);
|
||||||
+ if (likely(reset))
|
|
||||||
+ user_disable_single_step(target);
|
|
||||||
+ break;
|
+ break;
|
||||||
+
|
+
|
||||||
+ case UTRACE_BLOCKSTEP:
|
+ case UTRACE_BLOCKSTEP:
|
||||||
@ -3238,6 +3238,12 @@ index ...43f38b7 100644
|
|||||||
+ engine, event)))
|
+ engine, event)))
|
||||||
+ return NULL;
|
+ return NULL;
|
||||||
+
|
+
|
||||||
|
+ if (!event) {
|
||||||
|
+ /* We only got here to report QUIESCE */
|
||||||
|
+ report->spurious = false;
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
+ /*
|
+ /*
|
||||||
+ * finish_callback() reset utrace->reporting after the
|
+ * finish_callback() reset utrace->reporting after the
|
||||||
+ * quiesce callback. Now we set it again (as above)
|
+ * quiesce callback. Now we set it again (as above)
|
||||||
@ -3253,7 +3259,7 @@ index ...43f38b7 100644
|
|||||||
+ if (want & ENGINE_STOP)
|
+ if (want & ENGINE_STOP)
|
||||||
+ report->action = UTRACE_STOP;
|
+ report->action = UTRACE_STOP;
|
||||||
+
|
+
|
||||||
+ if (want & (event ?: UTRACE_EVENT(QUIESCE))) {
|
+ if (want & event) {
|
||||||
+ report->spurious = false;
|
+ report->spurious = false;
|
||||||
+ return ops;
|
+ return ops;
|
||||||
+ }
|
+ }
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
utrace_base=2.6-current
|
utrace_base=2.6.37
|
||||||
|
|
||||||
url=http://people.redhat.com/roland/utrace/${1:-$utrace_base}
|
url=http://people.redhat.com/roland/utrace/${1:-$utrace_base}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user