diff mbox series

[4/4] trace-cmd: Do not try to update parent's memory from a fork()-ed child

Message ID 20200430122222.101276-5-tz.stoyanov@gmail.com (mailing list archive)
State Superseded
Headers show
Series Few small trace-cmd fixes | expand

Commit Message

Tzvetomir Stoyanov (VMware) April 30, 2020, 12:22 p.m. UTC
When trace-cmd runs a command, specified with the "-F" flag, it forks a
child process and executes the command in its context. This child process
receives a full copy of the parents memory at the moment of fork(). When
it modifies this copy, the parent memory is not affected. Calling the
function update_task_filter() in the child context will operate on a valid
data, but will not update anything in the parent's databases.

Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com>
---
 tracecmd/trace-record.c | 34 +++++++++++++++++++++++++++++-----
 1 file changed, 29 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/tracecmd/trace-record.c b/tracecmd/trace-record.c
index 1e4d38fa..2b5cd42a 100644
--- a/tracecmd/trace-record.c
+++ b/tracecmd/trace-record.c
@@ -11,6 +11,7 @@ 
 #include <stdarg.h>
 #include <getopt.h>
 #include <time.h>
+#include <semaphore.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/time.h>
@@ -1487,18 +1488,35 @@  static int change_user(const char *user)
 	return 0;
 }
 
+#define TRACE_RUN_SEM	"trace_cmd_semaphore_run"
+#define TRACE_INIT_SEM	"trace_cmd_semaphore_init"
 static void run_cmd(enum trace_type type, const char *user, int argc, char **argv)
 {
+	sem_t *sem_init;
+	sem_t *sem_run;
 	int status;
 	int pid;
 
+	sem_init = sem_open(TRACE_INIT_SEM, O_CREAT, S_IRUSR|S_IWUSR, 0);
+	if (sem_init == SEM_FAILED)
+		die("failed to init trace_cmd init semaphore");
+
+	sem_run = sem_open(TRACE_RUN_SEM, O_CREAT, S_IRUSR|S_IWUSR, 0);
+	if (sem_run == SEM_FAILED) {
+		sem_close(sem_init);
+		sem_unlink(TRACE_INIT_SEM);
+		die("failed to init trace_cmd run semaphore");
+	}
+
 	if ((pid = fork()) < 0)
 		die("failed to fork");
 	if (!pid) {
 		/* child */
-		update_task_filter();
+		sem_wait(sem_init);
 		tracecmd_enable_tracing();
 		enable_ptrace();
+		sem_post(sem_run);
+
 		/*
 		 * If we are using stderr for stdout, switch
 		 * it back to the saved stdout for the code we run.
@@ -1519,11 +1537,17 @@  static void run_cmd(enum trace_type type, const char *user, int argc, char **arg
 			die("Failed to exec %s", argv[0]);
 		}
 	}
-	if (do_ptrace) {
-		add_filter_pid(pid, 0);
-		ptrace_attach(pid);
+	update_task_filter();
+	sem_post(sem_init);
+	sem_wait(sem_run);
+	sem_close(sem_init);
+	sem_unlink(TRACE_INIT_SEM);
+	sem_close(sem_run);
+	sem_unlink(TRACE_RUN_SEM);
+
+	if (do_ptrace)
 		ptrace_wait(type);
-	} else
+	else
 		trace_waitpid(type, pid, &status, 0);
 }