Exemplo n.º 1
0
int main(int argc, char *argv[])
{
	char *name = NULL;

	if (seccomp_syscall_resolve_name("open") != __NR_open)
		goto fail;
	if (seccomp_syscall_resolve_name("socket") != __NR_socket)
		goto fail;
	if (seccomp_syscall_resolve_name("INVALID") != __NR_SCMP_ERROR)
		goto fail;

	if (seccomp_syscall_resolve_name_arch(SCMP_ARCH_NATIVE,
					      "open") != __NR_open)
		goto fail;
	if (seccomp_syscall_resolve_name_arch(SCMP_ARCH_NATIVE,
					      "socket") != __NR_socket)
		goto fail;
	if (seccomp_syscall_resolve_name_arch(SCMP_ARCH_NATIVE,
					      "INVALID") != __NR_SCMP_ERROR)
		goto fail;

	name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, __NR_open);
	if (name == NULL || strcmp(name, "open") != 0)
		goto fail;
	free(name);

	name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, __NR_socket);
	if (name == NULL || strcmp(name, "socket") != 0)
		goto fail;
	free(name);

	name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE,
						__NR_SCMP_ERROR);
	if (name != NULL)
		goto fail;
	free(name);

	return 0;

fail:
	if (name != NULL)
		free(name);
	return 1;
}
Exemplo n.º 2
0
static void do_trace(const struct signalfd_siginfo *si, bool *trace_init, FILE *learn) {
    int status;
    if (waitpid((pid_t)si->ssi_pid, &status, WNOHANG) != (pid_t)si->ssi_pid)
        errx(EXIT_FAILURE, "waitpid");

    if (WIFEXITED(status) || WIFSIGNALED(status) || !WIFSTOPPED(status))
        errx(EXIT_FAILURE, "unexpected ptrace event");

    int inject_signal = 0;
    if (*trace_init) {
        int signal = WSTOPSIG(status);
        if (signal != SIGTRAP || !(status & PTRACE_EVENT_SECCOMP))
            inject_signal = signal;
        else {
            errno = 0;
#ifdef __x86_64__
            long syscall = ptrace(PTRACE_PEEKUSER, si->ssi_pid, sizeof(long)*ORIG_RAX);
#else
            long syscall = ptrace(PTRACE_PEEKUSER, si->ssi_pid, sizeof(long)*ORIG_EAX);
#endif
            if (errno) err(EXIT_FAILURE, "ptrace");
            char *name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, (int)syscall);
            if (!name) errx(EXIT_FAILURE, "seccomp_syscall_resolve_num_arch");

            rewind(learn);
            char line[SYSCALL_NAME_MAX];
            while (fgets(line, sizeof line, learn)) {
                char *pos;
                if ((pos = strchr(line, '\n'))) *pos = '\0';
                if (!strcmp(name, line)) {
                    name = NULL;
                    break;
                }
            }

            if (name) {
                fprintf(learn, "%s\n", name);
                free(name);
            }
        }
    } else {
        check_posix(ptrace(PTRACE_SETOPTIONS, si->ssi_pid, 0, PTRACE_O_TRACESECCOMP), "ptrace");
        *trace_init = true;
    }
    check_posix(ptrace(PTRACE_CONT, si->ssi_pid, 0, inject_signal), "ptrace");
}
Exemplo n.º 3
0
static void
handle_syscall(pid_t pid)
{
    errno = 0;
    int syscalln = ptrace(PTRACE_PEEKUSER, pid, sizeof(long) * ORIG_RAX);
    if (errno) ERROR("ptrace(PTRACE_PEEKUSER) failed");

    switch (syscalln) {
    default:
        goto kill;
    }
kill:
    kill(pid, SIGKILL);
    char *rule = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, syscalln);
    if (!rule) ERROR("seccomp_syscall_resolve_num_arch() failed");
    FINISH(POE_SIGNALED, -1, "System call %s is blocked", rule);
allowed:
    ptrace(PTRACE_CONT, pid, 0, 0);
}