Blame tests/util.c

Packit Service 8eee21
/**
Packit Service 8eee21
 * Seccomp Library utility code for tests
Packit Service 8eee21
 *
Packit Service 8eee21
 * Copyright (c) 2012 Red Hat <eparis@redhat.com>
Packit Service 8eee21
 * Author: Eric Paris <eparis@redhat.com>
Packit Service 8eee21
 */
Packit Service 8eee21
Packit Service 8eee21
/*
Packit Service 8eee21
 * This library is free software; you can redistribute it and/or modify it
Packit Service 8eee21
 * under the terms of version 2.1 of the GNU Lesser General Public License as
Packit Service 8eee21
 * published by the Free Software Foundation.
Packit Service 8eee21
 *
Packit Service 8eee21
 * This library is distributed in the hope that it will be useful, but WITHOUT
Packit Service 8eee21
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
Packit Service 8eee21
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
Packit Service 8eee21
 * for more details.
Packit Service 8eee21
 *
Packit Service 8eee21
 * You should have received a copy of the GNU Lesser General Public License
Packit Service 8eee21
 * along with this library; if not, see <http://www.gnu.org/licenses>.
Packit Service 8eee21
 */
Packit Service 8eee21
Packit Service 8eee21
#include <errno.h>
Packit Service 8eee21
#include <fcntl.h>
Packit Service 8eee21
#include <getopt.h>
Packit Service 8eee21
#include <signal.h>
Packit Service 8eee21
#include <stdio.h>
Packit Service 8eee21
#include <string.h>
Packit Service 8eee21
#include <unistd.h>
Packit Service 8eee21
#include <sys/types.h>
Packit Service 8eee21
#include <sys/stat.h>
Packit Service 8eee21
Packit Service 8eee21
#include <seccomp.h>
Packit Service 8eee21
Packit Service 8eee21
#include "util.h"
Packit Service 8eee21
Packit Service 8eee21
/**
Packit Service 8eee21
 * SIGSYS signal handler
Packit Service 8eee21
 * @param nr the signal number
Packit Service 8eee21
 * @param info siginfo_t pointer
Packit Service 8eee21
 * @param void_context handler context
Packit Service 8eee21
 *
Packit Service 8eee21
 * Simple signal handler for SIGSYS which exits with error code 161.
Packit Service 8eee21
 *
Packit Service 8eee21
 */
Packit Service 8eee21
static void _trap_handler(int signal, siginfo_t *info, void *ctx)
Packit Service 8eee21
{
Packit Service 8eee21
	_exit(161);
Packit Service 8eee21
}
Packit Service 8eee21
Packit Service 8eee21
/**
Packit Service 8eee21
 * Parse the arguments passed to main
Packit Service 8eee21
 * @param argc the argument count
Packit Service 8eee21
 * @param argv the argument pointer
Packit Service 8eee21
 * @param opts the options structure
Packit Service 8eee21
 *
Packit Service 8eee21
 * This function parses the arguments passed to the test from the command line.
Packit Service 8eee21
 * Returns zero on success and negative values on failure.
Packit Service 8eee21
 *
Packit Service 8eee21
 */
Packit Service 8eee21
int util_getopt(int argc, char *argv[], struct util_options *opts)
Packit Service 8eee21
{
Packit Service 8eee21
	int rc = 0;
Packit Service 8eee21
Packit Service 8eee21
	if (opts == NULL)
Packit Service 8eee21
		return -EFAULT;
Packit Service 8eee21
Packit Service 8eee21
	memset(opts, 0, sizeof(*opts));
Packit Service 8eee21
	while (1) {
Packit Service 8eee21
		int c, option_index = 0;
Packit Service 8eee21
		const struct option long_options[] = {
Packit Service 8eee21
			{"bpf", no_argument, &(opts->bpf_flg), 1},
Packit Service 8eee21
			{"pfc", no_argument, &(opts->bpf_flg), 0},
Packit Service 8eee21
			{0, 0, 0, 0},
Packit Service 8eee21
		};
Packit Service 8eee21
Packit Service 8eee21
		c = getopt_long(argc, argv, "bp",
Packit Service 8eee21
				long_options, &option_index);
Packit Service 8eee21
		if (c == -1)
Packit Service 8eee21
			break;
Packit Service 8eee21
Packit Service 8eee21
		switch (c) {
Packit Service 8eee21
		case 0:
Packit Service 8eee21
			break;
Packit Service 8eee21
		case 'b':
Packit Service 8eee21
			opts->bpf_flg = 1;
Packit Service 8eee21
			break;
Packit Service 8eee21
		case 'p':
Packit Service 8eee21
			opts->bpf_flg = 0;
Packit Service 8eee21
			break;
Packit Service 8eee21
		default:
Packit Service 8eee21
			rc = -EINVAL;
Packit Service 8eee21
			break;
Packit Service 8eee21
		}
Packit Service 8eee21
	}
Packit Service 8eee21
Packit Service 8eee21
	if (rc == -EINVAL || optind < argc) {
Packit Service 8eee21
		fprintf(stderr, "usage %s: [--bpf,-b] [--pfc,-p]\n", argv[0]);
Packit Service 8eee21
		rc = -EINVAL;
Packit Service 8eee21
	}
Packit Service 8eee21
Packit Service 8eee21
	return rc;
Packit Service 8eee21
}
Packit Service 8eee21
Packit Service 8eee21
/**
Packit Service 8eee21
 * Output the filter in either BPF or PFC
Packit Service 8eee21
 * @param opts the options structure
Packit Service 8eee21
 * @param ctx the filter context
Packit Service 8eee21
 *
Packit Service 8eee21
 * This function outputs the seccomp filter to stdout in either BPF or PFC
Packit Service 8eee21
 * format depending on the test paramaeters supplied by @opts.
Packit Service 8eee21
 *
Packit Service 8eee21
 */
Packit Service 8eee21
int util_filter_output(const struct util_options *opts,
Packit Service 8eee21
		       const scmp_filter_ctx ctx)
Packit Service 8eee21
{
Packit Service 8eee21
	int rc;
Packit Service 8eee21
Packit Service 8eee21
	if (opts == NULL)
Packit Service 8eee21
		return -EFAULT;
Packit Service 8eee21
Packit Service 8eee21
	if (opts->bpf_flg)
Packit Service 8eee21
		rc = seccomp_export_bpf(ctx, STDOUT_FILENO);
Packit Service 8eee21
	else
Packit Service 8eee21
		rc = seccomp_export_pfc(ctx, STDOUT_FILENO);
Packit Service 8eee21
Packit Service 8eee21
	return rc;
Packit Service 8eee21
}
Packit Service 8eee21
Packit Service 8eee21
/**
Packit Service 8eee21
 * Install a TRAP action signal handler
Packit Service 8eee21
 *
Packit Service 8eee21
 * This function installs the TRAP action signal handler and is based on
Packit Service 8eee21
 * examples from Will Drewry and Kees Cook.  Returns zero on success, negative
Packit Service 8eee21
 * values on failure.
Packit Service 8eee21
 *
Packit Service 8eee21
 */
Packit Service 8eee21
int util_trap_install(void)
Packit Service 8eee21
{
Packit Service 8eee21
	struct sigaction signal_handler;
Packit Service 8eee21
	sigset_t signal_mask;
Packit Service 8eee21
Packit Service 8eee21
	memset(&signal_handler, 0, sizeof(signal_handler));
Packit Service 8eee21
	sigemptyset(&signal_mask);
Packit Service 8eee21
	sigaddset(&signal_mask, SIGSYS);
Packit Service 8eee21
Packit Service 8eee21
	signal_handler.sa_sigaction = &_trap_handler;
Packit Service 8eee21
	signal_handler.sa_flags = SA_SIGINFO;
Packit Service 8eee21
	if (sigaction(SIGSYS, &signal_handler, NULL) < 0)
Packit Service 8eee21
		return -errno;
Packit Service 8eee21
	if (sigprocmask(SIG_UNBLOCK, &signal_mask, NULL))
Packit Service 8eee21
		return -errno;
Packit Service 8eee21
Packit Service 8eee21
	return 0;
Packit Service 8eee21
}
Packit Service 8eee21
Packit Service 8eee21
/**
Packit Service 8eee21
 * Parse a filter action string into an action value
Packit Service 8eee21
 * @param action the action string
Packit Service 8eee21
 *
Packit Service 8eee21
 * Parse a seccomp action string into the associated integer value.  Returns
Packit Service 8eee21
 * the correct value on success, -1 on failure.
Packit Service 8eee21
 *
Packit Service 8eee21
 */
Packit Service 8eee21
int util_action_parse(const char *action)
Packit Service 8eee21
{
Packit Service 8eee21
	if (action == NULL)
Packit Service 8eee21
		return -1;
Packit Service 8eee21
Packit Service 8eee21
	if (strcasecmp(action, "KILL") == 0)
Packit Service 8eee21
		return SCMP_ACT_KILL;
Packit Service 8eee21
	if (strcasecmp(action, "KILL_PROCESS") == 0)
Packit Service 8eee21
		return SCMP_ACT_KILL_PROCESS;
Packit Service 8eee21
	else if (strcasecmp(action, "TRAP") == 0)
Packit Service 8eee21
		return SCMP_ACT_TRAP;
Packit Service 8eee21
	else if (strcasecmp(action, "ERRNO") == 0)
Packit Service 8eee21
		return SCMP_ACT_ERRNO(163);
Packit Service 8eee21
	else if (strcasecmp(action, "TRACE") == 0)
Packit Service 8eee21
		return -1; /* not yet supported */
Packit Service 8eee21
	else if (strcasecmp(action, "ALLOW") == 0)
Packit Service 8eee21
		return SCMP_ACT_ALLOW;
Packit Service 8eee21
	else if (strcasecmp(action, "LOG") == 0)
Packit Service 8eee21
		return SCMP_ACT_LOG;
Packit Service 8eee21
Packit Service 8eee21
	return -1;
Packit Service 8eee21
}
Packit Service 8eee21
Packit Service 8eee21
/**
Packit Service 8eee21
 * Write a string to a file
Packit Service 8eee21
 * @param path the file path
Packit Service 8eee21
 *
Packit Service 8eee21
 * Open the specified file, write a string to the file, and close the file.
Packit Service 8eee21
 * Return zero on success, negative values on error.
Packit Service 8eee21
 *
Packit Service 8eee21
 */
Packit Service 8eee21
int util_file_write(const char *path)
Packit Service 8eee21
{
Packit Service 8eee21
	int fd;
Packit Service 8eee21
	const char buf[] = "testing";
Packit Service 8eee21
	ssize_t buf_len = strlen(buf);
Packit Service 8eee21
Packit Service 8eee21
	fd = open(path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
Packit Service 8eee21
	if (fd < 0)
Packit Service 8eee21
		return errno;
Packit Service 8eee21
	if (write(fd, buf, buf_len) < buf_len) {
Packit Service 8eee21
		int rc = errno;
Packit Service 8eee21
		close(fd);
Packit Service 8eee21
		return rc;
Packit Service 8eee21
	}
Packit Service 8eee21
	if (close(fd) < 0)
Packit Service 8eee21
		return errno;
Packit Service 8eee21
Packit Service 8eee21
	return 0;
Packit Service 8eee21
}