attempt to add stat64 filename filters; failed due to getaddrinfo..

This commit is contained in:
Cristian Toader 2013-08-12 21:14:43 +03:00
parent 44a4464cf6
commit 8a85a48b9d
6 changed files with 100 additions and 9 deletions

View File

@ -97,16 +97,14 @@ static int filter_nopar_gen[] = {
SCMP_SYS(sigreturn), SCMP_SYS(sigreturn),
#endif #endif
SCMP_SYS(stat), SCMP_SYS(stat),
#ifdef __NR_stat64
SCMP_SYS(stat64), // TODO
#endif
SCMP_SYS(uname), SCMP_SYS(uname),
SCMP_SYS(write), SCMP_SYS(write),
SCMP_SYS(exit_group), SCMP_SYS(exit_group),
SCMP_SYS(exit), SCMP_SYS(exit),
SCMP_SYS(madvise), SCMP_SYS(madvise),
// getaddrinfo uses this..
SCMP_SYS(stat64),
// Not needed.. // Not needed..
// SCMP_SYS(set_thread_area), // SCMP_SYS(set_thread_area),
// SCMP_SYS(set_tid_address), // SCMP_SYS(set_tid_address),
@ -542,6 +540,31 @@ sb_poll(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
return 0; return 0;
} }
#ifdef __NR_stat64
static int
sb_stat64(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
{
int rc = 0;
sandbox_cfg_t *elem = NULL;
// 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))) {
rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(stat64), 1,
SCMP_CMP(0, SCMP_CMP_EQ, elem->param));
if (rc != 0) {
log_err(LD_BUG,"(Sandbox) failed to add open syscall, received libseccomp "
"error %d", rc);
return rc;
}
}
}
return 0;
}
#endif
static sandbox_filter_func_t filter_func[] = { static sandbox_filter_func_t filter_func[] = {
sb_rt_sigaction, sb_rt_sigaction,
sb_rt_sigprocmask, sb_rt_sigprocmask,
@ -559,7 +582,8 @@ static sandbox_filter_func_t filter_func[] = {
sb_flock, sb_flock,
sb_futex, sb_futex,
sb_mremap, sb_mremap,
sb_poll sb_poll,
sb_stat64
}; };
const char* const char*
@ -616,6 +640,52 @@ prot_strdup(char* str)
return res; return res;
} }
#ifdef __NR_stat64
int
sandbox_cfg_allow_stat64_filename(sandbox_cfg_t **cfg, char *file, char fr)
{
sandbox_cfg_t *elem = NULL;
elem = (sandbox_cfg_t*) malloc(sizeof(sandbox_cfg_t));
elem->syscall = SCMP_SYS(stat64);
elem->pindex = 0;
elem->ptype = PARAM_PTR;
elem->param = (intptr_t) prot_strdup((char*) file);
elem->prot = 1;
elem->next = *cfg;
*cfg = elem;
if (fr) tor_free_(file);
return 0;
}
int
sandbox_cfg_allow_stat64_filename_array(sandbox_cfg_t **cfg, int num, ...)
{
int rc = 0, i;
va_list ap;
va_start(ap, num);
for (i = 0; i < num; i++) {
char *fn = va_arg(ap, char*);
char fr = (char) va_arg(ap, int);
rc = sandbox_cfg_allow_stat64_filename(cfg, fn, fr);
if(rc) {
log_err(LD_BUG,"(Sandbox) failed on par %d", i);
goto end;
}
}
end:
va_end(ap);
return 0;
}
#endif
int int
sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file, char fr) sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file, char fr)
{ {

View File

@ -9,6 +9,8 @@
* \brief Header file for sandbox.c. * \brief Header file for sandbox.c.
**/ **/
// TODO: thinking of only having allow_file for multiple syscalls
#ifndef SANDBOX_H_ #ifndef SANDBOX_H_
#define SANDBOX_H_ #define SANDBOX_H_
@ -110,6 +112,11 @@ int sandbox_cfg_allow_openat_filename_array(sandbox_cfg_t **cfg, int num, ...);
int sandbox_cfg_allow_execve(sandbox_cfg_t **cfg, char *com); int sandbox_cfg_allow_execve(sandbox_cfg_t **cfg, char *com);
int sandbox_cfg_allow_execve_array(sandbox_cfg_t **cfg, int num, ...); int sandbox_cfg_allow_execve_array(sandbox_cfg_t **cfg, int num, ...);
int sandbox_cfg_allow_stat64_filename(sandbox_cfg_t **cfg, char *file,
char fr);
int sandbox_cfg_allow_stat64_filename_array(sandbox_cfg_t **cfg,
int num, ...);
int sandbox_init(sandbox_cfg_t* cfg); int sandbox_init(sandbox_cfg_t* cfg);
#endif /* SANDBOX_H_ */ #endif /* SANDBOX_H_ */

View File

@ -1803,7 +1803,7 @@ file_status(const char *fname)
int r; int r;
f = tor_strdup(fname); f = tor_strdup(fname);
clean_name_for_stat(f); clean_name_for_stat(f);
r = stat(f, &st); r = stat(sandbox_intern_string(f), &st);
tor_free(f); tor_free(f);
if (r) { if (r) {
if (errno == ENOENT) { if (errno == ENOENT) {
@ -1853,7 +1853,7 @@ check_private_dir(const char *dirname, cpd_check_t check,
tor_assert(dirname); tor_assert(dirname);
f = tor_strdup(dirname); f = tor_strdup(dirname);
clean_name_for_stat(f); clean_name_for_stat(f);
r = stat(f, &st); r = stat(sandbox_intern_string(f), &st);
tor_free(f); tor_free(f);
if (r) { if (r) {
if (errno != ENOENT) { if (errno != ENOENT) {

View File

@ -6121,7 +6121,7 @@ remove_file_if_very_old(const char *fname, time_t now)
#define VERY_OLD_FILE_AGE (28*24*60*60) #define VERY_OLD_FILE_AGE (28*24*60*60)
struct stat st; struct stat st;
if (stat(fname, &st)==0 && st.st_mtime < now-VERY_OLD_FILE_AGE) { if (stat(sandbox_intern_string(fname), &st)==0 && st.st_mtime < now-VERY_OLD_FILE_AGE) {
char buf[ISO_TIME_LEN+1]; char buf[ISO_TIME_LEN+1];
format_local_iso_time(buf, st.st_mtime); format_local_iso_time(buf, st.st_mtime);
log_notice(LD_GENERAL, "Obsolete file %s hasn't been modified since %s. " log_notice(LD_GENERAL, "Obsolete file %s hasn't been modified since %s. "

View File

@ -24,6 +24,7 @@
#include "relay.h" #include "relay.h"
#include "router.h" #include "router.h"
#include "ht.h" #include "ht.h"
#include "../common/sandbox.h"
#ifdef HAVE_EVENT2_DNS_H #ifdef HAVE_EVENT2_DNS_H
#include <event2/event.h> #include <event2/event.h>
#include <event2/dns.h> #include <event2/dns.h>
@ -1477,7 +1478,7 @@ configure_nameservers(int force)
evdns_set_log_fn(evdns_log_cb); evdns_set_log_fn(evdns_log_cb);
if (conf_fname) { if (conf_fname) {
if (stat(conf_fname, &st)) { if (stat(sandbox_intern_string(conf_fname), &st)) {
log_warn(LD_EXIT, "Unable to stat resolver configuration in '%s': %s", log_warn(LD_EXIT, "Unable to stat resolver configuration in '%s': %s",
conf_fname, strerror(errno)); conf_fname, strerror(errno));
goto err; goto err;

View File

@ -2672,6 +2672,14 @@ sandbox_init_filter()
"/dev/urandom", 0 "/dev/urandom", 0
); );
sandbox_cfg_allow_stat64_filename_array(&cfg, 5,
get_datadir_fname(NULL), 1,
get_datadir_fname("lock"), 1,
get_datadir_fname("state"), 1,
get_datadir_fname("router-stability"), 1,
get_datadir_fname("cached-extrainfo.new"), 1
);
// orport // orport
if (server_mode(get_options())) { if (server_mode(get_options())) {
sandbox_cfg_allow_open_filename_array(&cfg, 13, sandbox_cfg_allow_open_filename_array(&cfg, 13,
@ -2689,6 +2697,11 @@ sandbox_init_filter()
"/etc/resolv.conf", 0, "/etc/resolv.conf", 0,
"/dev/random", 0 "/dev/random", 0
); );
sandbox_cfg_allow_stat64_filename_array(&cfg, 2,
get_datadir_fname("keys"), 1,
get_datadir_fname("stats/dirreq-stats"), 1
);
} }
sandbox_cfg_allow_execve(&cfg, "/usr/local/bin/tor"); sandbox_cfg_allow_execve(&cfg, "/usr/local/bin/tor");