Skip to content

Commit 910ffdb

Browse files
oleg-nesterovtorvalds
authored andcommitted
ptrace: introduce signal_wake_up_state() and ptrace_signal_wake_up()
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: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 9a92841 commit 910ffdb

File tree

3 files changed

+18
-15
lines changed

3 files changed

+18
-15
lines changed

include/linux/sched.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2714,7 +2714,16 @@ static inline void thread_group_cputime_init(struct signal_struct *sig)
27142714
extern void recalc_sigpending_and_wake(struct task_struct *t);
27152715
extern void recalc_sigpending(void);
27162716

2717-
extern void signal_wake_up(struct task_struct *t, int resume_stopped);
2717+
extern void signal_wake_up_state(struct task_struct *t, unsigned int state);
2718+
2719+
static inline void signal_wake_up(struct task_struct *t, bool resume)
2720+
{
2721+
signal_wake_up_state(t, resume ? TASK_WAKEKILL : 0);
2722+
}
2723+
static inline void ptrace_signal_wake_up(struct task_struct *t, bool resume)
2724+
{
2725+
signal_wake_up_state(t, resume ? __TASK_TRACED : 0);
2726+
}
27182727

27192728
/*
27202729
* Wrappers for p->thread_info->cpu access. No-op on UP.

kernel/ptrace.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ void __ptrace_unlink(struct task_struct *child)
117117
* TASK_KILLABLE sleeps.
118118
*/
119119
if (child->jobctl & JOBCTL_STOP_PENDING || task_is_traced(child))
120-
signal_wake_up(child, task_is_traced(child));
120+
ptrace_signal_wake_up(child, true);
121121

122122
spin_unlock(&child->sighand->siglock);
123123
}
@@ -317,7 +317,7 @@ static int ptrace_attach(struct task_struct *task, long request,
317317
*/
318318
if (task_is_stopped(task) &&
319319
task_set_jobctl_pending(task, JOBCTL_TRAP_STOP | JOBCTL_TRAPPING))
320-
signal_wake_up(task, 1);
320+
signal_wake_up_state(task, __TASK_STOPPED);
321321

322322
spin_unlock(&task->sighand->siglock);
323323

@@ -737,7 +737,7 @@ int ptrace_request(struct task_struct *child, long request,
737737
* tracee into STOP.
738738
*/
739739
if (likely(task_set_jobctl_pending(child, JOBCTL_TRAP_STOP)))
740-
signal_wake_up(child, child->jobctl & JOBCTL_LISTENING);
740+
ptrace_signal_wake_up(child, child->jobctl & JOBCTL_LISTENING);
741741

742742
unlock_task_sighand(child, &flags);
743743
ret = 0;
@@ -763,7 +763,7 @@ int ptrace_request(struct task_struct *child, long request,
763763
* start of this trap and now. Trigger re-trap.
764764
*/
765765
if (child->jobctl & JOBCTL_TRAP_NOTIFY)
766-
signal_wake_up(child, true);
766+
ptrace_signal_wake_up(child, true);
767767
ret = 0;
768768
}
769769
unlock_task_sighand(child, &flags);

kernel/signal.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -680,23 +680,17 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
680680
* No need to set need_resched since signal event passing
681681
* goes through ->blocked
682682
*/
683-
void signal_wake_up(struct task_struct *t, int resume)
683+
void signal_wake_up_state(struct task_struct *t, unsigned int state)
684684
{
685-
unsigned int mask;
686-
687685
set_tsk_thread_flag(t, TIF_SIGPENDING);
688-
689686
/*
690-
* For SIGKILL, we want to wake it up in the stopped/traced/killable
687+
* TASK_WAKEKILL also means wake it up in the stopped/traced/killable
691688
* case. We don't check t->state here because there is a race with it
692689
* executing another processor and just now entering stopped state.
693690
* By using wake_up_state, we ensure the process will wake up and
694691
* handle its death signal.
695692
*/
696-
mask = TASK_INTERRUPTIBLE;
697-
if (resume)
698-
mask |= TASK_WAKEKILL;
699-
if (!wake_up_state(t, mask))
693+
if (!wake_up_state(t, state | TASK_INTERRUPTIBLE))
700694
kick_process(t);
701695
}
702696

@@ -844,7 +838,7 @@ static void ptrace_trap_notify(struct task_struct *t)
844838
assert_spin_locked(&t->sighand->siglock);
845839

846840
task_set_jobctl_pending(t, JOBCTL_TRAP_NOTIFY);
847-
signal_wake_up(t, t->jobctl & JOBCTL_LISTENING);
841+
ptrace_signal_wake_up(t, t->jobctl & JOBCTL_LISTENING);
848842
}
849843

850844
/*

0 commit comments

Comments
 (0)