Example #1
0
void procd_coldplug(void)
{
	char *argv[] = { "udevtrigger", NULL };

	umount2("/dev/pts", MNT_DETACH);
	umount2("/dev/", MNT_DETACH);
	mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755,size=512K");
	mkdir("/dev/shm", 0755);
	mkdir("/dev/pts", 0755);
	mount("devpts", "/dev/pts", "devpts", 0, 0);
	udevtrigger.cb = udevtrigger_complete;
	udevtrigger.pid = fork();
	if (!udevtrigger.pid) {
		execvp(argv[0], argv);
		ERROR("Failed to start coldplug\n");
		exit(-1);
	}

	if (udevtrigger.pid <= 0) {
		ERROR("Failed to start new coldplug instance\n");
		return;
	}

	uloop_process_add(&udevtrigger);

	DEBUG(4, "Launched coldplug instance, pid=%d\n", (int) udevtrigger.pid);
}
Example #2
0
static void fork_worker(struct init_action *a)
{
	int fd;
	pid_t p;

	a->proc.pid = fork();
	if (!a->proc.pid) {
		p = setsid();

		fd = dev_open(a->id);
		if (fd != -1)
		{
			dup2(fd, STDIN_FILENO);
			dup2(fd, STDOUT_FILENO);
			dup2(fd, STDERR_FILENO);
			if (fd > STDERR_FILENO)
				close(fd);
		}

		ioctl(STDIN_FILENO, TIOCSCTTY, 1);
		tcsetpgrp(STDIN_FILENO, p);

		execvp(a->argv[0], a->argv);
		ERROR("Failed to execute %s\n", a->argv[0]);
		exit(-1);
	}

	if (a->proc.pid > 0) {
		DEBUG(4, "Launched new %s action, pid=%d\n",
					a->handler->name,
					(int) a->proc.pid);
		uloop_process_add(&a->proc);
	}
}
Example #3
0
void
preinit(void)
{
	char *init[] = { "/bin/sh", "/etc/preinit", NULL };
	char *plug[] = { "/sbin/procd", "-h", "/etc/hotplug-preinit.json", NULL };
	int fd;

	LOG("- preinit -\n");

	plugd_proc.cb = plugd_proc_cb;
	plugd_proc.pid = fork();
	if (!plugd_proc.pid) {
		execvp(plug[0], plug);
		ERROR("Failed to start plugd\n");
		exit(-1);
	}
	if (plugd_proc.pid <= 0) {
		ERROR("Failed to start new plugd instance\n");
		return;
	}
	uloop_process_add(&plugd_proc);

	setenv("PREINIT", "1", 1);

	fd = creat("/tmp/.preinit", 0600);

	if (fd < 0)
		ERROR("Failed to create sentinel file\n");
	else
		close(fd);

	preinit_proc.cb = spawn_procd;
	preinit_proc.pid = fork();
	if (!preinit_proc.pid) {
		execvp(init[0], init);
		ERROR("Failed to start preinit\n");
		exit(-1);
	}
	if (preinit_proc.pid <= 0) {
		ERROR("Failed to start new preinit instance\n");
		return;
	}
	uloop_process_add(&preinit_proc);

	DEBUG(4, "Launched preinit instance, pid=%d\n", (int) preinit_proc.pid);
}
Example #4
0
void runqueue_process_add(struct runqueue *q, struct runqueue_process *p, pid_t pid)
{
	if (p->proc.pending)
		return;

	p->proc.pid = pid;
	p->proc.cb = __runqueue_proc_cb;
	if (!p->task.type)
		p->task.type = &runqueue_proc_type;
	uloop_process_add(&p->proc);
	if (!p->task.running)
		runqueue_task_add(q, &p->task, true);
}
Example #5
0
File: trace.c Project: asac/procd
static void tracer_cb(struct uloop_process *c, int ret)
{
	if (WIFSTOPPED(ret) && WSTOPSIG(ret) & 0x80) {
		if (!in_syscall) {
			int syscall = ptrace(PTRACE_PEEKUSER, c->pid, reg_syscall_nr);

			if (syscall < syscall_max) {
				syscall_count[syscall]++;
				if (debug)
					fprintf(stderr, "%s()\n", syscall_names[syscall]);
			} else if (debug) {
				fprintf(stderr, "syscal(%d)\n", syscall);
			}
		}
		in_syscall = !in_syscall;
	} else if (WIFEXITED(ret)) {
		uloop_end();
		return;
	}
	ptrace(PTRACE_SYSCALL, c->pid, 0, 0);
	uloop_process_add(&tracer);
}
Example #6
0
static void
http_new_client(struct uloop_fd *ufd, unsigned events)
{
	int status;
	struct timeval t;

	t.tv_sec = 60;
	t.tv_usec = 0;

	for (;;) {
		int client = accept(ufd->fd, NULL, NULL);

		/* set one minute timeout */
		if (setsockopt(ufd->fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&t, sizeof t)) {
			DD("setsockopt() failed\n");
		}

		if (client == -1)
			break;

		struct uloop_process *uproc = calloc(1, sizeof(*uproc));
		if (!uproc || (uproc->pid = fork()) == -1) {
			FREE(uproc);
			close(client);
		}

		if (uproc->pid != 0) {
			/* parent */
			/* register an event handler for when the child terminates */
			uproc->cb = http_del_client;
			uloop_process_add(uproc);
			close(client);
		} else {
			/* child */
			FILE *fp;
			char buffer[BUFSIZ];
			char *auth_digest;
			int8_t auth_status = 0;
			
			fp = fdopen(client, "r+");

			DDF("+++ RECEIVED HTTP REQUEST +++\n");
			while (fgets(buffer, sizeof(buffer), fp)) {
				char *username = config->local->username;
				char *password = config->local->password;
				if (!username || !password) {
					// if we dont have username or password configured proceed with connecting to ACS
					auth_status = 1;
				}
				else if (auth_digest = strstr(buffer, "Authorization: Digest ")) {
					if (http_digest_auth_check("GET", "/", auth_digest + strlen("Authorization: Digest "), REALM, username, password, 300) == MHD_YES)
						auth_status = 1;
					else {
						auth_status = 0;
						log_message(NAME, L_NOTICE, "Connection Request authorization failed\n");
					}
				}
				if (buffer[0] == '\r' || buffer[0] == '\n') {
					/* end of http request (empty line) */
					goto http_end_child;
				}
			}
error_child:
			/* here we are because of an error, e.g. timeout */
			status = ETIMEDOUT|ENOMEM;
			goto done_child;

http_end_child:
			fflush(fp);
			if (auth_status) {
				status = 0;
				fputs("HTTP/1.1 200 OK\r\n", fp);
				fputs("Content-Length: 0\r\n", fp);
			} else {
				status = EACCES;
				fputs("HTTP/1.1 401 Unauthorized\r\n", fp);
				fputs("Content-Length: 0\r\n", fp);
				fputs("Connection: close\r\n", fp);
				http_digest_auth_fail_response(fp, "GET", "/", REALM, OPAQUE);
				fputs("\r\n", fp);
			}
			fputs("\r\n", fp);
			goto done_child;

done_child:
			fclose(fp);
			DDF("--- RECEIVED HTTP REQUEST ---\n");
			exit(status);
		}
	}
}
Example #7
0
File: main.c Project: lynxis/netifd
int
netifd_start_process(const char **argv, char **env, struct netifd_process *proc)
{
	int pfds[2];
	int pid;

	netifd_kill_process(proc);

	if (pipe(pfds) < 0)
		return -1;

	if ((pid = fork()) < 0)
		goto error;

	if (!pid) {
		int i;

		if (env) {
			while (*env) {
				putenv(*env);
				env++;
			}
		}
		if (proc->dir_fd >= 0)
			if (fchdir(proc->dir_fd)) {}

		close(pfds[0]);

		for (i = 0; i <= 2; i++) {
			if (pfds[1] == i)
				continue;

			dup2(pfds[1], i);
		}

		if (pfds[1] > 2)
			close(pfds[1]);

		execvp(argv[0], (char **) argv);
		exit(127);
	}

	if (pid < 0)
		goto error;

	close(pfds[1]);
	proc->uloop.cb = netifd_process_cb;
	proc->uloop.pid = pid;
	uloop_process_add(&proc->uloop);
	list_add_tail(&proc->list, &process_list);

	system_fd_set_cloexec(pfds[0]);
	proc->log.stream.string_data = true;
	proc->log.stream.notify_read = netifd_process_log_read_cb;
	ustream_fd_init(&proc->log, pfds[0]);

	return 0;

error:
	close(pfds[0]);
	close(pfds[1]);
	return -1;
}
Example #8
0
File: trace.c Project: asac/procd
int main(int argc, char **argv, char **envp)
{
	char *json = NULL;
	int status, ch, policy = EPERM;
	pid_t child;

	while ((ch = getopt(argc, argv, "f:p:")) != -1) {
		switch (ch) {
		case 'f':
			json = optarg;
			break;
		case 'p':
			policy = atoi(optarg);
			break;
		}
	}

	argc -= optind;
	argv += optind;

	if (!argc)
		return -1;

	if (getenv("TRACE_DEBUG"))
		debug = 1;
	unsetenv("TRACE_DEBUG");

	child = fork();

	if (child == 0) {
		char **_argv = calloc(argc + 1, sizeof(char *));
		char **_envp;
		char preload[] = "LD_PRELOAD=/lib/libpreload-trace.so";
		int envc = 1;
		int ret;

		memcpy(_argv, argv, argc * sizeof(char *));

		while (envp[envc++])
			;

		_envp = calloc(envc, sizeof(char *));
		memcpy(&_envp[1], _envp, envc * sizeof(char *));
		*envp = preload;

		ret = execve(_argv[0], _argv, envp);
		ERROR("failed to exec %s: %s\n", _argv[0], strerror(errno));
		return ret;
	}

	if (child < 0)
		return -1;

	syscall_max = ARRAY_SIZE(syscall_names);
	syscall_count = calloc(syscall_max, sizeof(int));
	waitpid(child, &status, 0);
	if (!WIFSTOPPED(status)) {
		ERROR("failed to start %s\n", *argv);
		return -1;
	}

	ptrace(PTRACE_SETOPTIONS, child, 0, PTRACE_O_TRACESYSGOOD);
	ptrace(PTRACE_SYSCALL, child, 0, 0);

	uloop_init();
	tracer.pid = child;
	tracer.cb = tracer_cb;
	uloop_process_add(&tracer);
	uloop_run();
	uloop_done();

	if (!json)
		if (asprintf(&json, "/tmp/%s.%u.json", basename(*argv), child) < 0)
			ERROR("failed to allocate output path: %s\n", strerror(errno));

	print_syscalls(policy, json);

	return 0;
}