aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-06-28 22:13:39 -0400
committerOleg Nesterov <oleg@redhat.com>2011-07-01 12:51:49 -0400
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)
1358 unsigned int depth = bprm->recursion_depth; 1358 unsigned int depth = bprm->recursion_depth;
1359 int try,retval; 1359 int try,retval;
1360 struct linux_binfmt *fmt; 1360 struct linux_binfmt *fmt;
1361 pid_t old_pid;
1361 1362
1362 retval = security_bprm_check(bprm); 1363 retval = security_bprm_check(bprm);
1363 if (retval) 1364 if (retval)
@@ -1371,6 +1372,11 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
1371 if (retval) 1372 if (retval)
1372 return retval; 1373 return retval;
1373 1374
1375 /* Need to fetch pid before load_binary changes it */
1376 rcu_read_lock();
1377 old_pid = task_pid_nr_ns(current, task_active_pid_ns(current->parent));
1378 rcu_read_unlock();
1379
1374 retval = -ENOENT; 1380 retval = -ENOENT;
1375 for (try=0; try<2; try++) { 1381 for (try=0; try<2; try++) {
1376 read_lock(&binfmt_lock); 1382 read_lock(&binfmt_lock);
@@ -1390,7 +1396,8 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
1390 bprm->recursion_depth = depth; 1396 bprm->recursion_depth = depth;
1391 if (retval >= 0) { 1397 if (retval >= 0) {
1392 if (depth == 0) 1398 if (depth == 0)
1393 ptrace_event(PTRACE_EVENT_EXEC, 0); 1399 ptrace_event(PTRACE_EVENT_EXEC,
1400 old_pid);
1394 put_binfmt(fmt); 1401 put_binfmt(fmt);
1395 allow_write_access(bprm->file); 1402 allow_write_access(bprm->file);
1396 if (bprm->file) 1403 if (bprm->file)