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 | |
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')
-rw-r--r-- | fs/exec.c | 27 | ||||
-rw-r--r-- | fs/proc/array.c | 2 | ||||
-rw-r--r-- | fs/proc/base.c | 2 |
3 files changed, 26 insertions, 5 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); |
diff --git a/fs/proc/array.c b/fs/proc/array.c index 9b45ee84fbcc..3a1dafd228d1 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
@@ -172,7 +172,7 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns, | |||
172 | task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0; | 172 | task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0; |
173 | tpid = 0; | 173 | tpid = 0; |
174 | if (pid_alive(p)) { | 174 | if (pid_alive(p)) { |
175 | struct task_struct *tracer = tracehook_tracer_task(p); | 175 | struct task_struct *tracer = ptrace_parent(p); |
176 | if (tracer) | 176 | if (tracer) |
177 | tpid = task_pid_nr_ns(tracer, ns); | 177 | tpid = task_pid_nr_ns(tracer, ns); |
178 | } | 178 | } |
diff --git a/fs/proc/base.c b/fs/proc/base.c index fc5bc2767692..c47719aaadef 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -216,7 +216,7 @@ static struct mm_struct *__check_mem_permission(struct task_struct *task) | |||
216 | if (task_is_stopped_or_traced(task)) { | 216 | if (task_is_stopped_or_traced(task)) { |
217 | int match; | 217 | int match; |
218 | rcu_read_lock(); | 218 | rcu_read_lock(); |
219 | match = (tracehook_tracer_task(task) == current); | 219 | match = (ptrace_parent(task) == current); |
220 | rcu_read_unlock(); | 220 | rcu_read_unlock(); |
221 | if (match && ptrace_may_access(task, PTRACE_MODE_ATTACH)) | 221 | if (match && ptrace_may_access(task, PTRACE_MODE_ATTACH)) |
222 | return mm; | 222 | return mm; |