aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-22 18:06:50 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-22 18:06:50 -0400
commit8209f53d79444747782a28520187abaf689761f2 (patch)
tree726270ea29e037f026d77a99787b9d844531ac42 /fs/exec.c
parent22a3b9771117d566def0150ea787fcc95f16e724 (diff)
parenteac1b5e57d7abc836e78fd3fbcf77dbeed01edc9 (diff)
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()/ ...
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 6075a1e727ae..d9576f261815 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -963,9 +963,18 @@ static int de_thread(struct task_struct *tsk)
963 leader->group_leader = tsk; 963 leader->group_leader = tsk;
964 964
965 tsk->exit_signal = SIGCHLD; 965 tsk->exit_signal = SIGCHLD;
966 leader->exit_signal = -1;
966 967
967 BUG_ON(leader->exit_state != EXIT_ZOMBIE); 968 BUG_ON(leader->exit_state != EXIT_ZOMBIE);
968 leader->exit_state = EXIT_DEAD; 969 leader->exit_state = EXIT_DEAD;
970
971 /*
972 * We are going to release_task()->ptrace_unlink() silently,
973 * the tracer can sleep in do_wait(). EXIT_DEAD guarantees
974 * the tracer wont't block again waiting for this thread.
975 */
976 if (unlikely(leader->ptrace))
977 __wake_up_parent(leader, leader->parent);
969 write_unlock_irq(&tasklist_lock); 978 write_unlock_irq(&tasklist_lock);
970 979
971 release_task(leader); 980 release_task(leader);
@@ -1225,7 +1234,12 @@ int check_unsafe_exec(struct linux_binprm *bprm)
1225 unsigned n_fs; 1234 unsigned n_fs;
1226 int res = 0; 1235 int res = 0;
1227 1236
1228 bprm->unsafe = tracehook_unsafe_exec(p); 1237 if (p->ptrace) {
1238 if (p->ptrace & PT_PTRACE_CAP)
1239 bprm->unsafe |= LSM_UNSAFE_PTRACE_CAP;
1240 else
1241 bprm->unsafe |= LSM_UNSAFE_PTRACE;
1242 }
1229 1243
1230 n_fs = 1; 1244 n_fs = 1;
1231 spin_lock(&p->fs->lock); 1245 spin_lock(&p->fs->lock);
@@ -1353,6 +1367,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
1353 unsigned int depth = bprm->recursion_depth; 1367 unsigned int depth = bprm->recursion_depth;
1354 int try,retval; 1368 int try,retval;
1355 struct linux_binfmt *fmt; 1369 struct linux_binfmt *fmt;
1370 pid_t old_pid;
1356 1371
1357 retval = security_bprm_check(bprm); 1372 retval = security_bprm_check(bprm);
1358 if (retval) 1373 if (retval)
@@ -1362,6 +1377,11 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
1362 if (retval) 1377 if (retval)
1363 return retval; 1378 return retval;
1364 1379
1380 /* Need to fetch pid before load_binary changes it */
1381 rcu_read_lock();
1382 old_pid = task_pid_nr_ns(current, task_active_pid_ns(current->parent));
1383 rcu_read_unlock();
1384
1365 retval = -ENOENT; 1385 retval = -ENOENT;
1366 for (try=0; try<2; try++) { 1386 for (try=0; try<2; try++) {
1367 read_lock(&binfmt_lock); 1387 read_lock(&binfmt_lock);
@@ -1381,7 +1401,8 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
1381 bprm->recursion_depth = depth; 1401 bprm->recursion_depth = depth;
1382 if (retval >= 0) { 1402 if (retval >= 0) {
1383 if (depth == 0) 1403 if (depth == 0)
1384 tracehook_report_exec(fmt, bprm, regs); 1404 ptrace_event(PTRACE_EVENT_EXEC,
1405 old_pid);
1385 put_binfmt(fmt); 1406 put_binfmt(fmt);
1386 allow_write_access(bprm->file); 1407 allow_write_access(bprm->file);
1387 if (bprm->file) 1408 if (bprm->file)
@@ -1769,7 +1790,7 @@ static int zap_process(struct task_struct *start, int exit_code)
1769 1790
1770 t = start; 1791 t = start;
1771 do { 1792 do {
1772 task_clear_group_stop_pending(t); 1793 task_clear_jobctl_pending(t, JOBCTL_PENDING_MASK);
1773 if (t != current && t->mm) { 1794 if (t != current && t->mm) {
1774 sigaddset(&t->pending.signal, SIGKILL); 1795 sigaddset(&t->pending.signal, SIGKILL);
1775 signal_wake_up(t, 1); 1796 signal_wake_up(t, 1);