[tor-commits] [tor/master] attempt to add stat64 filename filters; failed due to getaddrinfo..

nickm at torproject.org nickm at torproject.org
Fri Sep 13 16:31:55 UTC 2013


commit 8a85a48b9d0ed2b298bcc26dfeb96fa7e31c05c4
Author: Cristian Toader <cristian.matei.toader at gmail.com>
Date:   Mon Aug 12 21:14:43 2013 +0300

    attempt to add stat64 filename filters; failed due to getaddrinfo..
---
 src/common/sandbox.c |   80 ++++++++++++++++++++++++++++++++++++++++++++++----
 src/common/sandbox.h |    7 +++++
 src/common/util.c    |    4 +--
 src/or/config.c      |    2 +-
 src/or/dns.c         |    3 +-
 src/or/main.c        |   13 ++++++++
 6 files changed, 100 insertions(+), 9 deletions(-)

diff --git a/src/common/sandbox.c b/src/common/sandbox.c
index f2ead21..0be4c52 100644
--- a/src/common/sandbox.c
+++ b/src/common/sandbox.c
@@ -97,16 +97,14 @@ static int filter_nopar_gen[] = {
     SCMP_SYS(sigreturn),
 #endif
     SCMP_SYS(stat),
-#ifdef __NR_stat64
-    SCMP_SYS(stat64), // TODO
-#endif
     SCMP_SYS(uname),
     SCMP_SYS(write),
     SCMP_SYS(exit_group),
     SCMP_SYS(exit),
 
     SCMP_SYS(madvise),
-
+    // getaddrinfo uses this..
+    SCMP_SYS(stat64),
     // Not needed..
 //    SCMP_SYS(set_thread_area),
 //    SCMP_SYS(set_tid_address),
@@ -542,6 +540,31 @@ sb_poll(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
   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[] = {
     sb_rt_sigaction,
     sb_rt_sigprocmask,
@@ -559,7 +582,8 @@ static sandbox_filter_func_t filter_func[] = {
     sb_flock,
     sb_futex,
     sb_mremap,
-    sb_poll
+    sb_poll,
+    sb_stat64
 };
 
 const char*
@@ -616,6 +640,52 @@ prot_strdup(char* str)
    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
 sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file, char fr)
 {
diff --git a/src/common/sandbox.h b/src/common/sandbox.h
index 33668d9..e928591 100644
--- a/src/common/sandbox.h
+++ b/src/common/sandbox.h
@@ -9,6 +9,8 @@
  * \brief Header file for sandbox.c.
  **/
 
+// TODO: thinking of only having allow_file for multiple syscalls
+
 #ifndef 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_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);
 
 #endif /* SANDBOX_H_ */
diff --git a/src/common/util.c b/src/common/util.c
index 75462b6..8408a36 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -1803,7 +1803,7 @@ file_status(const char *fname)
   int r;
   f = tor_strdup(fname);
   clean_name_for_stat(f);
-  r = stat(f, &st);
+  r = stat(sandbox_intern_string(f), &st);
   tor_free(f);
   if (r) {
     if (errno == ENOENT) {
@@ -1853,7 +1853,7 @@ check_private_dir(const char *dirname, cpd_check_t check,
   tor_assert(dirname);
   f = tor_strdup(dirname);
   clean_name_for_stat(f);
-  r = stat(f, &st);
+  r = stat(sandbox_intern_string(f), &st);
   tor_free(f);
   if (r) {
     if (errno != ENOENT) {
diff --git a/src/or/config.c b/src/or/config.c
index e53c288..e1b7b4e 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -6121,7 +6121,7 @@ remove_file_if_very_old(const char *fname, time_t now)
 #define VERY_OLD_FILE_AGE (28*24*60*60)
   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];
     format_local_iso_time(buf, st.st_mtime);
     log_notice(LD_GENERAL, "Obsolete file %s hasn't been modified since %s. "
diff --git a/src/or/dns.c b/src/or/dns.c
index edcf92e..6dc0c05 100644
--- a/src/or/dns.c
+++ b/src/or/dns.c
@@ -24,6 +24,7 @@
 #include "relay.h"
 #include "router.h"
 #include "ht.h"
+#include "../common/sandbox.h"
 #ifdef HAVE_EVENT2_DNS_H
 #include <event2/event.h>
 #include <event2/dns.h>
@@ -1477,7 +1478,7 @@ configure_nameservers(int force)
 
   evdns_set_log_fn(evdns_log_cb);
   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",
                conf_fname, strerror(errno));
       goto err;
diff --git a/src/or/main.c b/src/or/main.c
index c236e83..a2fbe5f 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -2672,6 +2672,14 @@ sandbox_init_filter()
       "/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
   if (server_mode(get_options())) {
     sandbox_cfg_allow_open_filename_array(&cfg, 13,
@@ -2689,6 +2697,11 @@ sandbox_init_filter()
         "/etc/resolv.conf", 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");





More information about the tor-commits mailing list