Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to fork a process with compel #2377

Open
zhuizhuhaomeng opened this issue Mar 30, 2024 · 1 comment
Open

how to fork a process with compel #2377

zhuizhuhaomeng opened this issue Mar 30, 2024 · 1 comment

Comments

@zhuizhuhaomeng
Copy link

Description

I would like to fork a child in the tracee.
But I got a segment fault.

Steps to reproduce the issue:

This is the parasite code:

#include <unistd.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/prctl.h>

#include <compel/infect-rpc.h>
#include <compel/plugins/std/syscall.h>
#include <compel/plugins/std/log.h>
#include <plugins/std/infect.h>

/*
 * Stubs for std compel plugin.
 */
int compel_main(void *arg_p, unsigned int arg_s)
{
	return 0;
}
int parasite_trap_cmd(int cmd, void *args)
{
	return 0;
}
void parasite_cleanup(void)
{
}

#define ptr_to_u64(ptr)	   ((__u64)((uintptr_t)(ptr)))
#define PARASITE_CMD_CLONE PARASITE_USER_CMDS

int parasite_daemon_cmd(int cmd, void *args)
{
	struct timespec req = { .tv_sec = 1000, .tv_nsec = 0 };
	struct timespec rem = { .tv_sec = 0, .tv_nsec = 0 };

	if (cmd == PARASITE_CMD_CLONE) {
		int pidfd = -1;
		pid_t parent_tid = -1, pid = -1;
		struct clone_args args = {
			.stack = 0,
			.stack_size = 0,
			.parent_tid = ptr_to_u64(&parent_tid),
			.pidfd = ptr_to_u64(&pidfd),
			.flags = CLONE_CLEAR_SIGHAND,
			.exit_signal = 0, // SIGCHLD
		};

		pid = sys_clone3(&args, sizeof(args));
		if (pid < 0) {
			return -1;
		}

		if (pid == 0) {
			int i;
			for (i = 0; i < 10000; i++) {
				sys_nanosleep(&req, &rem);
			}
			sys_exit(0);

			return 0;
		}
	}

	return 0;
}

And this is the spy.c

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

#include <compel/log.h>
#include <compel/infect-rpc.h>
#include <compel/infect-util.h>

#include "parasite.h"

#define PARASITE_CMD_CLONE PARASITE_USER_CMDS

static void print_vmsg(unsigned int lvl, const char *fmt, va_list parms)
{
	printf("\tLC%u: ", lvl);
	vprintf(fmt, parms);
}

static int do_infection(int pid, int debug)
{
	//int child_pid;

#define err_and_ret(msg)              \
	do {                          \
		fprintf(stderr, msg); \
		return -1;            \
	} while (0)

	int state;
	struct parasite_ctl *ctl;
	struct infect_ctx *ictx;

	/* compel_log_init(print_vmsg, COMPEL_LOG_DEBUG); */
	if (debug) {
		compel_log_init(print_vmsg, COMPEL_LOG_DEBUG);
	} else {
		compel_log_init(print_vmsg, COMPEL_LOG_INFO);
	}

	printf("Stopping task\n");
	state = compel_stop_task(pid);
	if (state < 0)
		err_and_ret("Can't stop task");

	printf("Preparing parasite ctl\n");
	ctl = compel_prepare(pid);
	if (!ctl)
		err_and_ret("Can't prepare for infection");

	printf("Configuring contexts\n");

	/*
	 * First -- the infection context. Most of the stuff
	 * is already filled by compel_prepare(), just set the
	 * log descriptor for parasite side, library cannot
	 * live w/o it.
	 */
	ictx = compel_infect_ctx(ctl);
	ictx->log_fd = STDERR_FILENO;

	parasite_setup_c_header(ctl);

	printf("Infecting\n");
	if (compel_infect(ctl, 1, sizeof(int)))
		err_and_ret("Can't infect victim");

	if (compel_rpc_call(PARASITE_CMD_CLONE, ctl))
		err_and_ret("Can't run cmd");


	if (compel_rpc_sync(PARASITE_CMD_CLONE, ctl))
		err_and_ret("Con't finalize cmd");

	/*
	 * Done. Cure and resume the task.
	 */
	printf("Curing\n");
	if (compel_cure(ctl))
		err_and_ret("Can't cure victim");

	if (compel_resume_task(pid, state, state))
		err_and_ret("Can't unseize task");

	printf("Done\n");
	return 0;
}

int main(int argc, char **argv)
{
	int pid;
	int debug = 0;

	if (argc < 2) {
		fprintf(stderr, "%s PID DEBUG\n", argv[0]);
		return 1;
	}

	pid = atoi(argv[1]);

	if (argc >= 3) {
		debug = atoi(argv[2]);
	}

	/*
	 * Now do the infection with parasite.c
	 */

	printf("Infecting the tracee %d\n", pid);
	if (do_infection(pid, debug))
		return 1;

	return 0;
}

Describe the results you received:

[47871.778937] nginx[152231]: segfault at cccccccd ip 00000000cccccccd sp 00007ffff78c69a0 error 14 in libpcre2-8.so.0.10.2[7ffff5b51000+3000] likely on CPU 0 (core 0, socket 0)

Copy link

A friendly reminder that this issue had no activity for 30 days.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant