switched to a more generic way of handling the sandbox configuration

This commit is contained in:
Cristian Toader 2013-09-02 13:54:43 +03:00
parent fe6e2733ab
commit b4b0eddd29
2 changed files with 107 additions and 49 deletions

View File

@ -24,6 +24,7 @@
#include "orconfig.h"
#include "torint.h"
#include "util.h"
#include "tor_queue.h"
#if defined(HAVE_SECCOMP_H) && defined(__linux__)
#define USE_LIBSECCOMP
@ -156,9 +157,12 @@ sb_execve(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
// for each dynamic parameter filters
for (elem = filter; elem != NULL; elem = elem->next) {
if (elem->prot == 1 && elem->syscall == SCMP_SYS(execve)) {
smp_param_t *param = (smp_param_t*) elem->param;
if (param != NULL && param->prot == 1 && param->syscall
== SCMP_SYS(execve)) {
rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(execve), 1,
SCMP_CMP(0, SCMP_CMP_EQ, elem->param));
SCMP_CMP(0, SCMP_CMP_EQ, param->value));
if (rc != 0) {
log_err(LD_BUG,"(Sandbox) failed to add execve syscall, received "
"libseccomp error %d", rc);
@ -266,9 +270,12 @@ sb_open(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
// for each dynamic parameter filters
for (elem = filter; elem != NULL; elem = elem->next) {
if (elem->prot == 1 && elem->syscall == SCMP_SYS(open)) {
smp_param_t *param = elem->param;
if (param != NULL && param->prot == 1 && param->syscall
== SCMP_SYS(open)) {
rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 1,
SCMP_CMP(0, SCMP_CMP_EQ, elem->param));
SCMP_CMP(0, SCMP_CMP_EQ, param->value));
if (rc != 0) {
log_err(LD_BUG,"(Sandbox) failed to add open syscall, received "
"libseccomp error %d", rc);
@ -297,10 +304,13 @@ sb_openat(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
// for each dynamic parameter filters
for (elem = filter; elem != NULL; elem = elem->next) {
if (elem->prot == 1 && elem->syscall == SCMP_SYS(openat)) {
smp_param_t *param = elem->param;
if (param != NULL && param->prot == 1 && param->syscall
== SCMP_SYS(openat)) {
rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat), 1,
SCMP_CMP(0, SCMP_CMP_EQ, AT_FDCWD),
SCMP_CMP(1, SCMP_CMP_EQ, elem->param),
SCMP_CMP(1, SCMP_CMP_EQ, param->value),
SCMP_CMP(2, SCMP_CMP_EQ, O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|
O_CLOEXEC));
if (rc != 0) {
@ -618,10 +628,12 @@ sb_stat64(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
// for each dynamic parameter filters
for (elem = filter; elem != NULL; elem = elem->next) {
if (elem->prot == 1 && (elem->syscall == SCMP_SYS(open) ||
elem->syscall == SCMP_SYS(stat64))) {
smp_param_t *param = elem->param;
if (param != NULL && param->prot == 1 && (param->syscall == SCMP_SYS(open)
|| param->syscall == SCMP_SYS(stat64))) {
rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(stat64), 1,
SCMP_CMP(0, SCMP_CMP_EQ, elem->param));
SCMP_CMP(0, SCMP_CMP_EQ, param->value));
if (rc != 0) {
log_err(LD_BUG,"(Sandbox) failed to add open syscall, received "
"libseccomp error %d", rc);
@ -660,21 +672,23 @@ static sandbox_filter_func_t filter_func[] = {
};
const char*
sandbox_intern_string(const char *param)
sandbox_intern_string(const char *str)
{
sandbox_cfg_t *elem;
if (param == NULL)
if (str == NULL)
return NULL;
for (elem = filter_dynamic; elem != NULL; elem = elem->next) {
if (elem->prot && !strcmp(param, (char*)(elem->param))) {
return (char*)(elem->param);
smp_param_t *param = elem->param;
if (param->prot && !strcmp(str, (char*)(param->value))) {
return (char*)(param->value);
}
}
log_info(LD_GENERAL, "(Sandbox) Parameter %s not found", param);
return param;
log_info(LD_GENERAL, "(Sandbox) Parameter %s not found", str);
return str;
}
static int
@ -687,7 +701,7 @@ prot_strings(sandbox_cfg_t* cfg)
// get total number of bytes required to mmap
for (el = cfg; el != NULL; el = el->next) {
pr_mem_size += strlen((char*) el->param) + 1;
pr_mem_size += strlen((char*) ((smp_param_t*)el->param)->value) + 1;
}
// allocate protected memory
@ -705,7 +719,7 @@ prot_strings(sandbox_cfg_t* cfg)
// change el value pointer to protected
for (el = cfg; el != NULL; el = el->next) {
char *param_val = (char*) el->param;
char *param_val = (char*)((smp_param_t *)el->param)->value;
int param_size = strlen(param_val) + 1;
if (pr_mem_left - param_size >= 0) {
@ -713,9 +727,9 @@ prot_strings(sandbox_cfg_t* cfg)
memcpy(pr_mem_next, param_val, param_size);
// re-point el parameter to protected
free((char*) el->param);
el->param = (intptr_t) pr_mem_next;
el->prot = 1;
free((char*) ((smp_param_t*)el->param)->value);
((smp_param_t*)el->param)->value = (intptr_t) pr_mem_next;
((smp_param_t*)el->param)->prot = 1;
// move next available protected memory
pr_mem_next += param_size;
@ -739,23 +753,46 @@ prot_strings(sandbox_cfg_t* cfg)
return ret;
}
static sandbox_cfg_t*
new_element(int syscall, int index, intptr_t value)
{
smp_param_t *param = NULL;
sandbox_cfg_t *elem = (sandbox_cfg_t*) malloc(sizeof(sandbox_cfg_t));
if (!elem)
return NULL;
elem->param = (smp_param_t*) malloc(sizeof(smp_param_t));
if (!elem->param) {
free(elem);
return NULL;
}
param = elem->param;
param->syscall = syscall;
param->pindex = index;
param->value = value;
param->prot = 0;
return elem;
}
#ifdef __NR_stat64
int
sandbox_cfg_allow_stat64_filename(sandbox_cfg_t **cfg, char *file, int fr)
{
sandbox_cfg_t *elem = NULL;
elem = (sandbox_cfg_t*) malloc(sizeof(sandbox_cfg_t));
elem->syscall = SCMP_SYS(stat64);
elem->pindex = 0;
elem->param = (intptr_t) strdup(file);
elem->prot = 0;
elem = new_element(SCMP_SYS(stat64), 0, (intptr_t) strdup(file));
if (!elem) {
log_err(LD_BUG,"(Sandbox) failed to register parameter!");
return -1;
}
elem->next = *cfg;
*cfg = elem;
if (fr) tor_free_(file);
return 0;
}
@ -789,11 +826,11 @@ sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file, int fr)
{
sandbox_cfg_t *elem = NULL;
elem = (sandbox_cfg_t*) malloc(sizeof(sandbox_cfg_t));
elem->syscall = SCMP_SYS(open);
elem->pindex = 0;
elem->param = (intptr_t) strdup(file);
elem->prot = 0;
elem = new_element(SCMP_SYS(open), 0, (intptr_t) strdup(file));
if (!elem) {
log_err(LD_BUG,"(Sandbox) failed to register parameter!");
return -1;
}
elem->next = *cfg;
*cfg = elem;
@ -832,11 +869,11 @@ sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file, int fr)
{
sandbox_cfg_t *elem = NULL;
elem = (sandbox_cfg_t*) malloc(sizeof(sandbox_cfg_t));
elem->syscall = SCMP_SYS(openat);
elem->pindex = 1;
elem->param = (intptr_t) strdup(file);
elem->prot = 0;
elem = new_element(SCMP_SYS(openat), 1, (intptr_t) strdup(file));
if (!elem) {
log_err(LD_BUG,"(Sandbox) failed to register parameter!");
return -1;
}
elem->next = *cfg;
*cfg = elem;
@ -875,11 +912,11 @@ sandbox_cfg_allow_execve(sandbox_cfg_t **cfg, char *com)
{
sandbox_cfg_t *elem = NULL;
elem = (sandbox_cfg_t*) malloc(sizeof(sandbox_cfg_t));
elem->syscall = SCMP_SYS(openat);
elem->pindex = 1;
elem->param = (intptr_t) strdup(com);
elem->prot = 0;
elem = new_element(SCMP_SYS(execve), 1, (intptr_t) strdup(com));
if (!elem) {
log_err(LD_BUG,"(Sandbox) failed to register parameter!");
return -1;
}
elem->next = *cfg;
*cfg = elem;

View File

@ -40,27 +40,48 @@
#define PARAM_NUM 1
/**
* Structure used to manage a sandbox configuration.
*
* It is implemented as a linked list of parameters. Currently only controls
* parameters for open, openat, execve, stat64.
* Enum used to manage the type of the implementation for general purpose.
*/
struct pfd_elem {
typedef enum {
/** Libseccomp implementation based on seccomp2*/
LIBSECCOMP2 = 0
} SB_IMPL;
/**
* Configuration parameter structure associated with the LIBSECCOMP2
* implementation.
*/
typedef struct smp_param {
/** syscall associated with parameter. */
int syscall;
/** parameter index. */
int pindex;
/** parameter value. */
intptr_t param;
intptr_t value;
/** parameter flag (0 = not protected, 1 = protected). */
int prot;
} smp_param_t;
struct pfd_elem *next;
/**
* Structure used to manage a sandbox configuration.
*
* It is implemented as a linked list of parameters. Currently only controls
* parameters for open, openat, execve, stat64.
*/
struct sandbox_cfg_elem {
/** Sandbox implementation which dictates the parameter type. */
SB_IMPL implem;
/** Configuration parameter. */
void *param;
/** Next element of the configuration*/
struct sandbox_cfg_elem *next;
};
/** Typedef to structure used to manage a sandbox configuration. */
typedef struct pfd_elem sandbox_cfg_t;
typedef struct sandbox_cfg_elem sandbox_cfg_t;
/**
* Structure used for keeping a linked list of getaddrinfo pre-recorded