rpms/kernel/devel linux-2.6-utrace.patch,1.45,1.46
fedora-cvs-commits at redhat.com
fedora-cvs-commits at redhat.com
Sun Dec 24 00:03:16 UTC 2006
- Previous message (by thread): rpms/gdb/devel gdb-6.5-bz218379-ppc-solib-trampoline-fix.patch, NONE, 1.1 gdb-6.5-bz218379-ppc-solib-trampoline-test.patch, NONE, 1.1 gdb-6.5-bz218379-solib-trampoline-lookup-lock-fix.patch, NONE, 1.1 gdb-6.5-matching_bfd_sections.patch, 1.1, 1.2 gdb.spec, 1.210, 1.211 gdb-6.5-bz200533-ppc-solib_trampoline.patch, 1.2, NONE
- Next message (by thread): rpms/kernel/FC-6/configs config-xen-generic,1.31,1.32
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: roland
Update of /cvs/dist/rpms/kernel/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv9814
Modified Files:
linux-2.6-utrace.patch
Log Message:
utrace rebase, update with race fixes
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/ia64/ia32/ia32_entry.S | 2
arch/ia64/ia32/sys_ia32.c | 537 ++++++++++
arch/ia64/kernel/asm-offsets.c | 2
arch/ia64/kernel/fsys.S | 16
arch/ia64/kernel/mca.c | 2
arch/ia64/kernel/ptrace.c | 1680 ++++++++++++++++----------------
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 | 959 +++++++++++-------
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/process.c | 3
arch/s390/kernel/ptrace.c | 1073 +++++++++-----------
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 | 1224 ++++++++++++-----------
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 | 723 +++++++++----
arch/x86_64/ia32/sys_ia32.c | 5
arch/x86_64/kernel/process.c | 5
arch/x86_64/kernel/ptrace.c | 657 +++++++-----
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 | 17
include/asm-i386/i387.h | 13
include/asm-i386/signal.h | 4
include/asm-i386/thread_info.h | 7
include/asm-i386/tracehook.h | 49
include/asm-ia64/elf.h | 24
include/asm-ia64/tracehook.h | 83 +
include/asm-powerpc/tracehook.h | 80 +
include/asm-s390/tracehook.h | 53 +
include/asm-sparc64/tracehook.h | 44
include/asm-x86_64/fpu32.h | 3
include/asm-x86_64/thread_info.h | 3
include/asm-x86_64/tracehook.h | 54 +
include/linux/init_task.h | 3
include/linux/ptrace.h | 224 +++-
include/linux/sched.h | 25
include/linux/tracehook.h | 707 +++++++++++++
include/linux/utrace.h | 504 +++++++++
init/Kconfig | 29
kernel/Makefile | 1
kernel/exit.c | 244 +---
kernel/fork.c | 62 -
kernel/ptrace.c | 1767 ++++++++++++++++++++++++++++------
kernel/signal.c | 211 ----
kernel/sys.c | 2
kernel/timer.c | 6
kernel/tsacct.c | 2
kernel/utrace.c | 1861 ++++++++++++++++++++++++++++++++++++
security/selinux/hooks.c | 54 -
security/selinux/include/objsec.h | 1
97 files changed, 10644 insertions(+), 5053 deletions(-)
Index: linux-2.6-utrace.patch
===================================================================
RCS file: /cvs/dist/rpms/kernel/devel/linux-2.6-utrace.patch,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -r1.45 -r1.46
--- linux-2.6-utrace.patch 14 Dec 2006 14:17:26 -0000 1.45
+++ linux-2.6-utrace.patch 24 Dec 2006 00:03:12 -0000 1.46
@@ -34,7 +34,7 @@
arch/s390/kernel/compat_linux.c | 3
arch/s390/kernel/compat_signal.c | 5
arch/s390/kernel/process.c | 3
- arch/s390/kernel/ptrace.c | 1073 ++++++++++----------
+ arch/s390/kernel/ptrace.c | 1073 +++++++++-----------
arch/s390/kernel/signal.c | 3
arch/s390/kernel/traps.c | 6
arch/sparc64/Makefile | 0
@@ -77,7 +77,7 @@
include/asm-s390/tracehook.h | 53 +
include/asm-sparc64/tracehook.h | 44 +
include/asm-x86_64/fpu32.h | 3
- include/asm-x86_64/thread_info.h | 2
+ include/asm-x86_64/thread_info.h | 3
include/asm-x86_64/tracehook.h | 54 +
include/linux/init_task.h | 3
include/linux/ptrace.h | 224 +++-
@@ -88,15 +88,15 @@
kernel/Makefile | 1
kernel/exit.c | 244 +----
kernel/fork.c | 62 -
- kernel/ptrace.c | 1633 +++++++++++++++++++++++++------
+ kernel/ptrace.c | 1767 +++++++++++++++++++++++++++------
kernel/signal.c | 211 +---
kernel/sys.c | 2
kernel/timer.c | 6
kernel/tsacct.c | 2
- kernel/utrace.c | 1860 +++++++++++++++++++++++++++++++++++
+ kernel/utrace.c | 1861 +++++++++++++++++++++++++++++++++++
security/selinux/hooks.c | 54 +
security/selinux/include/objsec.h | 1
- 98 files changed, 10509 insertions(+), 5052 deletions(-)
+ 98 files changed, 10644 insertions(+), 5053 deletions(-)
create mode 100644 Documentation/utrace.txt
delete arch/powerpc/kernel/ptrace-common.h
delete arch/powerpc/kernel/ptrace32.c
@@ -350,8 +350,8 @@
} while (0)
#endif /* __KERNEL__ */
---- linux-2.6.19.noarch/include/asm-i386/thread_info.h~ 2006-12-14 09:11:23.000000000 -0500
-+++ linux-2.6.19.noarch/include/asm-i386/thread_info.h 2006-12-14 09:12:44.000000000 -0500
+--- linux-2.6/include/asm-i386/thread_info.h.utrace-ptrace-compat
++++ linux-2.6/include/asm-i386/thread_info.h
@@ -127,7 +127,6 @@ static inline struct thread_info *curren
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */
@@ -364,7 +364,7 @@
#define TIF_DEBUG 17 /* uses debug registers */
#define TIF_IO_BITMAP 18 /* uses I/O bitmap */
#define TIF_FREEZE 19 /* is freezing for suspend */
-+#define TIF_FORCED_TF 20 /* syscall emulation active */
++#define TIF_FORCED_TF 20 /* true if TF in eflags artificially */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
@@ -379,13 +379,13 @@
#define _TIF_DEBUG (1<<TIF_DEBUG)
#define _TIF_IO_BITMAP (1<<TIF_IO_BITMAP)
#define _TIF_FREEZE (1<<TIF_FREEZE)
-+#define _TIF_FORCED_EMU (1<<TIF_FORCED_TF)
++#define _TIF_FORCED_TF (1<<TIF_FORCED_TF)
/* work to do on interrupt/exception return */
#define _TIF_WORK_MASK \
- (0x0000FFFF & ~(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
- _TIF_SECCOMP | _TIF_SYSCALL_EMU))
-+ (0x0000FFFF & ~(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP))
++ (0x0000FFFF & ~(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP))
/* work to do on any return to u-space */
#define _TIF_ALLWORK_MASK (0x0000FFFF & ~_TIF_SECCOMP)
@@ -507,24 +507,25 @@
+int set_fpregs32(struct task_struct *, const struct user_i387_ia32_struct *);
+
#endif
---- linux-2.6.19.noarch/include/asm-x86_64/thread_info.h~ 2006-12-14 09:13:22.000000000 -0500
-+++ linux-2.6.19.noarch/include/asm-x86_64/thread_info.h 2006-12-14 09:13:53.000000000 -0500
-@@ -123,6 +123,7 @@ static inline struct thread_info *stack_
- #define TIF_DEBUG 21 /* uses debug registers */
- #define TIF_IO_BITMAP 22 /* uses I/O bitmap */
- #define TIF_FREEZE 23 /* is freezing for suspend */
-+#define TIF_FORCED_TF 24 /* true if TF in eflags artificially */
-
- #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
- #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
-@@ -139,6 +140,7 @@ static inline struct thread_info *stack_
- #define _TIF_DEBUG (1<<TIF_DEBUG)
- #define _TIF_IO_BITMAP (1<<TIF_IO_BITMAP)
- #define _TIF_FREEZE (1<<TIF_FREEZE)
+--- linux-2.6/include/asm-x86_64/thread_info.h.utrace-ptrace-compat
++++ linux-2.6/include/asm-x86_64/thread_info.h
+@@ -115,7 +115,7 @@ static inline struct thread_info *stack_
+ #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */
+ #define TIF_SECCOMP 8 /* secure computing */
+ #define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal */
+-/* 16 free */
++#define TIF_FORCED_TF 16 /* true if TF in eflags artificially */
+ #define TIF_IA32 17 /* 32bit process */
+ #define TIF_FORK 18 /* ret_from_fork */
+ #define TIF_ABI_PENDING 19
+@@ -133,6 +133,7 @@ static inline struct thread_info *stack_
+ #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
+ #define _TIF_SECCOMP (1<<TIF_SECCOMP)
+ #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
+#define _TIF_FORCED_TF (1<<TIF_FORCED_TF)
-
- /* work to do on interrupt/exception return */
- #define _TIF_WORK_MASK \
+ #define _TIF_IA32 (1<<TIF_IA32)
+ #define _TIF_FORK (1<<TIF_FORK)
+ #define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING)
--- linux-2.6/include/asm-x86_64/tracehook.h.utrace-ptrace-compat
+++ linux-2.6/include/asm-x86_64/tracehook.h
@@ -0,0 +1,54 @@
@@ -702,7 +703,7 @@
/*
* cache last used pipe for splice
*/
-@@ -1331,6 +1329,7 @@ extern int kill_pid(struct pid *pid, int
+@@ -1330,6 +1328,7 @@ extern int kill_pid(struct pid *pid, int
extern int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp);
extern int kill_pg_info(int, struct siginfo *, pid_t);
extern void do_notify_parent(struct task_struct *, int);
@@ -1459,7 +1460,7 @@
#ifndef force_successful_syscall_return
--- linux-2.6/include/linux/init_task.h.utrace-ptrace-compat
+++ linux-2.6/include/linux/init_task.h
-@@ -111,9 +111,6 @@ extern struct group_info init_groups;
+@@ -110,9 +110,6 @@ extern struct group_info init_groups;
.ioprio = 0, \
.time_slice = HZ, \
.tasks = LIST_HEAD_INIT(tsk.tasks), \
@@ -3280,7 +3281,7 @@
read_lock(&tasklist_lock);
do_notify_parent_cldstop(current, CLD_STOPPED);
read_unlock(&tasklist_lock);
-@@ -1824,44 +1718,24 @@ relock:
+@@ -1826,44 +1720,24 @@ relock:
handle_group_stop())
goto relock;
@@ -3341,7 +3342,7 @@
if (ka->sa.sa_handler == SIG_IGN) /* Do nothing. */
continue;
if (ka->sa.sa_handler != SIG_DFL) {
-@@ -1910,7 +1784,7 @@ relock:
+@@ -1912,7 +1786,7 @@ relock:
spin_lock_irq(¤t->sighand->siglock);
}
@@ -3350,7 +3351,7 @@
/* It released the siglock. */
goto relock;
}
-@@ -1937,13 +1811,13 @@ relock:
+@@ -1939,13 +1813,13 @@ relock:
* first and our do_group_exit call below will use
* that value and ignore the one we pass it.
*/
@@ -3366,7 +3367,7 @@
/* NOTREACHED */
}
spin_unlock_irq(¤t->sighand->siglock);
-@@ -1956,7 +1830,6 @@ EXPORT_SYMBOL(flush_signals);
+@@ -1958,7 +1832,6 @@ EXPORT_SYMBOL(flush_signals);
EXPORT_SYMBOL(force_sig);
EXPORT_SYMBOL(kill_pg);
EXPORT_SYMBOL(kill_proc);
@@ -3387,7 +3388,7 @@
stats->ac_stime = cputime_to_msecs(tsk->stime) * USEC_PER_MSEC;
--- linux-2.6/kernel/utrace.c.utrace-ptrace-compat
+++ linux-2.6/kernel/utrace.c
-@@ -0,0 +1,1860 @@
+@@ -0,0 +1,1861 @@
+#include <linux/utrace.h>
+#include <linux/tracehook.h>
+#include <linux/err.h>
@@ -4883,6 +4884,7 @@
+ sigdelset(&sigkill_only, SIGKILL);
+ killed = dequeue_signal(tsk, &sigkill_only, info);
+ BUG_ON(killed != SIGKILL);
++ *return_ka = tsk->sighand->action[killed - 1];
+ return killed;
+ }
+ }
@@ -5732,7 +5734,7 @@
goto out;
--- linux-2.6/kernel/timer.c.utrace-ptrace-compat
+++ linux-2.6/kernel/timer.c
-@@ -1242,9 +1242,9 @@ asmlinkage long sys_getpid(void)
+@@ -1246,9 +1246,9 @@ asmlinkage long sys_getpid(void)
}
/*
@@ -5744,7 +5746,7 @@
* release_task()->call_rcu(delayed_put_task_struct).
*/
asmlinkage long sys_getppid(void)
-@@ -1252,7 +1252,7 @@ asmlinkage long sys_getppid(void)
+@@ -1256,7 +1256,7 @@ asmlinkage long sys_getppid(void)
int pid;
rcu_read_lock();
@@ -5864,7 +5866,7 @@
static int may_attach(struct task_struct *task)
{
-@@ -157,334 +71,1433 @@ int ptrace_may_attach(struct task_struct
+@@ -157,334 +71,1567 @@ int ptrace_may_attach(struct task_struct
return !err;
}
@@ -5917,8 +5919,6 @@
+ struct rcu_head dead;
+ struct {
+ u8 options; /* PTRACE_SETOPTIONS bits. */
-+ unsigned int stopped:1; /* Stopped for report. */
-+ unsigned int reported:1; /* wait already reported. */
+ unsigned int syscall:1; /* Reporting for syscall. */
+#ifdef PTRACE_SYSEMU
+ unsigned int sysemu:1; /* PTRACE_SYSEMU in progress. */
@@ -5937,15 +5937,6 @@
+
+static const struct utrace_engine_ops ptrace_utrace_ops; /* Initialized below. */
+
-+
-+static void
-+ptrace_state_link(struct ptrace_state *state)
-+{
-+ task_lock(state->parent);
-+ list_add_rcu(&state->entry, &state->parent->ptracees);
-+ task_unlock(state->parent);
-+}
-+
+static void
+ptrace_state_unlink(struct ptrace_state *state)
+{
@@ -5954,25 +5945,37 @@
+ task_unlock(state->parent);
+}
+
-+static int
++static struct ptrace_state *
+ptrace_setup(struct task_struct *target, struct utrace_attached_engine *engine,
-+ struct task_struct *parent, u8 options, int cap_sys_ptrace)
++ struct task_struct *parent, u8 options, int cap_sys_ptrace,
++ struct ptrace_state *state)
+{
-+ struct ptrace_state *state = kzalloc(sizeof *state, GFP_USER);
-+ if (unlikely(state == NULL))
-+ return -ENOMEM;
++ if (state == NULL) {
++ state = kzalloc(sizeof *state, GFP_USER);
++ if (unlikely(state == NULL))
++ return ERR_PTR(-ENOMEM);
++ }
+
+ state->engine = engine;
+ state->task = target;
+ state->parent = parent;
+ state->u.live.options = options;
+ state->u.live.cap_sys_ptrace = cap_sys_ptrace;
-+ ptrace_state_link(state);
+
++ task_lock(parent);
++ if (unlikely(parent->flags & PF_EXITING)) {
++ task_unlock(parent);
++ kfree(state);
++ return ERR_PTR(-EALREADY);
+ }
++ list_add_rcu(&state->entry, &state->parent->ptracees);
++ task_unlock(state->parent);
+
+- if (!task->mm)
+ BUG_ON(engine->data != 0);
+ rcu_assign_pointer(engine->data, (unsigned long) state);
+
-+ return 0;
++ return state;
+}
+
+static void
@@ -6021,16 +6024,22 @@
+
+ /*
+ * ptrace always inhibits normal parent reaping.
-+ * But for a corner case we sometimes see the REAP event instead.
++ * But for a corner case we sometimes see the REAP event anyway.
+ */
+ flags |= UTRACE_ACTION_NOREAP | UTRACE_EVENT(REAP);
+
-+ state->u.live.stopped = (flags & UTRACE_ACTION_QUIESCE) != 0;
-+ if (!state->u.live.stopped) {
++ if (!(flags & UTRACE_ACTION_QUIESCE)) {
++ /*
++ * We're letting the thread resume from ptrace stop.
++ * If SIGKILL is waking it up, it can be racing with us here
++ * to set its own exit_code in do_exit. Though we clobber
++ * it here, we check for the case in ptrace_report_death.
++ */
++ if (!unlikely(target->flags & PF_SIGNALED))
++ target->exit_code = 0;
++
+ if (!state->u.live.have_eventmsg)
+ state->u.live.u.siginfo = NULL;
-+ if (!(target->flags & PF_EXITING))
-+ target->exit_code = 0;
+
+ if (target->state == TASK_STOPPED) {
+ spin_lock_irq(&target->sighand->siglock);
@@ -6039,12 +6048,15 @@
+ spin_unlock_irq(&target->sighand->siglock);
+ }
+ }
++
+ return utrace_set_flags(target, engine, flags);
+}
+
+static int ptrace_traceme(void)
+{
+ struct utrace_attached_engine *engine;
++ struct ptrace_state *state;
++ struct task_struct *parent;
+ int retval;
+
+ engine = utrace_attach(current, (UTRACE_ATTACH_CREATE
@@ -6058,27 +6070,64 @@
+ retval = -EPERM;
+ }
+ else {
++ /*
++ * We need to preallocate so that we can hold
++ * rcu_read_lock from extracting ->parent through
++ * ptrace_setup using it.
++ */
++ state = kzalloc(sizeof *state, GFP_USER);
++ if (unlikely(state == NULL)) {
++ (void) utrace_detach(current, engine);
++ printk(KERN_ERR
++ "ptrace out of memory, lost child %d of %d",
++ current->pid, current->parent->pid);
++ return -ENOMEM;
++ }
++
++ rcu_read_lock();
++ parent = rcu_dereference(current->parent);
++
+ task_lock(current);
-+ retval = security_ptrace(current->parent, current);
++ retval = security_ptrace(parent, current);
+ task_unlock(current);
-+ if (!retval)
-+ retval = ptrace_setup(current, engine,
-+ current->parent, 0, 0);
++
++ if (retval) {
++ kfree(state);
++ (void) utrace_detach(current, engine);
++ }
++ else {
++ state = ptrace_setup(current, engine, parent, 0, 0,
++ state);
++ if (IS_ERR(state))
++ retval = PTR_ERR(state);
++ }
++ rcu_read_unlock();
++
+ if (!retval) {
++ /*
++ * This can't fail because we can't die while we
++ * are here doing this.
++ */
+ retval = ptrace_update(current, engine, 0);
+ BUG_ON(retval);
+ }
-+ if (retval)
-+ utrace_detach(current, engine);
- }
-
-- if (!task->mm)
++ else if (unlikely(retval == -EALREADY))
++ /*
++ * We raced with our parent's exit, which would
++ * have detached us just after our attach if
++ * we'd won the race. Pretend we got attached
++ * and then detached immediately, no error.
++ */
++ retval = 0;
++ }
++
+ return retval;
+}
+
+static int ptrace_attach(struct task_struct *task)
+{
+ struct utrace_attached_engine *engine;
++ struct ptrace_state *state;
+ int retval;
+
+ retval = -EPERM;
@@ -6112,19 +6161,27 @@
+ }
- force_sig_specific(SIGSTOP, task);
-+ if (ptrace_may_attach(task))
-+ retval = ptrace_setup(task, engine, current, 0,
-+ capable(CAP_SYS_PTRACE));
-+ if (!retval) {
-+ retval = ptrace_update(task, engine, 0);
-+ if (retval) {
-+ if (retval == -EALREADY)
-+ retval = -ESRCH;
-+ BUG_ON(retval != -ESRCH);
++ if (ptrace_may_attach(task)) {
++ state = ptrace_setup(task, engine, current, 0,
++ capable(CAP_SYS_PTRACE), NULL);
++ if (IS_ERR(state))
++ retval = PTR_ERR(state);
++ else {
++ retval = ptrace_update(task, engine, 0);
++ if (retval) {
++ /*
++ * It died before we enabled any callbacks.
++ */
++ if (retval == -EALREADY)
++ retval = -ESRCH;
++ BUG_ON(retval != -ESRCH);
++ ptrace_state_unlink(state);
++ ptrace_done(state);
++ }
+ }
+ }
+ if (retval)
-+ utrace_detach(task, engine);
++ (void) utrace_detach(task, engine);
+ else {
+ int stopped;
+
@@ -6169,8 +6226,26 @@
+ struct ptrace_state *state = (struct ptrace_state *) engine->data;
+ int error = utrace_detach(task, engine);
+ if (!error) {
++ /*
++ * We can only get here from the ptracer itself or via
++ * detach_zombie from another thread in its group.
++ */
++ BUG_ON(state->parent->tgid != current->tgid);
+ ptrace_state_unlink(state);
+ ptrace_done(state);
++
++ /*
++ * Wake up any other threads that might be blocked in
++ * wait. Though traditional ptrace does not guarantee
++ * this wakeup on PTRACE_DETACH, it does prevent
++ * erroneous blocking in wait when another racing
++ * thread's wait call reap-detaches the last child.
++ * Without this wakeup, another thread might stay
++ * blocked when it should return -ECHILD.
++ */
++ spin_lock_irq(¤t->sighand->siglock);
++ wake_up_interruptible(¤t->signal->wait_chldexit);
++ spin_unlock_irq(¤t->sighand->siglock);
+ }
+ return error;
}
@@ -6184,30 +6259,51 @@
+ptrace_exit(struct task_struct *tsk)
{
- if (!valid_signal(data))
-+ rcu_read_lock();
-+ if (unlikely(!list_empty(&tsk->ptracees))) {
-+ struct ptrace_state *state, *next;
++ struct list_head *pos, *n;
+
-+ /*
-+ * First detach the utrace layer from all the tasks.
-+ * We don't want to hold any locks while calling utrace_detach.
-+ */
-+ list_for_each_entry_rcu(state, &tsk->ptracees, entry) {
-+ rcu_assign_pointer(state->engine->data, 0UL);
-+ (void) utrace_detach(state->task, state->engine);
-+ }
++ /*
++ * Taking the task_lock after PF_EXITING is set ensures that a
++ * child in ptrace_traceme will not put itself on our list when
++ * we might already be tearing it down.
++ */
++ task_lock(tsk);
++ if (likely(list_empty(&tsk->ptracees))) {
++ task_unlock(tsk);
++ return;
++ }
++ task_unlock(tsk);
+
-+ /*
-+ * Now clear out our list and clean up our data structures.
-+ * The task_lock protects our list structure.
-+ */
-+ task_lock(tsk);
-+ list_for_each_entry_safe(state, next, &tsk->ptracees, entry) {
-+ list_del_rcu(&state->entry);
++restart:
++ rcu_read_lock();
++
++ list_for_each_safe_rcu(pos, n, &tsk->ptracees) {
++ struct ptrace_state *state = list_entry(pos,
++ struct ptrace_state,
++ entry);
++ int error = utrace_detach(state->task, state->engine);
++ BUG_ON(state->parent != tsk);
++ if (likely(error == 0)) {
++ ptrace_state_unlink(state);
+ ptrace_done(state);
+ }
-+ task_unlock(tsk);
++ else if (unlikely(error == -EALREADY)) {
++ /*
++ * It's still doing report_death callbacks.
++ * Just wait for it to settle down.
++ * Since wait_task_inactive might yield,
++ * we must go out of rcu_read_lock and restart.
++ */
++ struct task_struct *p = state->task;
++ get_task_struct(p);
++ rcu_read_unlock();
++ wait_task_inactive(p);
++ put_task_struct(p);
++ goto restart;
++ }
++ else
++ BUG_ON(error != -ESRCH);
+ }
++
+ rcu_read_unlock();
+
+ BUG_ON(!list_empty(&tsk->ptracees));
@@ -6303,15 +6399,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;
}
@@ -6329,12 +6425,15 @@
+ view, setno);
+ unsigned int pos;
+ int ret;
++
++ if (unlikely(regset == NULL))
++ return -EIO;
- while (len > 0) {
- char buf[128];
- int this_len, retval;
-+ if (unlikely(regset == NULL))
-+ return -EIO;
++ if (regno < regset->bias || regno >= regset->bias + regset->n)
++ return -EINVAL;
- this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
- if (copy_from_user(buf, src, this_len))
@@ -6349,9 +6448,6 @@
- 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) {
@@ -6360,15 +6456,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;
}
@@ -6536,34 +6632,30 @@
- error = 0;
- }
- spin_unlock_irq(&child->sighand->siglock);
++ rcu_read_lock();
+ engine = utrace_attach(child, UTRACE_ATTACH_MATCH_OPS,
+ &ptrace_utrace_ops, 0);
+ ret = -ESRCH;
+ if (IS_ERR(engine) || engine == NULL)
-+ goto out_tsk;
-+ rcu_read_lock();
++ goto out_tsk_rcu;
+ state = rcu_dereference((struct ptrace_state *) engine->data);
-+ if (state == NULL || state->parent != current) {
-+ rcu_read_unlock();
-+ goto out_tsk;
- }
-- read_unlock(&tasklist_lock);
-- return error;
++ if (state == NULL || state->parent != current)
++ goto out_tsk_rcu;
+ rcu_read_unlock();
+
+ /*
+ * Traditional ptrace behavior demands that the target already be
+ * quiescent, but not dead.
+ */
-+ if (request != PTRACE_KILL && !state->u.live.stopped) {
++ if (request != PTRACE_KILL
++ && !(engine->flags & UTRACE_ACTION_QUIESCE)) {
+#ifdef PTRACE_DEBUG
+ printk("%d not stopped (%lx)\n", child->pid, child->state);
+#endif
-+ if (child->state != TASK_STOPPED)
-+ goto out_tsk;
-+ utrace_set_flags(child, engine,
-+ engine->flags | UTRACE_ACTION_QUIESCE);
-+ }
++ goto out_tsk;
+ }
+- read_unlock(&tasklist_lock);
+- return error;
+
+ /*
+ * We do this for all requests to match traditional ptrace behavior.
@@ -6587,6 +6679,8 @@
+ *statep = state;
+ return -EIO;
+
++out_tsk_rcu:
++ rcu_read_unlock();
+out_tsk:
+ put_task_struct(child);
+out:
@@ -6698,7 +6792,7 @@
+ if (ret)
+ BUG_ON(ret != -ESRCH);
+ ret = 0;
- break;
++ break;
+ }
+
+ return ret;
@@ -6755,7 +6849,7 @@
+ if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
+ break;
+ ret = -EIO;
-+ break;
+ break;
+
case PTRACE_GETEVENTMSG:
- ret = put_user(child->ptrace_message, (unsigned long __user *) data);
@@ -6787,7 +6881,7 @@
+ put_task_struct(child);
+out:
+#ifdef PTRACE_DEBUG
-+ printk("%d ptrace -> %x\n", current->pid, ret);
++ printk("%d ptrace -> %lx\n", current->pid, ret);
+#endif
+ return ret;
+}
@@ -6875,34 +6969,108 @@
+ put_task_struct(child);
+out:
+#ifdef PTRACE_DEBUG
-+ printk("%d ptrace -> %x\n", current->pid, ret);
++ printk("%d ptrace -> %lx\n", current->pid, ret);
+#endif
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.
+ */
+-int ptrace_traceme(void)
++static inline void
++detach_zombie(struct task_struct *tsk,
++ struct task_struct *p, struct ptrace_state *state)
+ {
+- int ret = -EPERM;
+-
+- /*
+- * Are we already being traced?
+- */
+- task_lock(current);
+- if (!(current->ptrace & PT_PTRACED)) {
+- ret = security_ptrace(current->parent, current);
++ int detach_error;
++restart:
++ detach_error = 0;
++ rcu_read_lock();
++ if (tsk != current) {
+ /*
+- * Set the ptrace bit in the process ptrace flags.
++ * We've excluded other ptrace_do_wait calls. But the
++ * ptracer itself might have done ptrace_detach while we
++ * did not have rcu_read_lock. So double-check that state
++ * is still valid.
+ */
+- if (!ret)
+- current->ptrace |= PT_PTRACED;
++ struct utrace_attached_engine *engine;
++ engine = utrace_attach(
++ p, (UTRACE_ATTACH_MATCH_OPS
++ | UTRACE_ATTACH_MATCH_DATA),
++ &ptrace_utrace_ops,
++ (unsigned long) state);
++ if (IS_ERR(engine) || state->parent != tsk)
++ detach_error = -ESRCH;
++ else
++ BUG_ON(state->engine != engine);
+ }
+- task_unlock(current);
+- return ret;
++ if (likely(!detach_error))
++ detach_error = ptrace_detach(p, state->engine);
++ if (unlikely(detach_error == -EALREADY)) {
++ /*
++ * It's still doing report_death callbacks.
++ * Just wait for it to settle down.
++ */
++ rcu_read_unlock();
++ wait_task_inactive(p); /* Might block. */
++ goto restart;
++ }
++ /*
++ * A failure with -ESRCH means that report_reap is
++ * already running and will do the cleanup, or that
++ * we lost a race with ptrace_detach in another
++ * thread or with the automatic detach in
++ * report_death.
++ */
++ if (detach_error)
++ BUG_ON(detach_error != -ESRCH);
++ rcu_read_unlock();
+ }
+
+-/**
+- * ptrace_get_task_struct -- grab a task struct reference for ptrace
+- * @pid: process id to grab a task_struct reference of
+- *
+- * This function is a helper for ptrace implementations. It checks
+- * permissions and then grabs a task struct for use of the actual
+- * ptrace implementation.
+- *
+- * Returns the task_struct for @pid or an ERR_PTR() on failure.
+/*
+ * We're called with tasklist_lock held for reading.
+ * If we return -ECHILD or zero, next_thread(tsk) must still be valid to use.
+ * If we return another error code, or a successful PID value, we
+ * release tasklist_lock first.
*/
--int ptrace_traceme(void)
+-struct task_struct *ptrace_get_task_struct(pid_t pid)
+int
+ptrace_do_wait(struct task_struct *tsk,
+ pid_t pid, int options, struct siginfo __user *infop,
+ int __user *stat_addr, struct rusage __user *rusagep)
{
-- int ret = -EPERM;
+- struct task_struct *child;
+ struct ptrace_state *state;
+ struct task_struct *p;
-+ struct utrace *utrace;
+ int err = -ECHILD;
+ int exit_code, why, status;
+
@@ -6926,34 +7094,60 @@
+ if (security_task_wait(p))
+ continue;
+
++ /*
++ * This is a matching child. If we don't win now, tell
++ * our caller to block and repeat. From this point we
++ * must ensure that wait_chldexit will get a wakeup for
++ * any tracee stopping, dying, or being detached.
++ * For death, tasklist_lock guarantees this already.
++ */
+ err = 0;
-+ if (state->u.live.reported)
-+ continue;
+
-+ if (state->u.live.stopped)
-+ goto found;
-+ if ((p->state & (TASK_TRACED | TASK_STOPPED))
-+ && (p->signal->flags & SIGNAL_STOP_STOPPED))
-+ goto found;
-+ if (p->exit_state == EXIT_ZOMBIE) {
++ switch (p->exit_state) {
++ case EXIT_ZOMBIE:
+ if (!likely(options & WEXITED))
+ continue;
+ if (delay_group_leader(p))
+ continue;
++ exit_code = p->exit_code;
+ goto found;
++ case EXIT_DEAD:
++ continue;
++ default:
++ /*
++ * tasklist_lock holds up any transitions to
++ * EXIT_ZOMBIE. After releasing it we are
++ * guaranteed a wakeup on wait_chldexit after
++ * any new deaths.
++ */
++ break;
+ }
++
++ /*
++ * This xchg atomically ensures that only one do_wait
++ * call can report this thread. Because exit_code is
++ * always set before do_notify wakes us up, after this
++ * check fails we are sure to get a wakeup if it stops.
++ */
++ exit_code = xchg(&p->exit_code, 0);
++ if (exit_code)
++ goto found;
++
+ // XXX should handle WCONTINUED
+ }
+ rcu_read_unlock();
+ return err;
+
+found:
++ BUG_ON(state->parent != tsk);
+ rcu_read_unlock();
+
-+ BUG_ON(state->parent != tsk);
++#ifdef PTRACE_DEBUG
++ printk("%d ptrace_do_wait (%d) found %d code %x (%lu)\n", current->pid, tsk->pid, p->pid, exit_code, p->exit_state);
++#endif
+
+ if (p->exit_state) {
-+ if (unlikely(p->parent == state->parent)) {
++ if (unlikely(p->parent == tsk))
+ /*
+ * This is our natural child we were ptracing.
+ * When it dies it detaches (see ptrace_report_death).
@@ -6962,32 +7156,35 @@
+ * the normal wait_task_zombie path instead.
+ */
+ return 0;
-+ }
-+ exit_code = p->exit_code;
+ if ((exit_code & 0x7f) == 0) {
+ why = CLD_EXITED;
+ status = exit_code >> 8;
-+ } else {
++ }
++ else {
+ why = (exit_code & 0x80) ? CLD_DUMPED : CLD_KILLED;
+ status = exit_code & 0x7f;
+ }
+ }
+ else {
+ why = CLD_TRAPPED;
-+ status = p->exit_code;
++ status = exit_code;
+ exit_code = (status << 8) | 0x7f;
+ }
/*
-- * Are we already being traced?
+- * Tracing init is not allowed.
+ * At this point we are committed to a successful return
+ * or a user error return. Release the tasklist_lock.
*/
-- task_lock(current);
-- if (!(current->ptrace & PT_PTRACED)) {
-- ret = security_ptrace(current->parent, current);
+- if (pid == 1)
+- return ERR_PTR(-EPERM);
++ get_task_struct(p);
+ read_unlock(&tasklist_lock);
-+
+
+- read_lock(&tasklist_lock);
+- child = find_task_by_pid(pid);
+- if (child)
+- get_task_struct(child);
+ if (rusagep)
+ err = getrusage(p, RUSAGE_BOTH, rusagep);
+ if (infop) {
@@ -7006,86 +7203,34 @@
+ }
+ if (!err && stat_addr)
+ err = put_user(exit_code, stat_addr);
-+
+
+- read_unlock(&tasklist_lock);
+- if (!child)
+- return ERR_PTR(-ESRCH);
+- return child;
+ if (!err) {
-+
-+ err = p->pid;
-+
- /*
-- * Set the ptrace bit in the process ptrace flags.
-+ * If this was a non-death report, the child might now be
-+ * detaching on death in the same race possible in the
-+ * p->exit_state check above. So check for p->utrace being
-+ * NULL, then we don't need to update the state any more.
- */
-- if (!ret)
-- current->ptrace |= PT_PTRACED;
-+ rcu_read_lock();
-+ utrace = rcu_dereference(p->utrace);
-+ if (likely(utrace != NULL)) {
-+ utrace_lock(utrace);
-+ if (unlikely(rcu_dereference(p->utrace) != utrace)
-+ || unlikely(state->u.live.reported))
-+ /*
-+ * Another thread in the group got here
-+ * first and reaped it before we locked.
-+ */
-+ err = -ERESTARTNOINTR;
-+ else
-+ state->u.live.reported = 1;
-+ utrace_unlock(utrace);
-+ }
-+
-+ if (err > 0 && why != CLD_TRAPPED) {
++ if (why != CLD_TRAPPED)
+ /*
+ * This was a death report. The ptracer's wait
+ * does an implicit detach, so the zombie reports
+ * to its real parent now.
+ */
-+ int detach_error = ptrace_detach(p, state->engine);
-+ while (detach_error == -EALREADY) {
-+ /*
-+ * It's still doing report_death callbacks.
-+ * Just wait for it to settle down.
-+ */
-+ wait_task_inactive(p);
-+ detach_error = ptrace_detach(p, state->engine);
-+ }
-+ /*
-+ * A failure with -ESRCH means that report_reap is
-+ * already running and will do the cleanup, or that
-+ * we lost a race with ptrace_detach in another
-+ * thread or with the automatic detach in
-+ * report_death.
-+ */
-+ if (detach_error) {
-+ BUG_ON(detach_error != -ESRCH);
-+ err = -ERESTARTNOINTR;
-+ }
-+ }
-+ rcu_read_unlock();
- }
-- task_unlock(current);
-- return ret;
++ detach_zombie(tsk, p, state);
++ err = p->pid;
++ }
++
++ put_task_struct(p);
+
+ return err;
}
--/**
-- * ptrace_get_task_struct -- grab a task struct reference for ptrace
-- * @pid: process id to grab a task_struct reference of
-- *
-- * This function is a helper for ptrace implementations. It checks
-- * permissions and then grabs a task struct for use of the actual
-- * ptrace implementation.
-- *
-- * Returns the task_struct for @pid or an ERR_PTR() on failure.
-- */
--struct task_struct *ptrace_get_task_struct(pid_t pid)
+-#ifndef __ARCH_SYS_PTRACE
+-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+static void
+do_notify(struct task_struct *tsk, struct task_struct *parent, int why)
{
- struct task_struct *child;
+- long ret;
+ struct siginfo info;
+ unsigned long flags;
+ struct sighand_struct *sighand;
@@ -7125,33 +7270,20 @@
+ !(sighand->action[SIGCHLD-1].sa.sa_flags & sa_mask))
+ __group_send_sig_info(SIGCHLD, &info, parent);
/*
-- * Tracing init is not allowed.
+- * This lock_kernel fixes a subtle race with suid exec
+ * Even if SIGCHLD is not generated, we must wake up wait4 calls.
*/
-- if (pid == 1)
-- return ERR_PTR(-EPERM);
--
-- read_lock(&tasklist_lock);
-- child = find_task_by_pid(pid);
-- if (child)
-- get_task_struct(child);
--
-- read_unlock(&tasklist_lock);
-- if (!child)
-- return ERR_PTR(-ESRCH);
-- return child;
+- lock_kernel();
+- if (request == PTRACE_TRACEME) {
+- ret = ptrace_traceme();
+ wake_up_interruptible_sync(&parent->signal->wait_chldexit);
+ spin_unlock_irqrestore(&sighand->siglock, flags);
- }
-
--#ifndef __ARCH_SYS_PTRACE
--asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
++}
++
+static u32
+ptrace_report(struct utrace_attached_engine *engine, struct task_struct *tsk,
+ int code)
- {
-- struct task_struct *child;
-- long ret;
++{
+ struct ptrace_state *state = (struct ptrace_state *) engine->data;
+ const struct utrace_regset *regset;
+
@@ -7169,29 +7301,24 @@
+
+ /*
+ * Set our QUIESCE flag right now, before notifying the tracer.
-+ * We do this before setting state->u.live.stopped rather than
++ * We do this before setting tsk->exit_code rather than
+ * by using UTRACE_ACTION_NEWSTATE in our return value, to
+ * ensure that the tracer can't get the notification and then
+ * 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);
+
-+ state->u.live.stopped = 1;
-+ state->u.live.reported = 0;
++ BUG_ON(code == 0);
+ tsk->exit_code = code;
+ do_notify(tsk, state->parent, CLD_TRAPPED);
+
@@ -7219,6 +7346,14 @@
+{
+ struct ptrace_state *state = (struct ptrace_state *) engine->data;
+
++ if (tsk->exit_code == 0 && unlikely(tsk->flags & PF_SIGNALED))
++ /*
++ * This can only mean that tsk->exit_code was clobbered
++ * by ptrace_update or ptrace_do_wait in a race with
++ * an asynchronous wakeup and exit for SIGKILL.
++ */
++ tsk->exit_code = SIGKILL;
++
+ if (tsk->parent == state->parent) {
+ /*
+ * This is a natural child, so we detach and let the normal
@@ -7234,7 +7369,6 @@
+ return UTRACE_ACTION_DETACH;
+ }
+
-+ state->u.live.reported = 0;
+ do_notify(tsk, state->parent, CLD_EXITED);
+ return UTRACE_ACTION_RESUME;
+}
@@ -7303,18 +7437,21 @@
+ child->pid, parent->pid);
+ }
+ else {
-+ int ret = ptrace_setup(child, child_engine,
-+ state->parent,
-+ state->u.live.options,
-+ state->u.live.cap_sys_ptrace);
-+ if (unlikely(ret != 0)) {
-+ BUG_ON(ret != -ENOMEM);
++ struct ptrace_state *child_state;
++ child_state = ptrace_setup(child, child_engine,
++ state->parent,
++ state->u.live.options,
++ state->u.live.cap_sys_ptrace,
++ NULL);
++ if (unlikely(IS_ERR(child_state))) {
++ BUG_ON(PTR_ERR(child_state) != -ENOMEM);
++ (void) utrace_detach(child, child_engine);
+ printk(KERN_ERR
+ "ptrace out of memory, lost child %d of %d",
+ child->pid, parent->pid);
-+ utrace_detach(child, child_engine);
+ }
+ else {
++ int ret;
+ sigaddset(&child->pending.signal, SIGSTOP);
+ set_tsk_thread_flag(child, TIF_SIGPENDING);
+ ret = ptrace_update(child, child_engine, 0);
@@ -7359,8 +7496,7 @@
+ state->u.live.have_eventmsg = 1;
+ state->u.live.u.eventmsg = child_pid;
+ return ptrace_event(engine, parent, PTRACE_EVENT_VFORK_DONE);
- }
--#endif /* __ARCH_SYS_PTRACE */
++}
+
+
+static u32
@@ -7387,7 +7523,6 @@
+ printk("ptrace %d jctl notify %d type %x exit_code %x\n",
+ tsk->pid, state->parent->pid, type, tsk->exit_code);
+#endif
-+ state->u.live.reported = 0;
+ do_notify(tsk, state->parent, type);
+ return UTRACE_JCTL_NOSIGCHLD;
+}
@@ -7426,7 +7561,8 @@
+ struct task_struct *tsk, struct pt_regs *regs)
+{
+ return ptrace_report_syscall(engine, tsk, regs, 1);
-+}
+ }
+-#endif /* __ARCH_SYS_PTRACE */
+
+static u32
+ptrace_report_syscall_exit(struct utrace_attached_engine *engine,
@@ -7517,7 +7653,7 @@
+#endif
--- linux-2.6/kernel/Makefile.utrace-ptrace-compat
+++ linux-2.6/kernel/Makefile
-@@ -51,6 +51,7 @@ obj-$(CONFIG_RELAY) += relay.o
+@@ -50,6 +50,7 @@ obj-$(CONFIG_RELAY) += relay.o
obj-$(CONFIG_UTS_NS) += utsname.o
obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
@@ -9981,7 +10117,7 @@
/*
* Note: it is necessary to treat pid and sig as unsigned ints, with the
* corresponding cast to a signed int to insure that the proper conversion
-@@ -1216,6 +1269,8 @@ no_signal:
+@@ -1226,6 +1279,8 @@ no_signal:
its frame, and we can clear the TIF_RESTORE_SIGMASK flag */
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
@@ -16506,7 +16642,7 @@
}
--- linux-2.6/arch/x86_64/kernel/traps.c.utrace-ptrace-compat
+++ linux-2.6/arch/x86_64/kernel/traps.c
-@@ -930,14 +930,6 @@ asmlinkage void __kprobes do_debug(struc
+@@ -864,14 +864,6 @@ asmlinkage void __kprobes do_debug(struc
*/
if (!user_mode(regs))
goto clear_TF_reenable;
- Previous message (by thread): rpms/gdb/devel gdb-6.5-bz218379-ppc-solib-trampoline-fix.patch, NONE, 1.1 gdb-6.5-bz218379-ppc-solib-trampoline-test.patch, NONE, 1.1 gdb-6.5-bz218379-solib-trampoline-lookup-lock-fix.patch, NONE, 1.1 gdb-6.5-matching_bfd_sections.patch, 1.1, 1.2 gdb.spec, 1.210, 1.211 gdb-6.5-bz200533-ppc-solib_trampoline.patch, 1.2, NONE
- Next message (by thread): rpms/kernel/FC-6/configs config-xen-generic,1.31,1.32
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the fedora-cvs-commits
mailing list