diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-22 18:06:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-22 18:06:50 -0400 |
commit | 8209f53d79444747782a28520187abaf689761f2 (patch) | |
tree | 726270ea29e037f026d77a99787b9d844531ac42 /fs/exec.c | |
parent | 22a3b9771117d566def0150ea787fcc95f16e724 (diff) | |
parent | eac1b5e57d7abc836e78fd3fbcf77dbeed01edc9 (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.c | 27 |
1 files changed, 24 insertions, 3 deletions
@@ -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); |