rpms/kernel/devel kernel-2.6.spec, 1.2979, 1.2980 linux-2.6-utrace.patch, 1.52, 1.53
fedora-cvs-commits at redhat.com
fedora-cvs-commits at redhat.com
Thu Mar 8 23:45:40 UTC 2007
- Previous message (by thread): rpms/anaconda/devel .cvsignore, 1.385, 1.386 anaconda.spec, 1.512, 1.513 sources, 1.509, 1.510
- Next message (by thread): rpms/kernel/devel kernel-2.6.spec, 1.2980, 1.2981 linux-2.6-squashfs.patch, 1.18, 1.19
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: davej
Update of /cvs/dist/rpms/kernel/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv16033
Modified Files:
kernel-2.6.spec linux-2.6-utrace.patch
Log Message:
* Thu Mar 08 2007 Dave Jones <davej at redhat.com>
- update to latest utrace.
Index: kernel-2.6.spec
===================================================================
RCS file: /cvs/dist/rpms/kernel/devel/kernel-2.6.spec,v
retrieving revision 1.2979
retrieving revision 1.2980
diff -u -r1.2979 -r1.2980
--- kernel-2.6.spec 8 Mar 2007 23:01:15 -0000 1.2979
+++ kernel-2.6.spec 8 Mar 2007 23:45:38 -0000 1.2980
@@ -2071,6 +2071,9 @@
# - tux.
%changelog
+* Thu Mar 08 2007 Dave Jones <davej at redhat.com>
+- update to latest utrace.
+
* Thu Mar 08 2007 John W. Linville <linville at redhat.com>
- update git-wireless-dev.patch (current as of 2007-03-06)
linux-2.6-utrace.patch:
Documentation/utrace.txt | 579 +++++++++++
arch/alpha/kernel/asm-offsets.c | 2
arch/alpha/kernel/entry.S | 4
arch/arm/kernel/ptrace.c | 36
arch/arm26/kernel/ptrace.c | 32
arch/frv/kernel/ptrace.c | 15
arch/i386/kernel/entry.S | 7
arch/i386/kernel/i387.c | 143 +-
arch/i386/kernel/process.c | 3
arch/i386/kernel/ptrace.c | 863 ++++++++--------
arch/i386/kernel/signal.c | 37
arch/i386/kernel/vm86.c | 7
arch/i386/math-emu/fpu_entry.c | 6
arch/ia64/ia32/ia32_entry.S | 2
arch/ia64/ia32/sys_ia32.c | 536 +++++++++-
arch/ia64/kernel/asm-offsets.c | 2
arch/ia64/kernel/fsys.S | 16
arch/ia64/kernel/mca.c | 2
arch/ia64/kernel/ptrace.c | 1700 ++++++++++++++++----------------
arch/ia64/kernel/signal.c | 4
arch/mips/kernel/ptrace.c | 21
arch/mips/kernel/sysirix.c | 2
arch/powerpc/kernel/Makefile | 4
arch/powerpc/kernel/asm-offsets.c | 2
arch/powerpc/kernel/process.c | 5
arch/powerpc/kernel/ptrace-common.h | 161 ---
arch/powerpc/kernel/ptrace.c | 957 ++++++++++--------
arch/powerpc/kernel/ptrace32.c | 436 --------
arch/powerpc/kernel/signal_32.c | 55 +
arch/powerpc/kernel/signal_64.c | 3
arch/powerpc/kernel/sys_ppc32.c | 5
arch/powerpc/lib/sstep.c | 3
arch/ppc/kernel/asm-offsets.c | 2
arch/s390/kernel/Makefile | 2
arch/s390/kernel/compat_linux.c | 3
arch/s390/kernel/compat_signal.c | 5
arch/s390/kernel/compat_wrapper.S | 2
arch/s390/kernel/process.c | 3
arch/s390/kernel/ptrace.c | 1118 ++++++++++-----------
arch/s390/kernel/signal.c | 3
arch/s390/kernel/traps.c | 6
arch/sparc64/kernel/Makefile | 2
arch/sparc64/kernel/binfmt_aout32.c | 2
arch/sparc64/kernel/entry.S | 6
arch/sparc64/kernel/process.c | 3
arch/sparc64/kernel/ptrace.c | 1222 ++++++++++++-----------
arch/sparc64/kernel/signal.c | 2
arch/sparc64/kernel/signal32.c | 2
arch/sparc64/kernel/sys_sparc32.c | 3
arch/sparc64/kernel/systbls.S | 4
arch/x86_64/ia32/fpu32.c | 92 +
arch/x86_64/ia32/ia32_aout.c | 6
arch/x86_64/ia32/ia32_signal.c | 7
arch/x86_64/ia32/ia32entry.S | 2
arch/x86_64/ia32/ptrace32.c | 724 +++++++++----
arch/x86_64/ia32/sys_ia32.c | 5
arch/x86_64/kernel/process.c | 5
arch/x86_64/kernel/ptrace.c | 662 +++++++-----
arch/x86_64/kernel/signal.c | 28
arch/x86_64/kernel/traps.c | 8
arch/x86_64/mm/fault.c | 4
drivers/connector/cn_proc.c | 4
fs/binfmt_aout.c | 6
fs/binfmt_elf.c | 6
fs/binfmt_elf_fdpic.c | 7
fs/binfmt_flat.c | 3
fs/binfmt_som.c | 2
fs/exec.c | 11
fs/proc/array.c | 12
fs/proc/base.c | 57 -
include/asm-i386/i387.h | 13
include/asm-i386/signal.h | 4
include/asm-i386/thread_info.h | 7
include/asm-i386/tracehook.h | 57 +
include/asm-ia64/elf.h | 24
include/asm-ia64/tracehook.h | 89 +
include/asm-powerpc/tracehook.h | 88 +
include/asm-s390/tracehook.h | 61 +
include/asm-sparc64/tracehook.h | 52
include/asm-x86_64/fpu32.h | 3
include/asm-x86_64/thread_info.h | 3
include/asm-x86_64/tracehook.h | 61 +
include/linux/init_task.h | 3
include/linux/ptrace.h | 236 +++-
include/linux/sched.h | 25
include/linux/tracehook.h | 715 +++++++++++++
include/linux/utrace.h | 510 +++++++++
init/Kconfig | 29
kernel/Makefile | 4
kernel/exit.c | 238 +---
kernel/fork.c | 61 -
kernel/ptrace.c | 1773 +++++++++++++++++++++++++++------
kernel/signal.c | 211 ----
kernel/sys.c | 2
kernel/sys_ni.c | 4
kernel/timer.c | 6
kernel/tsacct.c | 2
kernel/utrace.c | 1892 ++++++++++++++++++++++++++++++++++++
security/selinux/hooks.c | 54 -
security/selinux/include/objsec.h | 1
100 files changed, 10830 insertions(+), 5089 deletions(-)
Index: linux-2.6-utrace.patch
===================================================================
RCS file: /cvs/dist/rpms/kernel/devel/linux-2.6-utrace.patch,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -r1.52 -r1.53
--- linux-2.6-utrace.patch 18 Feb 2007 02:52:58 -0000 1.52
+++ linux-2.6-utrace.patch 8 Mar 2007 23:45:38 -0000 1.53
@@ -565,7 +565,7 @@
+#endif
--- linux-2.6/include/linux/sched.h
+++ linux-2.6/include/linux/sched.h
-@@ -803,7 +803,6 @@ struct task_struct {
+@@ -802,7 +802,6 @@ struct task_struct {
struct thread_info *thread_info;
atomic_t usage;
unsigned long flags; /* per process flags, defined below */
@@ -573,7 +573,7 @@
int lock_depth; /* BKL lock depth */
-@@ -835,12 +834,6 @@ struct task_struct {
+@@ -834,12 +833,6 @@ struct task_struct {
#endif
struct list_head tasks;
@@ -586,7 +586,7 @@
struct mm_struct *mm, *active_mm;
-@@ -860,15 +853,13 @@ struct task_struct {
+@@ -859,15 +852,13 @@ struct task_struct {
unsigned long stack_canary;
#endif
/*
@@ -604,7 +604,7 @@
*/
struct list_head children; /* list of my children */
struct list_head sibling; /* linkage in my parent's children list */
-@@ -951,6 +942,11 @@ struct task_struct {
+@@ -950,6 +941,11 @@ struct task_struct {
struct audit_context *audit_context;
seccomp_t seccomp;
@@ -616,7 +616,7 @@
/* Thread group tracking */
u32 parent_exec_id;
u32 self_exec_id;
-@@ -1004,8 +1000,6 @@ struct task_struct {
+@@ -1003,8 +999,6 @@ struct task_struct {
struct io_context *io_context;
@@ -625,7 +625,7 @@
/*
* current io wait handle: wait queue entry to use for io waits
* If this thread is processing aio, this points at the waitqueue
-@@ -1043,6 +1037,10 @@ struct task_struct {
+@@ -1042,6 +1036,10 @@ struct task_struct {
atomic_t fs_excl; /* holding fs exclusive resources */
struct rcu_head rcu;
@@ -636,9 +636,9 @@
/*
* cache last used pipe for splice
*/
-@@ -1330,6 +1328,7 @@ extern int kill_pid_info_as_uid(int, str
- extern int kill_pgrp(struct pid *pid, int sig, int priv);
+@@ -1330,6 +1328,7 @@ extern int kill_pgrp(struct pid *pid, in
extern int kill_pid(struct pid *pid, int sig, int priv);
+ extern int kill_proc_info(int, struct siginfo *, pid_t);
extern void do_notify_parent(struct task_struct *, int);
+extern void do_notify_parent_cldstop(struct task_struct *, int);
extern void force_sig(int, struct task_struct *);
@@ -1159,12 +1159,13 @@
+#endif /* linux/utrace.h */
--- linux-2.6/include/linux/ptrace.h
+++ linux-2.6/include/linux/ptrace.h
-@@ -49,66 +49,195 @@
+@@ -49,66 +49,196 @@
#include <asm/ptrace.h>
#ifdef __KERNEL__
+#include <linux/compiler.h>
+#include <linux/types.h>
++#include <linux/errno.h>
+struct task_struct;
+struct siginfo;
+struct rusage;
@@ -3068,7 +3069,7 @@
/*
* This signal will be fatal to the whole group.
*/
-@@ -1484,8 +1481,7 @@ void do_notify_parent(struct task_struct
+@@ -1485,8 +1482,7 @@ void do_notify_parent(struct task_struct
/* do_notify_parent_cldstop should have been called instead. */
BUG_ON(tsk->state & (TASK_STOPPED|TASK_TRACED));
@@ -3078,7 +3079,7 @@
info.si_signo = sig;
info.si_errno = 0;
-@@ -1510,7 +1506,7 @@ void do_notify_parent(struct task_struct
+@@ -1511,7 +1507,7 @@ void do_notify_parent(struct task_struct
psig = tsk->parent->sighand;
spin_lock_irqsave(&psig->siglock, flags);
@@ -3087,7 +3088,7 @@
(psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN ||
(psig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT))) {
/*
-@@ -1538,20 +1534,13 @@ void do_notify_parent(struct task_struct
+@@ -1539,20 +1535,13 @@ void do_notify_parent(struct task_struct
spin_unlock_irqrestore(&psig->siglock, flags);
}
@@ -3109,7 +3110,7 @@
info.si_signo = SIGCHLD;
info.si_errno = 0;
info.si_pid = tsk->pid;
-@@ -1576,6 +1565,15 @@ static void do_notify_parent_cldstop(str
+@@ -1577,6 +1566,15 @@ static void do_notify_parent_cldstop(str
BUG();
}
@@ -3125,7 +3126,7 @@
sighand = parent->sighand;
spin_lock_irqsave(&sighand->siglock, flags);
if (sighand->action[SIGCHLD-1].sa.sa_handler != SIG_IGN &&
-@@ -1588,110 +1586,6 @@ static void do_notify_parent_cldstop(str
+@@ -1589,110 +1587,6 @@ static void do_notify_parent_cldstop(str
spin_unlock_irqrestore(&sighand->siglock, flags);
}
@@ -3236,7 +3237,7 @@
static void
finish_stop(int stop_count)
{
-@@ -1700,7 +1594,7 @@ finish_stop(int stop_count)
+@@ -1701,7 +1595,7 @@ finish_stop(int stop_count)
* a group stop in progress and we are the last to stop,
* report to the parent. When ptraced, every thread reports itself.
*/
@@ -3245,7 +3246,7 @@
read_lock(&tasklist_lock);
do_notify_parent_cldstop(current, CLD_STOPPED);
read_unlock(&tasklist_lock);
-@@ -1827,44 +1721,24 @@ relock:
+@@ -1828,44 +1722,24 @@ relock:
handle_group_stop())
goto relock;
@@ -3306,7 +3307,7 @@
if (ka->sa.sa_handler == SIG_IGN) /* Do nothing. */
continue;
if (ka->sa.sa_handler != SIG_DFL) {
-@@ -1913,7 +1787,7 @@ relock:
+@@ -1914,7 +1788,7 @@ relock:
spin_lock_irq(¤t->sighand->siglock);
}
@@ -3315,7 +3316,7 @@
/* It released the siglock. */
goto relock;
}
-@@ -1940,13 +1814,13 @@ relock:
+@@ -1941,13 +1815,13 @@ relock:
* first and our do_group_exit call below will use
* that value and ignore the one we pass it.
*/
@@ -3331,7 +3332,7 @@
/* NOTREACHED */
}
spin_unlock_irq(¤t->sighand->siglock);
-@@ -1958,7 +1832,6 @@ EXPORT_SYMBOL_GPL(dequeue_signal);
+@@ -1959,7 +1833,6 @@ EXPORT_SYMBOL_GPL(dequeue_signal);
EXPORT_SYMBOL(flush_signals);
EXPORT_SYMBOL(force_sig);
EXPORT_SYMBOL(kill_proc);
@@ -3365,7 +3366,7 @@
cond_syscall(sys_pciconfig_write);
--- linux-2.6/kernel/utrace.c
+++ linux-2.6/kernel/utrace.c
-@@ -0,0 +1,1871 @@
+@@ -0,0 +1,1892 @@
+/*
+ * utrace infrastructure interface for debugging user processes
+ *
@@ -3570,17 +3571,23 @@
+ */
+ if (((tsk->utrace_flags &~ flags) & UTRACE_ACTION_NOREAP)
+ && tsk->exit_state) {
-+ BUG_ON(tsk->exit_state != EXIT_ZOMBIE);
+ /*
+ * While holding the utrace lock, mark that it's been done.
+ * For self-reaping, we need to change tsk->exit_state
+ * before clearing tsk->utrace_flags, so that the real
-+ * parent can't see it in EXIT_ZOMBIE momentarily and reap it.
++ * parent can't see it in EXIT_ZOMBIE momentarily and reap
++ * it. If tsk was the group_leader, an exec by another
++ * thread can release_task it despite our NOREAP. Holding
++ * tasklist_lock for reading excludes de_thread until we
++ * decide what to do.
+ */
-+ if (tsk->exit_signal == -1) {
++ read_lock(&tasklist_lock);
++ if (tsk->exit_signal == -1) { /* Self-reaping thread. */
+ exit_state = xchg(&tsk->exit_state, EXIT_DEAD);
++ read_unlock(&tasklist_lock);
++
+ BUG_ON(exit_state != EXIT_ZOMBIE);
-+ exit_state = EXIT_DEAD;
++ exit_state = EXIT_DEAD; /* Reap it below. */
+
+ /*
+ * Now that we've changed its state to DEAD,
@@ -3588,7 +3595,7 @@
+ * value without the UTRACE_ACTION_NOREAP bit set.
+ */
+ }
-+ else if (thread_group_empty(tsk)) {
++ else if (thread_group_empty(tsk)) /* Normal solo zombie. */
+ /*
+ * We need to prevent the real parent from reaping
+ * until after we've called do_notify_parent, below.
@@ -3601,32 +3608,47 @@
+ * everything we need to do.
+ */
+ exit_state = EXIT_ZOMBIE;
-+ read_lock(&tasklist_lock);
-+ }
++ else
++ /*
++ * Delayed group leader, nothing to do yet.
++ * This is also the situation with the old
++ * group leader in an exec by another thread,
++ * which will call release_task itself.
++ */
++ read_unlock(&tasklist_lock);
++
+ }
+
+ tsk->utrace_flags = flags;
+ if (flags)
+ spin_unlock(&utrace->lock);
-+ else {
++ else
+ rcu_utrace_free(utrace);
-+ utrace = NULL;
-+ }
+
+ /*
+ * Now we're finished updating the utrace state.
+ * Do a pending self-reaping or parent notification.
+ */
++ if (exit_state == EXIT_ZOMBIE) {
++ do_notify_parent(tsk, tsk->exit_signal);
++
++ /*
++ * If SIGCHLD was ignored, that set tsk->exit_signal = -1
++ * to tell us to reap it immediately.
++ */
++ if (tsk->exit_signal == -1) {
++ exit_state = xchg(&tsk->exit_state, EXIT_DEAD);
++ BUG_ON(exit_state != EXIT_ZOMBIE);
++ exit_state = EXIT_DEAD; /* Reap it below. */
++ }
++ read_unlock(&tasklist_lock); /* See comment above. */
++ }
+ if (exit_state == EXIT_DEAD)
+ /*
+ * Note this can wind up in utrace_reap and do more callbacks.
+ * Our callers must be in places where that is OK.
+ */
+ release_task(tsk);
-+ else if (exit_state == EXIT_ZOMBIE) {
-+ do_notify_parent(tsk, tsk->exit_signal);
-+ read_unlock(&tasklist_lock); /* See comment above. */
-+ }
+}
+
+
@@ -3700,12 +3722,19 @@
+ rcu_read_lock();
+ utrace = rcu_dereference(target->utrace);
+ smp_rmb();
++ if (unlikely(target->exit_state == EXIT_DEAD)) {
++ /*
++ * The target has already been reaped.
++ * Check this first; a race with reaping may lead to restart.
++ */
++ rcu_read_unlock();
++ return ERR_PTR(-ESRCH);
++ }
+ if (utrace == NULL) {
+ rcu_read_unlock();
+
-+ if (!(flags & UTRACE_ATTACH_CREATE)) {
++ if (!(flags & UTRACE_ATTACH_CREATE))
+ return ERR_PTR(-ENOENT);
-+ }
+
+ engine = kmem_cache_alloc(utrace_engine_cachep, GFP_KERNEL);
+ if (unlikely(engine == NULL))
@@ -3714,19 +3743,12 @@
+
+ first:
+ utrace = utrace_first_engine(target, engine);
-+ if (IS_ERR(utrace)) {
++ if (IS_ERR(utrace) || unlikely(utrace == NULL)) {
+ kmem_cache_free(utrace_engine_cachep, engine);
++ if (unlikely(utrace == NULL)) /* Race condition. */
++ goto restart;
+ return ERR_PTR(PTR_ERR(utrace));
+ }
-+ if (unlikely(utrace == NULL)) /* Race condition. */
-+ goto restart;
-+ }
-+ else if (unlikely(target->exit_state == EXIT_DEAD)) {
-+ /*
-+ * The target has already been reaped.
-+ */
-+ rcu_read_unlock();
-+ return ERR_PTR(-ESRCH);
+ }
+ else {
+ if (!(flags & UTRACE_ATTACH_CREATE)) {
@@ -5725,7 +5747,7 @@
goto out;
--- linux-2.6/kernel/timer.c
+++ linux-2.6/kernel/timer.c
-@@ -1326,9 +1326,9 @@ asmlinkage long sys_getpid(void)
+@@ -1335,9 +1335,9 @@ asmlinkage long sys_getpid(void)
}
/*
@@ -5737,7 +5759,7 @@
* release_task()->call_rcu(delayed_put_task_struct).
*/
asmlinkage long sys_getppid(void)
-@@ -1336,7 +1336,7 @@ asmlinkage long sys_getppid(void)
+@@ -1345,7 +1345,7 @@ asmlinkage long sys_getppid(void)
int pid;
rcu_read_lock();
@@ -5748,7 +5770,7 @@
return pid;
--- linux-2.6/kernel/ptrace.c
+++ linux-2.6/kernel/ptrace.c
-@@ -18,473 +18,1560 @@
+@@ -18,473 +18,1590 @@
#include <linux/ptrace.h>
#include <linux/security.h>
#include <linux/signal.h>
@@ -5871,7 +5893,9 @@
}
+ list_add_rcu(&state->entry, &state->parent->ptracees);
+ task_unlock(state->parent);
-+
+
+- if (child->state == TASK_TRACED)
+- ptrace_untrace(child);
+ BUG_ON(engine->data != 0);
+ rcu_assign_pointer(engine->data, (unsigned long) state);
+
@@ -5885,9 +5909,7 @@
+ struct ptrace_state, u.dead);
+ kfree(state);
+}
-
-- if (child->state == TASK_TRACED)
-- ptrace_untrace(child);
++
+static void
+ptrace_done(struct ptrace_state *state)
+{
@@ -5932,7 +5954,9 @@
- read_unlock(&tasklist_lock);
+ flags |= (UTRACE_EVENT(DEATH) | UTRACE_EVENT(EXEC)
+ | UTRACE_EVENT_SIGNAL_ALL | UTRACE_EVENT(JCTL));
-+
+
+- if (!ret && !kill) {
+- wait_task_inactive(child);
+ /*
+ * We always have to examine clone events to check for CLONE_PTRACE.
+ */
@@ -5951,9 +5975,7 @@
+ * But for a corner case we sometimes see the REAP event anyway.
+ */
+ flags |= UTRACE_ACTION_NOREAP | UTRACE_EVENT(REAP);
-
-- if (!ret && !kill) {
-- wait_task_inactive(child);
++
+ if (!(flags & UTRACE_ACTION_QUIESCE)) {
+ /*
+ * We're letting the thread resume from ptrace stop.
@@ -5968,10 +5990,19 @@
+ state->u.live.u.siginfo = NULL;
+
+ if (target->state == TASK_STOPPED) {
-+ spin_lock_irq(&target->sighand->siglock);
-+ if (target->state == TASK_STOPPED)
-+ target->signal->flags &= ~SIGNAL_STOP_STOPPED;
-+ spin_unlock_irq(&target->sighand->siglock);
++ /*
++ * We have to double-check for naughty de_thread
++ * reaping despite NOREAP, before we can get siglock.
++ */
++ read_lock(&tasklist_lock);
++ if (!target->exit_state) {
++ spin_lock_irq(&target->sighand->siglock);
++ if (target->state == TASK_STOPPED)
++ target->signal->flags &=
++ ~SIGNAL_STOP_STOPPED;
++ spin_unlock_irq(&target->sighand->siglock);
++ }
++ read_unlock(&tasklist_lock);
+ }
}
@@ -6098,7 +6129,8 @@
retval = -EPERM;
if (task->pid <= 1)
- goto out;
-- if (task->tgid == current->tgid)
++ goto bad;
+ if (task->tgid == current->tgid)
- goto out;
-
-repeat:
@@ -6126,20 +6158,11 @@
goto bad;
- /* the same process cannot be attached many times */
- if (task->ptrace & PT_PTRACED)
-+ if (task->tgid == current->tgid)
++ if (!task->mm) /* kernel threads */
goto bad;
- retval = may_attach(task);
- if (retval)
-+ if (!task->mm) /* kernel threads */
- goto bad;
-
-- /* Go */
-- task->ptrace |= PT_PTRACED | ((task->real_parent != current)
-- ? PT_ATTACHED : 0);
-- if (capable(CAP_SYS_PTRACE))
-- task->ptrace |= PT_PTRACE_CAP;
--
-- __ptrace_link(task, current);
++
+ engine = utrace_attach(task, (UTRACE_ATTACH_CREATE
+ | UTRACE_ATTACH_EXCLUSIVE
+ | UTRACE_ATTACH_MATCH_OPS),
@@ -6148,10 +6171,14 @@
+ retval = PTR_ERR(engine);
+ if (retval == -EEXIST)
+ retval = -EPERM;
-+ goto bad;
+ goto bad;
+ }
-- force_sig_specific(SIGSTOP, task);
+- /* Go */
+- task->ptrace |= PT_PTRACED | ((task->real_parent != current)
+- ? PT_ATTACHED : 0);
+- if (capable(CAP_SYS_PTRACE))
+- task->ptrace |= PT_PTRACE_CAP;
+ if (ptrace_may_attach(task)) {
+ state = ptrace_setup(task, engine, current, 0,
+ capable(CAP_SYS_PTRACE), NULL);
@@ -6174,14 +6201,26 @@
+ if (retval)
+ (void) utrace_detach(task, engine);
+ else {
-+ int stopped;
-+
-+ force_sig_specific(SIGSTOP, task);
-+
-+ spin_lock_irq(&task->sighand->siglock);
-+ stopped = (task->state == TASK_STOPPED);
-+ spin_unlock_irq(&task->sighand->siglock);
++ int stopped = 0;
+
+- __ptrace_link(task, current);
++ /*
++ * We must double-check that task has not just died and
++ * been reaped (after ptrace_update succeeded).
++ * This happens when exec (de_thread) ignores NOREAP.
++ * We cannot call into the signal code if it's dead.
++ */
++ read_lock(&tasklist_lock);
++ if (likely(!task->exit_state)) {
++ force_sig_specific(SIGSTOP, task);
+
++ spin_lock_irq(&task->sighand->siglock);
++ stopped = (task->state == TASK_STOPPED);
++ spin_unlock_irq(&task->sighand->siglock);
++ }
++ read_unlock(&tasklist_lock);
+
+- force_sig_specific(SIGSTOP, task);
+ if (stopped) {
+ /*
+ * Do now the regset 0 writeback that we do on every
@@ -6214,8 +6253,19 @@
- /* .. and wake it up. */
- if (child->exit_state != EXIT_ZOMBIE)
- wake_up_process(child);
-+ struct ptrace_state *state = (struct ptrace_state *) engine->data;
-+ int error = utrace_detach(task, engine);
++ struct ptrace_state *state;
++ int error;
++
++#ifdef HAVE_ARCH_PTRACE_DETACH
++ /*
++ * Some funky compatibility code in arch_ptrace may have
++ * needed to install special state it should clean up now.
++ */
++ arch_ptrace_detach(task);
++#endif
++
++ state = (struct ptrace_state *) engine->data;
++ error = utrace_detach(task, engine);
+ if (!error) {
+ /*
+ * We can only get here from the ptracer itself or via
@@ -6239,17 +6289,15 @@
+ spin_unlock_irq(¤t->sighand->siglock);
+ }
+ return error;
- }
-
--int ptrace_detach(struct task_struct *child, unsigned int data)
++}
++
+
+/*
+ * This is called when we are exiting. We must stop all our ptracing.
+ */
+void
+ptrace_exit(struct task_struct *tsk)
- {
-- if (!valid_signal(data))
++{
+ struct list_head *pos, *n;
+
+ /*
@@ -6298,13 +6346,15 @@
+ rcu_read_unlock();
+
+ BUG_ON(!list_empty(&tsk->ptracees));
-+}
-+
+ }
+
+-int ptrace_detach(struct task_struct *child, unsigned int data)
+static int
+ptrace_induce_signal(struct task_struct *target,
+ struct utrace_attached_engine *engine,
+ long signr)
-+{
+ {
+- if (!valid_signal(data))
+ struct ptrace_state *state = (struct ptrace_state *) engine->data;
+
+ if (signr == 0)
@@ -6390,15 +6440,15 @@
+ else
+ ret = (*regset->set)(target, regset,
+ offset, size, NULL, data);
-+ }
+ }
+- return copied;
+ else {
+ if (!access_ok(VERIFY_WRITE, data, size))
+ ret = -EIO;
+ else
+ ret = (*regset->get)(target, regset,
+ offset, size, NULL, data);
- }
-- return copied;
++ }
+
+ return ret;
}
@@ -6416,15 +6466,12 @@
+ view, setno);
+ unsigned int pos;
+ int ret;
-+
-+ if (unlikely(regset == NULL))
-+ return -EIO;
- while (len > 0) {
- char buf[128];
- int this_len, retval;
-+ if (regno < regset->bias || regno >= regset->bias + regset->n)
-+ return -EINVAL;
++ if (unlikely(regset == NULL))
++ return -EIO;
- this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
- if (copy_from_user(buf, src, this_len))
@@ -6439,6 +6486,9 @@
- src += retval;
- dst += retval;
- len -= retval;
++ if (regno < regset->bias || regno >= regset->bias + regset->n)
++ return -EINVAL;
++
+ pos = (regno - regset->bias) * regset->size;
+
+ if (write) {
@@ -6447,15 +6497,15 @@
+ else
+ ret = (*regset->set)(target, regset, pos, regset->size,
+ NULL, data);
-+ }
+ }
+- return copied;
+ else {
+ if (!access_ok(VERIFY_WRITE, data, regset->size))
+ ret = -EIO;
+ else
+ ret = (*regset->get)(target, regset, pos, regset->size,
+ NULL, data);
- }
-- return copied;
++ }
+
+ return ret;
}
@@ -6570,10 +6620,10 @@
+ struct utrace_attached_engine *engine;
+ struct ptrace_state *state;
+ int ret;
-+
+
+ if (request == PTRACE_TRACEME)
+ return ptrace_traceme();
-
++
+ ret = -ESRCH;
read_lock(&tasklist_lock);
- if (likely(child->sighand != NULL)) {
@@ -6779,7 +6829,7 @@
+ if (ret)
+ BUG_ON(ret != -ESRCH);
+ ret = 0;
- break;
++ break;
+ }
+
+ return ret;
@@ -6825,7 +6875,7 @@
+ if (copied != sizeof(tmp))
+ break;
+ ret = put_user(tmp, (unsigned long __user *) data);
-+ break;
+ break;
+ }
+
+ case PTRACE_POKETEXT: /* write the word at location addr. */
@@ -6913,9 +6963,9 @@
+ if (copied != sizeof(tmp))
+ break;
+ ret = put_user(tmp, (compat_ulong_t __user *) data);
-+ break;
-+ }
-+
+ break;
+ }
+
+ case PTRACE_POKETEXT: /* write the word at location addr. */
+ case PTRACE_POKEDATA:
+ ret = 0;
@@ -6943,9 +6993,9 @@
+ state->u.live.u.siginfo,
+ (struct compat_siginfo __user *) data))
+ ret = -EFAULT;
- break;
- }
-
++ break;
++ }
++
+out_tsk:
+ put_task_struct(child);
+out:
@@ -6953,13 +7003,13 @@
return ret;
}
+#endif
++
-/**
- * ptrace_traceme -- helper for PTRACE_TRACEME
- *
- * Performs checks and sets PT_PTRACED.
- * Should be used by all ptrace implementations for PTRACE_TRACEME.
-+
+/*
+ * Detach the zombie being reported for wait.
*/
@@ -7254,19 +7304,15 @@
+ info.si_status = tsk->exit_code >> 8;
+ }
+ }
-
++
+ sighand = parent->sighand;
+ spin_lock_irqsave(&sighand->siglock, flags);
+ if (sighand->action[SIGCHLD-1].sa.sa_handler != SIG_IGN &&
+ !(sighand->action[SIGCHLD-1].sa.sa_flags & sa_mask))
+ __group_send_sig_info(SIGCHLD, &info, parent);
- /*
-- * This lock_kernel fixes a subtle race with suid exec
++ /*
+ * Even if SIGCHLD is not generated, we must wake up wait4 calls.
- */
-- lock_kernel();
-- if (request == PTRACE_TRACEME) {
-- ret = ptrace_traceme();
++ */
+ wake_up_interruptible_sync(&parent->signal->wait_chldexit);
+ spin_unlock_irqrestore(&sighand->siglock, flags);
+}
@@ -7297,13 +7343,17 @@
+ * try to resume us with PTRACE_CONT before we set the flag.
+ */
+ utrace_set_flags(tsk, engine, engine->flags | UTRACE_ACTION_QUIESCE);
-+
-+ /*
+
+ /*
+- * This lock_kernel fixes a subtle race with suid exec
+ * If regset 0 has a writeback call, do it now. On register window
+ * machines, this makes sure the user memory backing the register
+ * data is up to date by the time wait_task_inactive returns to
+ * ptrace_start in our tracer doing a PTRACE_PEEKDATA or the like.
-+ */
+ */
+- lock_kernel();
+- if (request == PTRACE_TRACEME) {
+- ret = ptrace_traceme();
+ regset = utrace_regset(tsk, engine, utrace_native_view(tsk), 0);
+ if (regset->writeback)
+ (*regset->writeback)(tsk, regset, 0);
@@ -7515,8 +7565,7 @@
+ tsk->pid, state->parent->pid, type, tsk->exit_code);
+ do_notify(tsk, state->parent, type);
+ return UTRACE_JCTL_NOSIGCHLD;
- }
--#endif /* __ARCH_SYS_PTRACE */
++}
+
+static u32
+ptrace_report_exec(struct utrace_attached_engine *engine,
@@ -7559,7 +7608,8 @@
+ struct task_struct *tsk, struct pt_regs *regs)
+{
+ return ptrace_report_syscall(engine, tsk, regs, 0);
-+}
+ }
+-#endif /* __ARCH_SYS_PTRACE */
+
+static u32
+ptrace_report_exit(struct utrace_attached_engine *engine,
@@ -7925,7 +7975,7 @@
--- linux-2.6/init/Kconfig
+++ linux-2.6/init/Kconfig
-@@ -579,6 +579,35 @@ config STOP_MACHINE
+@@ -595,6 +595,35 @@ config STOP_MACHINE
Need stop_machine() primitive.
endmenu
@@ -8320,7 +8370,7 @@
current->thread.error_code = error_code;
--- linux-2.6/arch/i386/kernel/process.c
+++ linux-2.6/arch/i386/kernel/process.c
-@@ -820,9 +820,6 @@ asmlinkage int sys_execve(struct pt_regs
+@@ -769,9 +769,6 @@ asmlinkage int sys_execve(struct pt_regs
(char __user * __user *) regs.edx,
®s);
if (error == 0) {
@@ -8812,7 +8862,7 @@
return 0;
}
-@@ -326,308 +615,155 @@ ptrace_get_thread_area(struct task_struc
+@@ -326,308 +615,154 @@ ptrace_get_thread_area(struct task_struc
* Perform set_thread_area on behalf of the traced child.
*/
static int
@@ -9190,8 +9240,7 @@
+
+const struct utrace_regset_view utrace_i386_native = {
+ .name = "i386", .e_machine = EM_386,
-+ .regsets = native_regsets,
-+ .n = sizeof native_regsets / sizeof native_regsets[0],
++ .regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
+};
+EXPORT_SYMBOL_GPL(utrace_i386_native);
+
@@ -9251,7 +9300,7 @@
void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
{
-@@ -651,78 +787,24 @@ void send_sigtrap(struct task_struct *ts
+@@ -651,78 +786,24 @@ void send_sigtrap(struct task_struct *ts
* - triggered by current->work.syscall_trace
*/
__attribute__((regparm(3)))
@@ -9413,7 +9462,7 @@
}
--- linux-2.6/arch/mips/kernel/ptrace.c
+++ linux-2.6/arch/mips/kernel/ptrace.c
-@@ -477,26 +477,9 @@ asmlinkage void do_syscall_trace(struct
+@@ -487,26 +487,9 @@ asmlinkage void do_syscall_trace(struct
audit_syscall_exit(AUDITSC_RESULT(regs->regs[2]),
regs->regs[2]);
@@ -10511,7 +10560,7 @@
/*
* For get_evrregs/set_evrregs functions 'data' has the following layout:
*
-@@ -154,383 +265,454 @@ static inline int set_vrregs(struct task
+@@ -154,383 +265,452 @@ static inline int set_vrregs(struct task
* }
*/
@@ -10616,8 +10665,7 @@
+
+const struct utrace_regset_view utrace_ppc_native_view = {
+ .name = UTS_MACHINE, .e_machine = ELF_ARCH,
-+ .regsets = native_regsets,
-+ .n = sizeof native_regsets / sizeof native_regsets[0],
++ .regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
+};
+EXPORT_SYMBOL_GPL(utrace_ppc_native_view);
@@ -10794,8 +10842,7 @@
+
+const struct utrace_regset_view utrace_ppc32_view = {
+ .name = "ppc", .e_machine = EM_PPC,
-+ .regsets = ppc32_regsets,
-+ .n = sizeof ppc32_regsets / sizeof ppc32_regsets[0],
++ .regsets = ppc32_regsets, .n = ARRAY_SIZE(ppc32_regsets)
+};
+EXPORT_SYMBOL_GPL(utrace_ppc32_view);
+#endif
@@ -11273,7 +11320,7 @@
if (unlikely(current->audit_context)) {
#ifdef CONFIG_PPC64
-@@ -556,8 +738,11 @@ void do_syscall_trace_leave(struct pt_re
+@@ -556,8 +736,11 @@ void do_syscall_trace_leave(struct pt_re
audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
regs->result);
@@ -11416,7 +11463,7 @@
* Copyright (C) 1997 Jakub Jelinek (jj at sunsite.mff.cuni.cz)
*
* Based upon code written by Ross Biro, Linus Torvalds, Bob Manson,
-@@ -11,103 +11,597 @@
+@@ -11,103 +11,595 @@
*/
#include <linux/kernel.h>
@@ -11734,8 +11781,7 @@
-void ptrace_disable(struct task_struct *child)
+const struct utrace_regset_view utrace_sparc64_native_view = {
+ .name = UTS_MACHINE, .e_machine = ELF_ARCH,
-+ .regsets = native_regsets,
-+ .n = sizeof native_regsets / sizeof native_regsets[0],
++ .regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
+};
+EXPORT_SYMBOL_GPL(utrace_sparc64_native_view);
+
@@ -12074,8 +12120,7 @@
+
+const struct utrace_regset_view utrace_sparc32_view = {
+ .name = "sparc", .e_machine = EM_SPARC,
-+ .regsets = sparc32_regsets,
-+ .n = sizeof sparc32_regsets / sizeof sparc32_regsets[0],
++ .regsets = sparc32_regsets, .n = ARRAY_SIZE(sparc32_regsets)
+};
+EXPORT_SYMBOL_GPL(utrace_sparc32_view);
+
@@ -12084,7 +12129,7 @@
/* To get the necessary page struct, access_process_vm() first calls
* get_user_pages(). This has done a flush_dcache_page() on the
* accessed page. Then our caller (copy_{to,from}_user_page()) did
-@@ -167,487 +661,124 @@ void flush_ptrace_access(struct vm_area_
+@@ -167,487 +659,124 @@ void flush_ptrace_access(struct vm_area_
}
}
@@ -12673,7 +12718,7 @@
if (unlikely(current->audit_context) && syscall_exit_p) {
unsigned long tstate = regs->tstate;
-@@ -659,26 +790,9 @@ asmlinkage void syscall_trace(struct pt_
+@@ -659,26 +788,9 @@ asmlinkage void syscall_trace(struct pt_
audit_syscall_exit(result, regs->u_regs[UREG_I0]);
}
@@ -13416,7 +13461,7 @@
}
if (write_access)
*ptr = *data;
-@@ -1104,567 +845,827 @@ access_uarea (struct task_struct *child,
+@@ -1104,567 +845,826 @@ access_uarea (struct task_struct *child,
return 0;
}
@@ -14606,8 +14651,7 @@
+const struct utrace_regset_view utrace_ia64_native = {
+ .name = "ia64",
+ .e_machine = EM_IA_64,
-+ .regsets = native_regsets,
-+ .n = sizeof native_regsets / sizeof native_regsets[0],
++ .regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
+};
+EXPORT_SYMBOL_GPL(utrace_ia64_native);
+
@@ -14759,7 +14803,7 @@
#include <linux/stat.h>
#include <linux/ipc.h>
#include <linux/capability.h>
-@@ -1432,25 +1433,6 @@ sys32_waitpid (int pid, unsigned int *st
+@@ -1436,25 +1437,6 @@ sys32_waitpid (int pid, unsigned int *st
return compat_sys_wait4(pid, stat_addr, options, NULL);
}
@@ -14785,7 +14829,7 @@
/*
* The order in which registers are stored in the ptrace regs structure
*/
-@@ -1748,6 +1730,7 @@ restore_ia32_fpxstate (struct task_struc
+@@ -1752,6 +1734,7 @@ restore_ia32_fpxstate (struct task_struc
return 0;
}
@@ -14793,7 +14837,7 @@
asmlinkage long
sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data)
{
-@@ -1855,9 +1838,11 @@ sys32_ptrace (int request, pid_t pid, un
+@@ -1859,9 +1842,11 @@ sys32_ptrace (int request, pid_t pid, un
compat_ptr(data));
break;
@@ -14805,7 +14849,7 @@
case PTRACE_SYSCALL: /* continue, stop after next syscall */
case PTRACE_CONT: /* restart after signal. */
-@@ -1878,6 +1863,520 @@ sys32_ptrace (int request, pid_t pid, un
+@@ -1882,6 +1867,519 @@ sys32_ptrace (int request, pid_t pid, un
unlock_kernel();
return ret;
}
@@ -14916,7 +14960,7 @@
+ if (dst->pos < sizeof(struct ia32_user_i387_struct)) {
+ pt = task_pt_regs(task);
+ tos = (task->thread.fsr >> 11) & 7;
-+ end = min(dst->pos + dst->count,
++ end = min(dst->pos + dst->count,
+ (unsigned int)(sizeof(struct ia32_user_i387_struct)));
+ start = (dst->pos - 7 * sizeof(int)) / sizeof(struct _fpreg_ia32);
+ end = (end - 7 * sizeof(int)) / sizeof(struct _fpreg_ia32);
@@ -15080,12 +15124,12 @@
+ if (dst->pos < OFFSET(xmm_space[0])) {
+ pt = task_pt_regs(task);
+ tos = (task->thread.fsr >> 11) & 7;
-+ end = min(dst->pos + dst->count,
++ end = min(dst->pos + dst->count,
+ (unsigned int)OFFSET(xmm_space[0]));
+ start = (dst->pos - OFFSET(st_space[0])) / 16;
+ end = (end - OFFSET(st_space[0])) / 16;
+ for (; start < end; start++)
-+ access_fpreg_ia32(start, buf + 16 * start, pt,
++ access_fpreg_ia32(start, buf + 16 * start, pt,
+ info->sw, tos, 0);
+ dst->ret = utrace_regset_copyout(&dst->pos, &dst->count,
+ &dst->u.get.kbuf, &dst->u.get.ubuf,
@@ -15278,8 +15322,7 @@
+
+const struct utrace_regset_view utrace_ia32_view = {
+ .name = "i386", .e_machine = EM_386,
-+ .regsets = ia32_regsets,
-+ .n = sizeof ia32_regsets / sizeof ia32_regsets[0],
++ .regsets = ia32_regsets, .n = ARRAY_SIZE(ia32_regsets)
+};
+EXPORT_SYMBOL_GPL(utrace_ia32_view);
+#endif
@@ -15456,7 +15499,7 @@
#ifdef CONFIG_COMPAT
#include "compat_ptrace.h"
-@@ -84,653 +87,639 @@ FixPerRegisters(struct task_struct *task
+@@ -84,653 +87,637 @@ FixPerRegisters(struct task_struct *task
per_info->control_regs.bits.storage_alt_space_ctl = 1;
else
per_info->control_regs.bits.storage_alt_space_ctl = 0;
@@ -15938,8 +15981,7 @@
+
+const struct utrace_regset_view utrace_s390_native_view = {
+ .name = UTS_MACHINE, .e_machine = ELF_ARCH,
-+ .regsets = native_regsets,
-+ .n = sizeof native_regsets / sizeof native_regsets[0],
++ .regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
+};
+EXPORT_SYMBOL_GPL(utrace_s390_native_view);
@@ -16315,8 +16357,7 @@
+
+const struct utrace_regset_view utrace_s390_compat_view = {
+ .name = "s390", .e_machine = EM_S390,
-+ .regsets = s390_compat_regsets,
-+ .n = sizeof s390_compat_regsets / sizeof s390_compat_regsets[0],
++ .regsets = s390_compat_regsets, .n = ARRAY_SIZE(s390_compat_regsets)
+};
+EXPORT_SYMBOL_GPL(utrace_s390_compat_view);
+#endif /* CONFIG_COMPAT */
@@ -16646,7 +16687,7 @@
asmlinkage void
syscall_trace(struct pt_regs *regs, int entryexit)
-@@ -738,30 +727,17 @@ syscall_trace(struct pt_regs *regs, int
+@@ -738,30 +725,17 @@ syscall_trace(struct pt_regs *regs, int
if (unlikely(current->audit_context) && entryexit)
audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]), regs->gprs[2]);
@@ -16869,7 +16910,7 @@
break;
case offsetof(struct user_regs_struct,cs):
if ((value & 3) != 3)
-@@ -301,311 +304,438 @@ static unsigned long getreg(struct task_
+@@ -301,311 +304,435 @@ static unsigned long getreg(struct task_
val = get_stack_long(child, regno);
if (test_tsk_thread_flag(child, TIF_IA32))
val &= 0xffffffff;
@@ -17486,8 +17527,7 @@
+
+const struct utrace_regset_view utrace_x86_64_native = {
+ .name = "x86-64", .e_machine = EM_X86_64,
-+ .regsets = native_regsets,
-+ .n = sizeof native_regsets / sizeof native_regsets[0],
++ .regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
+};
+EXPORT_SYMBOL_GPL(utrace_x86_64_native);
+
@@ -17498,9 +17538,7 @@
+ {sizeof(struct user_regs_struct),
+ offsetof(struct user, u_debugreg[0]), -1, 0},
+ {offsetof(struct user, u_debugreg[0]),
-+ offsetof(struct user, u_debugreg[4]), 3, 0},
-+ {offsetof(struct user, u_debugreg[6]),
-+ offsetof(struct user, u_debugreg[8]), 3, 6 * sizeof(long)},
++ offsetof(struct user, u_debugreg[8]), 3, 0},
+ {0, 0, -1, 0}
+};
+
@@ -17564,7 +17602,7 @@
if (unlikely(current->audit_context)) {
if (test_thread_flag(TIF_IA32)) {
-@@ -627,8 +757,11 @@ asmlinkage void syscall_trace_leave(stru
+@@ -627,8 +754,11 @@ asmlinkage void syscall_trace_leave(stru
if (unlikely(current->audit_context))
audit_syscall_exit(AUDITSC_RESULT(regs->rax), regs->rax);
@@ -17743,7 +17781,7 @@
break;
R32(cs, cs);
-@@ -167,236 +131,505 @@ static int getreg32(struct task_struct *
+@@ -167,236 +131,504 @@ static int getreg32(struct task_struct *
R32(eax, rax);
R32(orig_eax, orig_rax);
R32(eip, rip);
@@ -18377,8 +18415,7 @@
+
+const struct utrace_regset_view utrace_ia32_view = {
+ .name = "i386", .e_machine = EM_386,
-+ .regsets = ia32_regsets,
-+ .n = sizeof ia32_regsets / sizeof ia32_regsets[0],
++ .regsets = ia32_regsets, .n = ARRAY_SIZE(ia32_regsets)
+};
+EXPORT_SYMBOL_GPL(utrace_ia32_view);
+
- Previous message (by thread): rpms/anaconda/devel .cvsignore, 1.385, 1.386 anaconda.spec, 1.512, 1.513 sources, 1.509, 1.510
- Next message (by thread): rpms/kernel/devel kernel-2.6.spec, 1.2980, 1.2981 linux-2.6-squashfs.patch, 1.18, 1.19
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the fedora-cvs-commits
mailing list