rpms/kernel/devel kernel.spec, 1.2001, 1.2002 linux-2.6-utrace-ptrace.patch, 1.4, 1.5
roland
roland at fedoraproject.org
Sat May 22 00:53:20 UTC 2010
Author: roland
Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs01.phx2.fedoraproject.org:/tmp/cvs-serv19389
Modified Files:
kernel.spec linux-2.6-utrace-ptrace.patch
Log Message:
this time, with feeling
Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.2001
retrieving revision 1.2002
diff -u -p -r1.2001 -r1.2002
--- kernel.spec 21 May 2010 22:43:56 -0000 1.2001
+++ kernel.spec 22 May 2010 00:53:19 -0000 1.2002
@@ -2034,7 +2034,7 @@ fi
# || ||
%changelog
-* Fri May 21 2010 Roland McGrath <roland at redhat.com> 2.6.34-10
+* Fri May 21 2010 Roland McGrath <roland at redhat.com> 2.6.34-11
- utrace update
* Fri May 21 2010 Dave Jones <davej at redhat.com>
linux-2.6-utrace-ptrace.patch:
include/linux/ptrace.h | 2
kernel/Makefile | 1
kernel/ptrace-utrace.c | 1127 +++++++++++++++++++++++++++++++++++++++++++++++++
kernel/ptrace.c | 695 ++++++++++++++----------------
kernel/utrace.c | 16
5 files changed, 1487 insertions(+), 354 deletions(-)
Index: linux-2.6-utrace-ptrace.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6-utrace-ptrace.patch,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -p -r1.4 -r1.5
--- linux-2.6-utrace-ptrace.patch 21 May 2010 22:43:56 -0000 1.4
+++ linux-2.6-utrace-ptrace.patch 22 May 2010 00:53:20 -0000 1.5
@@ -15,9 +15,9 @@ Signed-off-by: Oleg Nesterov <oleg at redha
include/linux/ptrace.h | 2 +-
kernel/Makefile | 1 +
kernel/ptrace-utrace.c | 1127 ++++++++++++++++++++++++++++++++++++++++++++++++
- kernel/ptrace.c | 576 ++++++++++++-------------
+ kernel/ptrace.c | 654 ++++++++++++++--------------
kernel/utrace.c | 16 +
- 5 files changed, 1427 insertions(+), 295 deletions(-)
+ 5 files changed, 1466 insertions(+), 334 deletions(-)
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index 0d84f1e..102cb0f 100644
@@ -1178,7 +1178,7 @@ index ...86234ee 100644
+}
+#endif /* CONFIG_COMPAT */
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
-index 0ad4dc0..deae114 100644
+index 0ad4dc0..448b353 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -16,7 +16,6 @@
@@ -1189,7 +1189,7 @@ index 0ad4dc0..deae114 100644
#include <linux/security.h>
#include <linux/signal.h>
#include <linux/audit.h>
-@@ -25,7 +24,286 @@
+@@ -25,7 +24,327 @@
#include <linux/uaccess.h>
#include <linux/regset.h>
@@ -1341,6 +1341,47 @@ index 0ad4dc0..deae114 100644
+ return copied;
+}
+
++#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
++
++static const struct user_regset *
++find_regset(const struct user_regset_view *view, unsigned int type)
++{
++ const struct user_regset *regset;
++ int n;
++
++ for (n = 0; n < view->n; ++n) {
++ regset = view->regsets + n;
++ if (regset->core_note_type == type)
++ return regset;
++ }
++
++ return NULL;
++}
++
++int ptrace_regset(struct task_struct *task, int req, unsigned int type,
++ struct iovec *kiov)
++{
++ const struct user_regset_view *view = task_user_regset_view(task);
++ const struct user_regset *regset = find_regset(view, type);
++ int regset_no;
++
++ if (!regset || (kiov->iov_len % regset->size) != 0)
++ return -EINVAL;
++
++ regset_no = regset - view->regsets;
++ kiov->iov_len = min(kiov->iov_len,
++ (__kernel_size_t) (regset->n * regset->size));
++
++ if (req == PTRACE_GETREGSET)
++ return copy_regset_to_user(task, view, regset_no, 0,
++ kiov->iov_len, kiov->iov_base);
++ else
++ return copy_regset_from_user(task, view, regset_no, 0,
++ kiov->iov_len, kiov->iov_base);
++}
++
++#endif
++
+static struct task_struct *ptrace_get_task_struct(pid_t pid)
+{
+ struct task_struct *child;
@@ -1359,7 +1400,7 @@ index 0ad4dc0..deae114 100644
+#ifndef arch_ptrace_attach
+#define arch_ptrace_attach(child) do { } while (0)
+#endif
-
++
+SYSCALL_DEFINE4(ptrace, long, request, long, pid, long, addr, long, data)
+{
+ struct task_struct *child;
@@ -1405,7 +1446,7 @@ index 0ad4dc0..deae114 100644
+ unlock_kernel();
+ return ret;
+}
-+
+
+int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data)
+{
+ unsigned long tmp;
@@ -1476,27 +1517,10 @@ index 0ad4dc0..deae114 100644
/*
* ptrace a task: make the debugger its new parent and
* move it to the ptrace list.
-@@ -102,76 +380,21 @@ int ptrace_check_attach(struct task_stru
- /*
- * child->sighand can't be NULL, release_task()
- * does ptrace_unlink() before __exit_signal().
-- */
-- spin_lock_irq(&child->sighand->siglock);
-- if (task_is_stopped(child))
-- child->state = TASK_TRACED;
-- else if (!task_is_traced(child) && !kill)
-- ret = -ESRCH;
-- spin_unlock_irq(&child->sighand->siglock);
-- }
-- read_unlock(&tasklist_lock);
--
-- if (!ret && !kill)
-- ret = wait_task_inactive(child, TASK_TRACED) ? 0 : -ESRCH;
--
-- /* All systems go.. */
-- return ret;
--}
--
+@@ -119,61 +438,6 @@ int ptrace_check_attach(struct task_stru
+ return ret;
+ }
+
-int __ptrace_may_access(struct task_struct *task, unsigned int mode)
-{
- const struct cred *cred = current_cred(), *tcred;
@@ -1534,16 +1558,7 @@ index 0ad4dc0..deae114 100644
-
- return security_ptrace_access_check(task, mode);
-}
-+ */
-+ spin_lock_irq(&child->sighand->siglock);
-+ if (task_is_stopped(child))
-+ child->state = TASK_TRACED;
-+ else if (!task_is_traced(child) && !kill)
-+ ret = -ESRCH;
-+ spin_unlock_irq(&child->sighand->siglock);
-+ }
-+ read_unlock(&tasklist_lock);
-
+-
-bool ptrace_may_access(struct task_struct *task, unsigned int mode)
-{
- int err;
@@ -1552,21 +1567,19 @@ index 0ad4dc0..deae114 100644
- task_unlock(task);
- return !err;
-}
-+ if (!ret && !kill)
-+ ret = wait_task_inactive(child, TASK_TRACED) ? 0 : -ESRCH;
-
+-
-/*
- * For experimental use of utrace, exclude ptrace on the same task.
- */
-static inline bool exclude_ptrace(struct task_struct *task)
-{
- return unlikely(!!task_utrace_flags(task));
-+ /* All systems go.. */
-+ return ret;
- }
-
+-}
+-
int ptrace_attach(struct task_struct *task)
-@@ -197,8 +420,6 @@ int ptrace_attach(struct task_struct *ta
+ {
+ int retval;
+@@ -197,8 +461,6 @@ int ptrace_attach(struct task_struct *ta
task_lock(task);
retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH);
@@ -1575,20 +1588,42 @@ index 0ad4dc0..deae114 100644
task_unlock(task);
if (retval)
goto unlock_creds;
-@@ -236,9 +457,6 @@ int ptrace_traceme(void)
- {
- int ret = -EPERM;
+@@ -226,87 +488,33 @@ out:
+ return retval;
+ }
+-/**
+- * ptrace_traceme -- helper for PTRACE_TRACEME
+- *
+- * Performs checks and sets PT_PTRACED.
+- * Should be used by all ptrace implementations for PTRACE_TRACEME.
+- */
+-int ptrace_traceme(void)
+-{
+- int ret = -EPERM;
+-
- if (exclude_ptrace(current)) /* XXX locking */
- return -EBUSY;
-
- write_lock_irq(&tasklist_lock);
- /* Are we already being traced? */
- if (!current->ptrace) {
-@@ -258,57 +476,6 @@ int ptrace_traceme(void)
- return ret;
- }
-
+- write_lock_irq(&tasklist_lock);
+- /* Are we already being traced? */
+- if (!current->ptrace) {
+- ret = security_ptrace_traceme(current->parent);
+- /*
+- * Check PF_EXITING to ensure ->real_parent has not passed
+- * exit_ptrace(). Otherwise we don't report the error but
+- * pretend ->real_parent untraces us right after return.
+- */
+- if (!ret && !(current->real_parent->flags & PF_EXITING)) {
+- current->ptrace = PT_PTRACED;
+- __ptrace_link(current, current->real_parent);
+- }
+- }
+- write_unlock_irq(&tasklist_lock);
+-
+- return ret;
+-}
+-
-/*
- * Called with irqs disabled, returns true if childs should reap themselves.
- */
@@ -1616,11 +1651,18 @@ index 0ad4dc0..deae114 100644
- * children self-reap, then this child was prevented by ptrace and we must
- * reap it now, in that case we must also wake up sub-threads sleeping in
- * do_wait().
-- */
++/**
++ * ptrace_traceme -- helper for PTRACE_TRACEME
++ *
++ * Performs checks and sets PT_PTRACED.
++ * Should be used by all ptrace implementations for PTRACE_TRACEME.
+ */
-bool __ptrace_detach(struct task_struct *tracer, struct task_struct *p)
--{
++int ptrace_traceme(void)
+ {
- __ptrace_unlink(p);
--
++ int ret = -EPERM;
+
- if (p->exit_state == EXIT_ZOMBIE) {
- if (!task_detached(p) && thread_group_empty(p)) {
- if (!same_thread_group(p->real_parent, tracer))
@@ -1634,16 +1676,28 @@ index 0ad4dc0..deae114 100644
- /* Mark it as in the process of being reaped. */
- p->exit_state = EXIT_DEAD;
- return true;
-- }
-- }
--
++ write_lock_irq(&tasklist_lock);
++ /* Are we already being traced? */
++ if (!current->ptrace) {
++ ret = security_ptrace_traceme(current->parent);
++ /*
++ * Check PF_EXITING to ensure ->real_parent has not passed
++ * exit_ptrace(). Otherwise we don't report the error but
++ * pretend ->real_parent untraces us right after return.
++ */
++ if (!ret && !(current->real_parent->flags & PF_EXITING)) {
++ current->ptrace = PT_PTRACED;
++ __ptrace_link(current, current->real_parent);
+ }
+ }
++ write_unlock_irq(&tasklist_lock);
+
- return false;
--}
--
++ return ret;
+ }
+
int ptrace_detach(struct task_struct *child, unsigned int data)
- {
- bool dead = false;
-@@ -362,56 +529,6 @@ void exit_ptrace(struct task_struct *tra
+@@ -362,56 +570,6 @@ void exit_ptrace(struct task_struct *tra
}
}
@@ -1700,17 +1754,54 @@ index 0ad4dc0..deae114 100644
static int ptrace_setoptions(struct task_struct *child, long data)
{
child->ptrace &= ~PT_TRACE_MASK;
-@@ -543,8 +659,8 @@ find_regset(const struct user_regset_vie
- return NULL;
+@@ -526,47 +683,6 @@ static int ptrace_resume(struct task_str
+ return 0;
}
+-#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
+-
+-static const struct user_regset *
+-find_regset(const struct user_regset_view *view, unsigned int type)
+-{
+- const struct user_regset *regset;
+- int n;
+-
+- for (n = 0; n < view->n; ++n) {
+- regset = view->regsets + n;
+- if (regset->core_note_type == type)
+- return regset;
+- }
+-
+- return NULL;
+-}
+-
-static int ptrace_regset(struct task_struct *task, int req, unsigned int type,
- struct iovec *kiov)
-+int ptrace_regset(struct task_struct *task, int req, unsigned int type,
-+ struct iovec *kiov)
+-{
+- const struct user_regset_view *view = task_user_regset_view(task);
+- const struct user_regset *regset = find_regset(view, type);
+- int regset_no;
+-
+- if (!regset || (kiov->iov_len % regset->size) != 0)
+- return -EINVAL;
+-
+- regset_no = regset - view->regsets;
+- kiov->iov_len = min(kiov->iov_len,
+- (__kernel_size_t) (regset->n * regset->size));
+-
+- if (req == PTRACE_GETREGSET)
+- return copy_regset_to_user(task, view, regset_no, 0,
+- kiov->iov_len, kiov->iov_base);
+- else
+- return copy_regset_from_user(task, view, regset_no, 0,
+- kiov->iov_len, kiov->iov_base);
+-}
+-
+-#endif
+-
+ int ptrace_request(struct task_struct *child, long request,
+ long addr, long data)
{
- const struct user_regset_view *view = task_user_regset_view(task);
- const struct user_regset *regset = find_regset(view, type);
@@ -656,93 +772,7 @@ int ptrace_request(struct task_struct *c
return ret;
}
More information about the scm-commits
mailing list