Merge branch 'ptrace' of git://git.kernel.org/pub/scm/linux/kernel/git/oleg/misc
* 'ptrace' of git://git.kernel.org/pub/scm/linux/kernel/git/oleg/misc: (39 commits) ptrace: do_wait(traced_leader_killed_by_mt_exec) can block forever ptrace: fix ptrace_signal() && STOP_DEQUEUED interaction connector: add an event for monitoring process tracers ptrace: dont send SIGSTOP on auto-attach if PT_SEIZED ptrace: mv send-SIGSTOP from do_fork() to ptrace_init_task() ptrace_init_task: initialize child->jobctl explicitly has_stopped_jobs: s/task_is_stopped/SIGNAL_STOP_STOPPED/ ptrace: make former thread ID available via PTRACE_GETEVENTMSG after PTRACE_EVENT_EXEC stop ptrace: wait_consider_task: s/same_thread_group/ptrace_reparented/ ptrace: kill real_parent_is_ptracer() in in favor of ptrace_reparented() ptrace: ptrace_reparented() should check same_thread_group() redefine thread_group_leader() as exit_signal >= 0 do not change dead_task->exit_signal kill task_detached() reparent_leader: check EXIT_DEAD instead of task_detached() make do_notify_parent() __must_check, update the callers __ptrace_detach: avoid task_detached(), check do_notify_parent() kill tracehook_notify_death() make do_notify_parent() return bool ptrace: s/tracehook_tracer_task()/ptrace_parent()/ ...
This commit is contained in:
27
fs/exec.c
27
fs/exec.c
@ -963,9 +963,18 @@ static int de_thread(struct task_struct *tsk)
|
||||
leader->group_leader = tsk;
|
||||
|
||||
tsk->exit_signal = SIGCHLD;
|
||||
leader->exit_signal = -1;
|
||||
|
||||
BUG_ON(leader->exit_state != EXIT_ZOMBIE);
|
||||
leader->exit_state = EXIT_DEAD;
|
||||
|
||||
/*
|
||||
* We are going to release_task()->ptrace_unlink() silently,
|
||||
* the tracer can sleep in do_wait(). EXIT_DEAD guarantees
|
||||
* the tracer wont't block again waiting for this thread.
|
||||
*/
|
||||
if (unlikely(leader->ptrace))
|
||||
__wake_up_parent(leader, leader->parent);
|
||||
write_unlock_irq(&tasklist_lock);
|
||||
|
||||
release_task(leader);
|
||||
@ -1225,7 +1234,12 @@ int check_unsafe_exec(struct linux_binprm *bprm)
|
||||
unsigned n_fs;
|
||||
int res = 0;
|
||||
|
||||
bprm->unsafe = tracehook_unsafe_exec(p);
|
||||
if (p->ptrace) {
|
||||
if (p->ptrace & PT_PTRACE_CAP)
|
||||
bprm->unsafe |= LSM_UNSAFE_PTRACE_CAP;
|
||||
else
|
||||
bprm->unsafe |= LSM_UNSAFE_PTRACE;
|
||||
}
|
||||
|
||||
n_fs = 1;
|
||||
spin_lock(&p->fs->lock);
|
||||
@ -1353,6 +1367,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
|
||||
unsigned int depth = bprm->recursion_depth;
|
||||
int try,retval;
|
||||
struct linux_binfmt *fmt;
|
||||
pid_t old_pid;
|
||||
|
||||
retval = security_bprm_check(bprm);
|
||||
if (retval)
|
||||
@ -1362,6 +1377,11 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
/* Need to fetch pid before load_binary changes it */
|
||||
rcu_read_lock();
|
||||
old_pid = task_pid_nr_ns(current, task_active_pid_ns(current->parent));
|
||||
rcu_read_unlock();
|
||||
|
||||
retval = -ENOENT;
|
||||
for (try=0; try<2; try++) {
|
||||
read_lock(&binfmt_lock);
|
||||
@ -1381,7 +1401,8 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
|
||||
bprm->recursion_depth = depth;
|
||||
if (retval >= 0) {
|
||||
if (depth == 0)
|
||||
tracehook_report_exec(fmt, bprm, regs);
|
||||
ptrace_event(PTRACE_EVENT_EXEC,
|
||||
old_pid);
|
||||
put_binfmt(fmt);
|
||||
allow_write_access(bprm->file);
|
||||
if (bprm->file)
|
||||
@ -1769,7 +1790,7 @@ static int zap_process(struct task_struct *start, int exit_code)
|
||||
|
||||
t = start;
|
||||
do {
|
||||
task_clear_group_stop_pending(t);
|
||||
task_clear_jobctl_pending(t, JOBCTL_PENDING_MASK);
|
||||
if (t != current && t->mm) {
|
||||
sigaddset(&t->pending.signal, SIGKILL);
|
||||
signal_wake_up(t, 1);
|
||||
|
Reference in New Issue
Block a user