Commit 905f1272 authored by Oleg Nesterov's avatar Oleg Nesterov Committed by Willy Tarreau

ptrace: introduce signal_wake_up_state() and ptrace_signal_wake_up()

ptrace: introduce signal_wake_up_state() and ptrace_signal_wake_up()

CVE-2013-0871

BugLink: http://bugs.launchpad.net/bugs/1129192

Cleanup and preparation for the next change.

signal_wake_up(resume => true) is overused. None of ptrace/jctl callers
actually want to wakeup a TASK_WAKEKILL task, but they can't specify the
necessary mask.

Turn signal_wake_up() into signal_wake_up_state(state), reintroduce
signal_wake_up() as a trivial helper, and add ptrace_signal_wake_up()
which adds __TASK_TRACED.

This way ptrace_signal_wake_up() can work "inside" ptrace_request()
even if the tracee doesn't have the TASK_WAKEKILL bit set.
Signed-off-by: default avatarOleg Nesterov <oleg@redhat.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
(backported from commit 910ffdb1)

Conflicts:
	kernel/ptrace.c
	kernel/signal.c
Signed-off-by: default avatarLuis Henriques <luis.henriques@canonical.com>
Acked-by: default avatarColin King <colin.king@canonical.com>
Signed-off-by: default avatarTim Gardner <tim.gardner@canonical.com>
Signed-off-by: default avatarWilly Tarreau <w@1wt.eu>
parent fd2ab7dc
...@@ -2459,7 +2459,16 @@ static inline void thread_group_cputime_free(struct signal_struct *sig) ...@@ -2459,7 +2459,16 @@ static inline void thread_group_cputime_free(struct signal_struct *sig)
extern void recalc_sigpending_and_wake(struct task_struct *t); extern void recalc_sigpending_and_wake(struct task_struct *t);
extern void recalc_sigpending(void); extern void recalc_sigpending(void);
extern void signal_wake_up(struct task_struct *t, int resume_stopped); extern void signal_wake_up_state(struct task_struct *t, unsigned int state);
static inline void signal_wake_up(struct task_struct *t, bool resume)
{
signal_wake_up_state(t, resume ? TASK_WAKEKILL : 0);
}
static inline void ptrace_signal_wake_up(struct task_struct *t, bool resume)
{
signal_wake_up_state(t, resume ? __TASK_TRACED : 0);
}
/* /*
* Wrappers for p->thread_info->cpu access. No-op on UP. * Wrappers for p->thread_info->cpu access. No-op on UP.
......
...@@ -56,7 +56,7 @@ static void ptrace_untrace(struct task_struct *child) ...@@ -56,7 +56,7 @@ static void ptrace_untrace(struct task_struct *child)
child->signal->group_stop_count) child->signal->group_stop_count)
__set_task_state(child, TASK_STOPPED); __set_task_state(child, TASK_STOPPED);
else else
signal_wake_up(child, 1); ptrace_signal_wake_up(child, true);
} }
spin_unlock(&child->sighand->siglock); spin_unlock(&child->sighand->siglock);
} }
......
...@@ -516,23 +516,17 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) ...@@ -516,23 +516,17 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
* No need to set need_resched since signal event passing * No need to set need_resched since signal event passing
* goes through ->blocked * goes through ->blocked
*/ */
void signal_wake_up(struct task_struct *t, int resume) void signal_wake_up_state(struct task_struct *t, unsigned int state)
{ {
unsigned int mask;
set_tsk_thread_flag(t, TIF_SIGPENDING); set_tsk_thread_flag(t, TIF_SIGPENDING);
/* /*
* For SIGKILL, we want to wake it up in the stopped/traced/killable * TASK_WAKEKILL also means wake it up in the stopped/traced/killable
* case. We don't check t->state here because there is a race with it * case. We don't check t->state here because there is a race with it
* executing another processor and just now entering stopped state. * executing another processor and just now entering stopped state.
* By using wake_up_state, we ensure the process will wake up and * By using wake_up_state, we ensure the process will wake up and
* handle its death signal. * handle its death signal.
*/ */
mask = TASK_INTERRUPTIBLE; if (!wake_up_state(t, state | TASK_INTERRUPTIBLE))
if (resume)
mask |= TASK_WAKEKILL;
if (!wake_up_state(t, mask))
kick_process(t); kick_process(t);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment