|
Packit Service |
8eee21 |
/**
|
|
Packit Service |
8eee21 |
* Seccomp Library API
|
|
Packit Service |
8eee21 |
*
|
|
Packit Service |
8eee21 |
* Copyright (c) 2012,2013 Red Hat <pmoore@redhat.com>
|
|
Packit Service |
8eee21 |
* Author: Paul Moore <paul@paul-moore.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 <endian.h>
|
|
Packit Service |
8eee21 |
#include <errno.h>
|
|
Packit Service |
8eee21 |
#include <inttypes.h>
|
|
Packit Service |
8eee21 |
#include <unistd.h>
|
|
Packit Service |
8eee21 |
#include <stdarg.h>
|
|
Packit Service |
8eee21 |
#include <stdlib.h>
|
|
Packit Service |
8eee21 |
#include <string.h>
|
|
Packit Service |
8eee21 |
#include <stdbool.h>
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
#include <seccomp.h>
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
#include "arch.h"
|
|
Packit Service |
8eee21 |
#include "db.h"
|
|
Packit Service |
8eee21 |
#include "gen_pfc.h"
|
|
Packit Service |
8eee21 |
#include "gen_bpf.h"
|
|
Packit Service |
8eee21 |
#include "system.h"
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
#define API __attribute__((visibility("default")))
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
const struct scmp_version library_version = {
|
|
Packit Service |
8eee21 |
.major = SCMP_VER_MAJOR,
|
|
Packit Service |
8eee21 |
.minor = SCMP_VER_MINOR,
|
|
Packit Service |
8eee21 |
.micro = SCMP_VER_MICRO,
|
|
Packit Service |
8eee21 |
};
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
unsigned int seccomp_api_level = 0;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/**
|
|
Packit Service |
8eee21 |
* Validate a filter context
|
|
Packit Service |
8eee21 |
* @param ctx the filter context
|
|
Packit Service |
8eee21 |
*
|
|
Packit Service |
8eee21 |
* Attempt to validate the provided filter context. Returns zero if the
|
|
Packit Service |
8eee21 |
* context is valid, negative values on failure.
|
|
Packit Service |
8eee21 |
*
|
|
Packit Service |
8eee21 |
*/
|
|
Packit Service |
8eee21 |
static int _ctx_valid(const scmp_filter_ctx *ctx)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
return db_col_valid((struct db_filter_col *)ctx);
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/**
|
|
Packit Service |
8eee21 |
* Validate a syscall number
|
|
Packit Service |
8eee21 |
* @param syscall the syscall number
|
|
Packit Service |
8eee21 |
*
|
|
Packit Service |
8eee21 |
* Attempt to perform basic syscall number validation. Returns zero of the
|
|
Packit Service |
8eee21 |
* syscall appears valid, negative values on failure.
|
|
Packit Service |
8eee21 |
*
|
|
Packit Service |
8eee21 |
*/
|
|
Packit Service |
8eee21 |
static int _syscall_valid(const struct db_filter_col *col, int syscall)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
/* syscall -1 is used by tracers to skip the syscall */
|
|
Packit Service |
8eee21 |
if (col->attr.api_tskip && syscall == -1)
|
|
Packit Service |
8eee21 |
return 0;
|
|
Packit Service |
8eee21 |
if (syscall <= -1 && syscall >= -99)
|
|
Packit Service |
8eee21 |
return -EINVAL;
|
|
Packit Service |
8eee21 |
return 0;
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/**
|
|
Packit Service |
8eee21 |
* Update the API level
|
|
Packit Service |
8eee21 |
*
|
|
Packit Service |
8eee21 |
* This function performs a series of tests to determine what functionality is
|
|
Packit Service |
8eee21 |
* supported given the current running environment (kernel, etc.). It is
|
|
Packit Service |
8eee21 |
* important to note that this function only does meaningful checks the first
|
|
Packit Service |
8eee21 |
* time it is run, the resulting API level is cached after this first run and
|
|
Packit Service |
8eee21 |
* used for all subsequent calls. The API level value is returned.
|
|
Packit Service |
8eee21 |
*
|
|
Packit Service |
8eee21 |
*/
|
|
Packit Service |
8eee21 |
static unsigned int _seccomp_api_update(void)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
unsigned int level = 1;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* if seccomp_api_level > 0 then it's already been set, we're done */
|
|
Packit Service |
8eee21 |
if (seccomp_api_level >= 1)
|
|
Packit Service |
8eee21 |
return seccomp_api_level;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE: level 1 is the base level, start checking at 2 */
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* level 2 */
|
|
Packit Service |
8eee21 |
if (sys_chk_seccomp_syscall() &&
|
|
Packit Service |
8eee21 |
sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC) == 1)
|
|
Packit Service |
8eee21 |
level = 2;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* level 3 */
|
|
Packit Service |
8eee21 |
if (level == 2 &&
|
|
Packit Service |
8eee21 |
sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_LOG) == 1 &&
|
|
Packit Service |
8eee21 |
sys_chk_seccomp_action(SCMP_ACT_LOG) == 1)
|
|
Packit Service |
8eee21 |
level = 3;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* update the stored api level and return */
|
|
Packit Service |
8eee21 |
seccomp_api_level = level;
|
|
Packit Service |
8eee21 |
return seccomp_api_level;
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API const struct scmp_version *seccomp_version(void)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
return &library_version;
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API unsigned int seccomp_api_get(void)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
/* update the api level, if needed */
|
|
Packit Service |
8eee21 |
return _seccomp_api_update();
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API int seccomp_api_set(unsigned int level)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
switch (level) {
|
|
Packit Service |
8eee21 |
case 1:
|
|
Packit Service |
8eee21 |
sys_set_seccomp_syscall(false);
|
|
Packit Service |
8eee21 |
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC, false);
|
|
Packit Service |
8eee21 |
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_LOG, false);
|
|
Packit Service |
8eee21 |
sys_set_seccomp_action(SCMP_ACT_LOG, false);
|
|
Packit Service |
8eee21 |
sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, false);
|
|
Packit Service |
8eee21 |
break;
|
|
Packit Service |
8eee21 |
case 2:
|
|
Packit Service |
8eee21 |
sys_set_seccomp_syscall(true);
|
|
Packit Service |
8eee21 |
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC, true);
|
|
Packit Service |
8eee21 |
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_LOG, false);
|
|
Packit Service |
8eee21 |
sys_set_seccomp_action(SCMP_ACT_LOG, false);
|
|
Packit Service |
8eee21 |
sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, false);
|
|
Packit Service |
8eee21 |
break;
|
|
Packit Service |
8eee21 |
case 3:
|
|
Packit Service |
8eee21 |
sys_set_seccomp_syscall(true);
|
|
Packit Service |
8eee21 |
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC, true);
|
|
Packit Service |
8eee21 |
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_LOG, true);
|
|
Packit Service |
8eee21 |
sys_set_seccomp_action(SCMP_ACT_LOG, true);
|
|
Packit Service |
8eee21 |
sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, true);
|
|
Packit Service |
8eee21 |
break;
|
|
Packit Service |
8eee21 |
default:
|
|
Packit Service |
8eee21 |
return -EINVAL;
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
seccomp_api_level = level;
|
|
Packit Service |
8eee21 |
return 0;
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API scmp_filter_ctx seccomp_init(uint32_t def_action)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
if (db_action_valid(def_action) < 0)
|
|
Packit Service |
8eee21 |
return NULL;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
return db_col_init(def_action);
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API int seccomp_reset(scmp_filter_ctx ctx, uint32_t def_action)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
struct db_filter_col *col = (struct db_filter_col *)ctx;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
if (ctx == NULL || db_action_valid(def_action) < 0)
|
|
Packit Service |
8eee21 |
return -EINVAL;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
return db_col_reset(col, def_action);
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API void seccomp_release(scmp_filter_ctx ctx)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
db_col_release((struct db_filter_col *)ctx);
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API int seccomp_merge(scmp_filter_ctx ctx_dst,
|
|
Packit Service |
8eee21 |
scmp_filter_ctx ctx_src)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
struct db_filter_col *col_dst = (struct db_filter_col *)ctx_dst;
|
|
Packit Service |
8eee21 |
struct db_filter_col *col_src = (struct db_filter_col *)ctx_src;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
if (db_col_valid(col_dst) || db_col_valid(col_src))
|
|
Packit Service |
8eee21 |
return -EINVAL;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE: only the default action, NNP, and TSYNC settings must match */
|
|
Packit Service |
8eee21 |
if ((col_dst->attr.act_default != col_src->attr.act_default) ||
|
|
Packit Service |
8eee21 |
(col_dst->attr.nnp_enable != col_src->attr.nnp_enable) ||
|
|
Packit Service |
8eee21 |
(col_dst->attr.tsync_enable != col_src->attr.tsync_enable))
|
|
Packit Service |
8eee21 |
return -EINVAL;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
return db_col_merge(col_dst, col_src);
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API uint32_t seccomp_arch_resolve_name(const char *arch_name)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
const struct arch_def *arch;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
if (arch_name == NULL)
|
|
Packit Service |
8eee21 |
return 0;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
arch = arch_def_lookup_name(arch_name);
|
|
Packit Service |
8eee21 |
if (arch == NULL)
|
|
Packit Service |
8eee21 |
return 0;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
return arch->token;
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API uint32_t seccomp_arch_native(void)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
return arch_def_native->token;
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API int seccomp_arch_exist(const scmp_filter_ctx ctx,
|
|
Packit Service |
8eee21 |
uint32_t arch_token)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
struct db_filter_col *col = (struct db_filter_col *)ctx;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
if (arch_token == 0)
|
|
Packit Service |
8eee21 |
arch_token = arch_def_native->token;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
if (arch_valid(arch_token))
|
|
Packit Service |
8eee21 |
return -EINVAL;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
return (db_col_arch_exist(col, arch_token) ? 0 : -EEXIST);
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API int seccomp_arch_add(scmp_filter_ctx ctx, uint32_t arch_token)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
const struct arch_def *arch;
|
|
Packit Service |
8eee21 |
struct db_filter_col *col = (struct db_filter_col *)ctx;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
if (arch_token == 0)
|
|
Packit Service |
8eee21 |
arch_token = arch_def_native->token;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
arch = arch_def_lookup(arch_token);
|
|
Packit Service |
8eee21 |
if (arch == NULL)
|
|
Packit Service |
8eee21 |
return -EINVAL;
|
|
Packit Service |
8eee21 |
if (db_col_arch_exist(col, arch_token))
|
|
Packit Service |
8eee21 |
return -EEXIST;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
return db_col_db_new(col, arch);
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API int seccomp_arch_remove(scmp_filter_ctx ctx, uint32_t arch_token)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
struct db_filter_col *col = (struct db_filter_col *)ctx;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
if (arch_token == 0)
|
|
Packit Service |
8eee21 |
arch_token = arch_def_native->token;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
if (arch_valid(arch_token))
|
|
Packit Service |
8eee21 |
return -EINVAL;
|
|
Packit Service |
8eee21 |
if (db_col_arch_exist(col, arch_token) != -EEXIST)
|
|
Packit Service |
8eee21 |
return -EEXIST;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
return db_col_db_remove(col, arch_token);
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API int seccomp_load(const scmp_filter_ctx ctx)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
struct db_filter_col *col;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
if (_ctx_valid(ctx))
|
|
Packit Service |
8eee21 |
return -EINVAL;
|
|
Packit Service |
8eee21 |
col = (struct db_filter_col *)ctx;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
return sys_filter_load(col);
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API int seccomp_attr_get(const scmp_filter_ctx ctx,
|
|
Packit Service |
8eee21 |
enum scmp_filter_attr attr, uint32_t *value)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
if (_ctx_valid(ctx))
|
|
Packit Service |
8eee21 |
return -EINVAL;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
return db_col_attr_get((const struct db_filter_col *)ctx, attr, value);
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API int seccomp_attr_set(scmp_filter_ctx ctx,
|
|
Packit Service |
8eee21 |
enum scmp_filter_attr attr, uint32_t value)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
if (_ctx_valid(ctx))
|
|
Packit Service |
8eee21 |
return -EINVAL;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
return db_col_attr_set((struct db_filter_col *)ctx, attr, value);
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API char *seccomp_syscall_resolve_num_arch(uint32_t arch_token, int num)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
const struct arch_def *arch;
|
|
Packit Service |
8eee21 |
const char *name;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
if (arch_token == 0)
|
|
Packit Service |
8eee21 |
arch_token = arch_def_native->token;
|
|
Packit Service |
8eee21 |
if (arch_valid(arch_token))
|
|
Packit Service |
8eee21 |
return NULL;
|
|
Packit Service |
8eee21 |
arch = arch_def_lookup(arch_token);
|
|
Packit Service |
8eee21 |
if (arch == NULL)
|
|
Packit Service |
8eee21 |
return NULL;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
name = arch_syscall_resolve_num(arch, num);
|
|
Packit Service |
8eee21 |
if (name == NULL)
|
|
Packit Service |
8eee21 |
return NULL;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
return strdup(name);
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API int seccomp_syscall_resolve_name_arch(uint32_t arch_token, const char *name)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
const struct arch_def *arch;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
if (name == NULL)
|
|
Packit Service |
8eee21 |
return __NR_SCMP_ERROR;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
if (arch_token == 0)
|
|
Packit Service |
8eee21 |
arch_token = arch_def_native->token;
|
|
Packit Service |
8eee21 |
if (arch_valid(arch_token))
|
|
Packit Service |
8eee21 |
return __NR_SCMP_ERROR;
|
|
Packit Service |
8eee21 |
arch = arch_def_lookup(arch_token);
|
|
Packit Service |
8eee21 |
if (arch == NULL)
|
|
Packit Service |
8eee21 |
return __NR_SCMP_ERROR;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
return arch_syscall_resolve_name(arch, name);
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API int seccomp_syscall_resolve_name_rewrite(uint32_t arch_token,
|
|
Packit Service |
8eee21 |
const char *name)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
int rc;
|
|
Packit Service |
8eee21 |
int syscall;
|
|
Packit Service |
8eee21 |
const struct arch_def *arch;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
if (name == NULL)
|
|
Packit Service |
8eee21 |
return __NR_SCMP_ERROR;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
if (arch_token == 0)
|
|
Packit Service |
8eee21 |
arch_token = arch_def_native->token;
|
|
Packit Service |
8eee21 |
if (arch_valid(arch_token))
|
|
Packit Service |
8eee21 |
return __NR_SCMP_ERROR;
|
|
Packit Service |
8eee21 |
arch = arch_def_lookup(arch_token);
|
|
Packit Service |
8eee21 |
if (arch == NULL)
|
|
Packit Service |
8eee21 |
return __NR_SCMP_ERROR;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
syscall = arch_syscall_resolve_name(arch, name);
|
|
Packit Service |
8eee21 |
if (syscall == __NR_SCMP_ERROR)
|
|
Packit Service |
8eee21 |
return __NR_SCMP_ERROR;
|
|
Packit Service |
8eee21 |
rc = arch_syscall_rewrite(arch, &syscall);
|
|
Packit Service |
8eee21 |
if (rc == -EDOM)
|
|
Packit Service |
8eee21 |
/* if we can't rewrite the syscall, just pass it through */
|
|
Packit Service |
8eee21 |
return syscall;
|
|
Packit Service |
8eee21 |
else if (rc < 0)
|
|
Packit Service |
8eee21 |
return __NR_SCMP_ERROR;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
return syscall;
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API int seccomp_syscall_resolve_name(const char *name)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
return seccomp_syscall_resolve_name_arch(SCMP_ARCH_NATIVE, name);
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API int seccomp_syscall_priority(scmp_filter_ctx ctx,
|
|
Packit Service |
8eee21 |
int syscall, uint8_t priority)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
struct db_filter_col *col = (struct db_filter_col *)ctx;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
if (db_col_valid(col) || _syscall_valid(col, syscall))
|
|
Packit Service |
8eee21 |
return -EINVAL;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
return db_col_syscall_priority(col, syscall, priority);
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API int seccomp_rule_add_array(scmp_filter_ctx ctx,
|
|
Packit Service |
8eee21 |
uint32_t action, int syscall,
|
|
Packit Service |
8eee21 |
unsigned int arg_cnt,
|
|
Packit Service |
8eee21 |
const struct scmp_arg_cmp *arg_array)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
int rc;
|
|
Packit Service |
8eee21 |
struct db_filter_col *col = (struct db_filter_col *)ctx;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
if (arg_cnt > ARG_COUNT_MAX)
|
|
Packit Service |
8eee21 |
return -EINVAL;
|
|
Packit Service |
8eee21 |
if (arg_cnt > 0 && arg_array == NULL)
|
|
Packit Service |
8eee21 |
return -EINVAL;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
if (db_col_valid(col) || _syscall_valid(col, syscall))
|
|
Packit Service |
8eee21 |
return -EINVAL;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
rc = db_action_valid(action);
|
|
Packit Service |
8eee21 |
if (rc < 0)
|
|
Packit Service |
8eee21 |
return rc;
|
|
Packit Service |
8eee21 |
if (action == col->attr.act_default)
|
|
Packit Service |
8eee21 |
return -EPERM;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
return db_col_rule_add(col, 0, action, syscall, arg_cnt, arg_array);
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API int seccomp_rule_add(scmp_filter_ctx ctx,
|
|
Packit Service |
8eee21 |
uint32_t action, int syscall,
|
|
Packit Service |
8eee21 |
unsigned int arg_cnt, ...)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
int rc;
|
|
Packit Service |
8eee21 |
int iter;
|
|
Packit Service |
8eee21 |
struct scmp_arg_cmp arg_array[ARG_COUNT_MAX];
|
|
Packit Service |
8eee21 |
va_list arg_list;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* arg_cnt is unsigned, so no need to check the lower bound */
|
|
Packit Service |
8eee21 |
if (arg_cnt > ARG_COUNT_MAX)
|
|
Packit Service |
8eee21 |
return -EINVAL;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
va_start(arg_list, arg_cnt);
|
|
Packit Service |
8eee21 |
for (iter = 0; iter < arg_cnt; ++iter)
|
|
Packit Service |
8eee21 |
arg_array[iter] = va_arg(arg_list, struct scmp_arg_cmp);
|
|
Packit Service |
8eee21 |
rc = seccomp_rule_add_array(ctx, action, syscall, arg_cnt, arg_array);
|
|
Packit Service |
8eee21 |
va_end(arg_list);
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
return rc;
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API int seccomp_rule_add_exact_array(scmp_filter_ctx ctx,
|
|
Packit Service |
8eee21 |
uint32_t action, int syscall,
|
|
Packit Service |
8eee21 |
unsigned int arg_cnt,
|
|
Packit Service |
8eee21 |
const struct scmp_arg_cmp *arg_array)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
int rc;
|
|
Packit Service |
8eee21 |
struct db_filter_col *col = (struct db_filter_col *)ctx;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
if (arg_cnt > ARG_COUNT_MAX)
|
|
Packit Service |
8eee21 |
return -EINVAL;
|
|
Packit Service |
8eee21 |
if (arg_cnt > 0 && arg_array == NULL)
|
|
Packit Service |
8eee21 |
return -EINVAL;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
if (db_col_valid(col) || _syscall_valid(col, syscall))
|
|
Packit Service |
8eee21 |
return -EINVAL;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
rc = db_action_valid(action);
|
|
Packit Service |
8eee21 |
if (rc < 0)
|
|
Packit Service |
8eee21 |
return rc;
|
|
Packit Service |
8eee21 |
if (action == col->attr.act_default)
|
|
Packit Service |
8eee21 |
return -EPERM;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
if (col->filter_cnt > 1)
|
|
Packit Service |
8eee21 |
return -EOPNOTSUPP;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
return db_col_rule_add(col, 1, action, syscall, arg_cnt, arg_array);
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API int seccomp_rule_add_exact(scmp_filter_ctx ctx,
|
|
Packit Service |
8eee21 |
uint32_t action, int syscall,
|
|
Packit Service |
8eee21 |
unsigned int arg_cnt, ...)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
int rc;
|
|
Packit Service |
8eee21 |
int iter;
|
|
Packit Service |
8eee21 |
struct scmp_arg_cmp arg_array[ARG_COUNT_MAX];
|
|
Packit Service |
8eee21 |
va_list arg_list;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* arg_cnt is unsigned, so no need to check the lower bound */
|
|
Packit Service |
8eee21 |
if (arg_cnt > ARG_COUNT_MAX)
|
|
Packit Service |
8eee21 |
return -EINVAL;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
va_start(arg_list, arg_cnt);
|
|
Packit Service |
8eee21 |
for (iter = 0; iter < arg_cnt; ++iter)
|
|
Packit Service |
8eee21 |
arg_array[iter] = va_arg(arg_list, struct scmp_arg_cmp);
|
|
Packit Service |
8eee21 |
rc = seccomp_rule_add_exact_array(ctx,
|
|
Packit Service |
8eee21 |
action, syscall, arg_cnt, arg_array);
|
|
Packit Service |
8eee21 |
va_end(arg_list);
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
return rc;
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API int seccomp_export_pfc(const scmp_filter_ctx ctx, int fd)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
if (_ctx_valid(ctx))
|
|
Packit Service |
8eee21 |
return -EINVAL;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
return gen_pfc_generate((struct db_filter_col *)ctx, fd);
|
|
Packit Service |
8eee21 |
}
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
/* NOTE - function header comment in include/seccomp.h */
|
|
Packit Service |
8eee21 |
API int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd)
|
|
Packit Service |
8eee21 |
{
|
|
Packit Service |
8eee21 |
int rc;
|
|
Packit Service |
8eee21 |
struct bpf_program *program;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
if (_ctx_valid(ctx))
|
|
Packit Service |
8eee21 |
return -EINVAL;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
program = gen_bpf_generate((struct db_filter_col *)ctx);
|
|
Packit Service |
8eee21 |
if (program == NULL)
|
|
Packit Service |
8eee21 |
return -ENOMEM;
|
|
Packit Service |
8eee21 |
rc = write(fd, program->blks, BPF_PGM_SIZE(program));
|
|
Packit Service |
8eee21 |
gen_bpf_release(program);
|
|
Packit Service |
8eee21 |
if (rc < 0)
|
|
Packit Service |
8eee21 |
return -errno;
|
|
Packit Service |
8eee21 |
|
|
Packit Service |
8eee21 |
return 0;
|
|
Packit Service |
8eee21 |
}
|