summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-06-29 04:13:39 +0200
committerOleg Nesterov <oleg@redhat.com>2011-07-01 18:51:49 +0200
commitbb188d7e64deb0e9cf13a99f44ae0065de5352d6 (patch)
tree3425b09bf6217ef4b59e82cec150d2af1ec16f9f /fs
parent479bf98c1c29b40d86e40a4e6e4944c2f03d9493 (diff)
ptrace: make former thread ID available via PTRACE_GETEVENTMSG after PTRACE_EVENT_EXEC stop
When multithreaded program execs under ptrace, all traced threads report WIFEXITED status, except for thread group leader and the thread which execs. Unless tracer tracks thread group relationship between tracees, which is a nontrivial task, it will not detect that execed thread no longer exists. This patch allows tracer to figure out which thread performed this exec, by requesting PTRACE_GETEVENTMSG in PTRACE_EVENT_EXEC stop. Another, samller problem which is solved by this patch is that tracer now can figure out which of the several concurrent execs in multithreaded program succeeded. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/exec.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/fs/exec.c b/fs/exec.c
index c3d517bfdd27..b08367abf30e 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1358,6 +1358,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)
@@ -1371,6 +1372,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);
@@ -1390,7 +1396,8 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
bprm->recursion_depth = depth;
if (retval >= 0) {
if (depth == 0)
- ptrace_event(PTRACE_EVENT_EXEC, 0);
+ ptrace_event(PTRACE_EVENT_EXEC,
+ old_pid);
put_binfmt(fmt);
allow_write_access(bprm->file);
if (bprm->file)