[tor-commits] [tor/master] Merge branch 'fix-torrcd-sandbox-22605v2'

nickm at torproject.org nickm at torproject.org
Tue Oct 31 18:00:11 UTC 2017


commit b76a161e019dd808119f9e6d3bfa54990e7dcb2c
Merge: 1f9764f90 ade9baaf9
Author: Nick Mathewson <nickm at torproject.org>
Date:   Tue Oct 31 13:58:33 2017 -0400

    Merge branch 'fix-torrcd-sandbox-22605v2'

 src/common/confline.c  |  94 +++++++++++++++++++++------------------
 src/common/confline.h  |   5 ++-
 src/common/sandbox.c   |   1 +
 src/or/config.c        |  22 +++++++++-
 src/or/main.c          |   4 ++
 src/or/or.h            |   3 ++
 src/test/test_config.c | 117 +++++++++++++++++++++++++++++++++++++++++--------
 7 files changed, 183 insertions(+), 63 deletions(-)

diff --cc src/or/config.c
index 9013fb6d2,753547767..e913e5459
--- a/src/or/config.c
+++ b/src/or/config.c
@@@ -935,10 -895,10 +935,14 @@@ or_options_free(or_options_t *options
                        rs, routerset_free(rs));
      smartlist_free(options->NodeFamilySets);
    }
 +  if (options->SchedulerTypes_) {
 +    SMARTLIST_FOREACH(options->SchedulerTypes_, int *, i, tor_free(i));
 +    smartlist_free(options->SchedulerTypes_);
 +  }
+   if (options->FilesOpenedByIncludes) {
+     SMARTLIST_FOREACH(options->FilesOpenedByIncludes, char *, f, tor_free(f));
+     smartlist_free(options->FilesOpenedByIncludes);
+   }
    tor_free(options->BridgePassword_AuthDigest_);
    tor_free(options->command_arg);
    tor_free(options->master_key_fname);
@@@ -5377,7 -5186,7 +5388,8 @@@ options_init_from_string(const char *cf
    }
  
    newoptions->IncludeUsed = cf_has_include;
 +  in_option_validation = 1;
+   newoptions->FilesOpenedByIncludes = opened_files;
  
    /* Validate newoptions */
    if (options_validate(oldoptions, newoptions, newdefaultoptions,
@@@ -5403,7 -5210,12 +5415,13 @@@
    return SETOPT_OK;
  
   err:
 +  in_option_validation = 0;
+   if (opened_files) {
+     SMARTLIST_FOREACH(opened_files, char *, f, tor_free(f));
+     smartlist_free(opened_files);
+   }
+   // may have been set to opened_files, avoid double free
+   newoptions->FilesOpenedByIncludes = NULL;
    or_options_free(newoptions);
    or_options_free(newdefaultoptions);
    if (*msg) {
diff --cc src/or/or.h
index c318c4754,5f62e8dcc..4572a4645
--- a/src/or/or.h
+++ b/src/or/or.h
@@@ -4610,28 -4564,10 +4610,31 @@@ typedef struct 
     * use the default. */
    int MaxConsensusAgeForDiffs;
  
 +  /** Bool (default: 0). Tells Tor to never try to exec another program.
 +   */
 +  int NoExec;
 +
 +  /** Have the KIST scheduler run every X milliseconds. If less than zero, do
 +   * not use the KIST scheduler but use the old vanilla scheduler instead. If
 +   * zero, do what the consensus says and fall back to using KIST as if this is
 +   * set to "10 msec" if the consensus doesn't say anything. */
 +  int KISTSchedRunInterval;
 +
 +  /** A multiplier for the KIST per-socket limit calculation. */
 +  double KISTSockBufSizeFactor;
 +
 +  /** The list of scheduler type string ordered by priority that is first one
 +   * has to be tried first. Default: KIST,KISTLite,Vanilla */
 +  smartlist_t *Schedulers;
 +  /* An ordered list of scheduler_types mapped from Schedulers. */
 +  smartlist_t *SchedulerTypes_;
++
+   /** List of files that were opened by %include in torrc and torrc-defaults */
+    smartlist_t *FilesOpenedByIncludes;
  } or_options_t;
  
 +#define LOG_PROTOCOL_WARN (get_protocol_warning_severity_level())
 +
  /** Persistent state for an onion router, as saved to disk. */
  typedef struct {
    uint32_t magic_;
diff --cc src/test/test_config.c
index 456d8bcc3,ca852c943..79f72fca1
--- a/src/test/test_config.c
+++ b/src/test/test_config.c
@@@ -4944,49 -4944,8 +4944,50 @@@ test_config_include_empty_file_folder(v
  
   done:
    config_free_lines(result);
 +  tor_free(folder_path);
 +  tor_free(file_path);
 +  tor_free(dir);
 +}
 +
 +#ifndef _WIN32
 +static void
 +test_config_include_no_permission(void *data)
 +{
 +  (void)data;
 +  config_line_t *result = NULL;
 +
 +  char *folder_path = NULL;
 +  char *dir = NULL;
 +  if (geteuid() == 0)
 +    tt_skip();
 +
 +  dir = tor_strdup(get_fname("test_include_forbidden_folder"));
 +  tt_ptr_op(dir, OP_NE, NULL);
 +
 +  tt_int_op(mkdir(dir, 0700), OP_EQ, 0);
 +
 +  tor_asprintf(&folder_path, "%s"PATH_SEPARATOR"forbidden_dir", dir);
 +  tt_int_op(mkdir(folder_path, 0100), OP_EQ, 0);
 +
 +  char torrc_contents[1000];
 +  tor_snprintf(torrc_contents, sizeof(torrc_contents),
 +               "%%include %s\n",
 +               folder_path);
 +
 +  int include_used;
-   tt_int_op(config_get_lines_include(torrc_contents, &result, 0,&include_used),
++  tt_int_op(config_get_lines_include(torrc_contents, &result, 0,
++                                     &include_used, NULL),
 +            OP_EQ, -1);
 +  tt_ptr_op(result, OP_EQ, NULL);
 +
 + done:
 +  config_free_lines(result);
 +  tor_free(folder_path);
 +  if (dir)
 +    chmod(dir, 0700);
    tor_free(dir);
  }
 +#endif
  
  static void
  test_config_include_recursion_before_after(void *data)
@@@ -5412,107 -5358,84 +5413,186 @@@ test_config_include_flag_defaults_only(
  }
  
  static void
 +test_config_dup_and_filter(void *arg)
 +{
 +  (void)arg;
 +  /* Test normal input. */
 +  config_line_t *line = NULL;
 +  config_line_append(&line, "abc", "def");
 +  config_line_append(&line, "ghi", "jkl");
 +  config_line_append(&line, "ABCD", "mno");
 +
 +  config_line_t *line_dup = config_lines_dup_and_filter(line, "aBc");
 +  tt_ptr_op(line_dup, OP_NE, NULL);
 +  tt_ptr_op(line_dup->next, OP_NE, NULL);
 +  tt_ptr_op(line_dup->next->next, OP_EQ, NULL);
 +
 +  tt_str_op(line_dup->key, OP_EQ, "abc");
 +  tt_str_op(line_dup->value, OP_EQ, "def");
 +  tt_str_op(line_dup->next->key, OP_EQ, "ABCD");
 +  tt_str_op(line_dup->next->value, OP_EQ, "mno");
 +
 +  /* empty output */
 +  config_free_lines(line_dup);
 +  line_dup = config_lines_dup_and_filter(line, "skdjfsdkljf");
 +  tt_ptr_op(line_dup, OP_EQ, NULL);
 +
 +  /* empty input */
 +  config_free_lines(line_dup);
 +  line_dup = config_lines_dup_and_filter(NULL, "abc");
 +  tt_ptr_op(line_dup, OP_EQ, NULL);
 +
 + done:
 +  config_free_lines(line);
 +  config_free_lines(line_dup);
 +}
 +
 +/* If we're not configured to be a bridge, but we set
 + * BridgeDistribution, then options_validate () should return -1. */
 +static void
 +test_config_check_bridge_distribution_setting_not_a_bridge(void *arg)
 +{
 +  or_options_t* options = get_options_mutable();
 +  or_options_t* old_options = options;
 +  or_options_t* default_options = options;
 +  char* message = (char*)("");
 +  int ret;
 +
 +  (void)arg;
 +
 +  options->BridgeRelay = 0;
 +  options->BridgeDistribution = (char*)("https");
 +
 +  ret = options_validate(old_options, options, default_options, 0, &message);
 +
 +  tt_int_op(ret, OP_EQ, -1);
 + done:
 +  return;
 +}
 +
 +/* If the BridgeDistribution setting was valid, 0 should be returned. */
 +static void
 +test_config_check_bridge_distribution_setting_valid(void *arg)
 +{
 +  int ret = check_bridge_distribution_setting("https");
 +
 +  (void)arg;
 +
 +  tt_int_op(ret, OP_EQ, 0);
 + done:
 +  return;
 +}
 +
 +/* If the BridgeDistribution setting was invalid, -1 should be returned. */
 +static void
 +test_config_check_bridge_distribution_setting_invalid(void *arg)
 +{
 +  int ret = check_bridge_distribution_setting("hyphens-are-allowed");
 +
 +  (void)arg;
 +
 +  tt_int_op(ret, OP_EQ, 0);
 +
 +  ret = check_bridge_distribution_setting("asterisks*are*forbidden");
 +
 +  tt_int_op(ret, OP_EQ, -1);
 + done:
 +  return;
 +}
 +
 +/* If the BridgeDistribution setting was unrecognised, a warning should be
 + * logged and 0 should be returned. */
 +static void
 +test_config_check_bridge_distribution_setting_unrecognised(void *arg)
 +{
 +  int ret = check_bridge_distribution_setting("unicorn");
 +
 +  (void)arg;
 +
 +  tt_int_op(ret, OP_EQ, 0);
 + done:
 +  return;
 +}
 +
++static void
+ test_config_include_opened_file_list(void *data)
+ {
+   (void)data;
+ 
+   config_line_t *result = NULL;
+   smartlist_t *opened_files = smartlist_new();
+   char *dir = tor_strdup(get_fname("test_include_opened_file_list"));
+   tt_ptr_op(dir, OP_NE, NULL);
+ 
+ #ifdef _WIN32
+   tt_int_op(mkdir(dir), OP_EQ, 0);
+ #else
+   tt_int_op(mkdir(dir, 0700), OP_EQ, 0);
+ #endif
+ 
+   char torrcd[PATH_MAX+1];
+   tor_snprintf(torrcd, sizeof(torrcd), "%s"PATH_SEPARATOR"%s", dir, "torrc.d");
+ 
+ #ifdef _WIN32
+   tt_int_op(mkdir(torrcd), OP_EQ, 0);
+ #else
+   tt_int_op(mkdir(torrcd, 0700), OP_EQ, 0);
+ #endif
+ 
+   char subfolder[PATH_MAX+1];
+   tor_snprintf(subfolder, sizeof(subfolder), "%s"PATH_SEPARATOR"%s", torrcd,
+                "subfolder");
+ 
+ #ifdef _WIN32
+   tt_int_op(mkdir(subfolder), OP_EQ, 0);
+ #else
+   tt_int_op(mkdir(subfolder, 0700), OP_EQ, 0);
+ #endif
+ 
+   char path[PATH_MAX+1];
+   tor_snprintf(path, sizeof(path), "%s"PATH_SEPARATOR"%s", subfolder,
+                "01_file_in_subfolder");
+   tt_int_op(write_str_to_file(path, "Test 1\n", 0), OP_EQ, 0);
+ 
+   char empty[PATH_MAX+1];
+   tor_snprintf(empty, sizeof(empty), "%s"PATH_SEPARATOR"%s", torrcd, "empty");
+   tt_int_op(write_str_to_file(empty, "", 0), OP_EQ, 0);
+ 
+   char file[PATH_MAX+1];
+   tor_snprintf(file, sizeof(file), "%s"PATH_SEPARATOR"%s", torrcd, "file");
+   tt_int_op(write_str_to_file(file, "Test 2\n", 0), OP_EQ, 0);
+ 
+   char dot[PATH_MAX+1];
+   tor_snprintf(dot, sizeof(dot), "%s"PATH_SEPARATOR"%s", torrcd, ".dot");
+   tt_int_op(write_str_to_file(dot, "Test 3\n", 0), OP_EQ, 0);
+ 
+   char torrc_contents[1000];
+   tor_snprintf(torrc_contents, sizeof(torrc_contents),
+                "%%include %s\n",
+                torrcd);
+ 
+   int include_used;
+   tt_int_op(config_get_lines_include(torrc_contents, &result, 0, &include_used,
+             opened_files), OP_EQ, 0);
+   tt_ptr_op(result, OP_NE, NULL);
+   tt_int_op(include_used, OP_EQ, 1);
+ 
+   tt_int_op(smartlist_len(opened_files), OP_EQ, 4);
+   tt_int_op(smartlist_contains_string(opened_files, torrcd), OP_EQ, 1);
+   tt_int_op(smartlist_contains_string(opened_files, subfolder), OP_EQ, 1);
+   // files inside subfolders are not opended, only the subfolder is opened
+   tt_int_op(smartlist_contains_string(opened_files, empty), OP_EQ, 1);
+   tt_int_op(smartlist_contains_string(opened_files, file), OP_EQ, 1);
+   // dot files are not opened as we ignore them when we get their name from
+   // their parent folder
+ 
+  done:
+   SMARTLIST_FOREACH(opened_files, char *, f, tor_free(f));
+   smartlist_free(opened_files);
+   config_free_lines(result);
+   tor_free(dir);
+ }
+ 
  #define CONFIG_TEST(name, flags)                          \
    { #name, test_config_ ## name, flags, NULL, NULL }
  
@@@ -5555,11 -5475,7 +5635,12 @@@ struct testcase_t config_tests[] = 
    CONFIG_TEST(include_flag_both_without, TT_FORK),
    CONFIG_TEST(include_flag_torrc_only, TT_FORK),
    CONFIG_TEST(include_flag_defaults_only, TT_FORK),
 +  CONFIG_TEST(dup_and_filter, 0),
 +  CONFIG_TEST(check_bridge_distribution_setting_not_a_bridge, TT_FORK),
 +  CONFIG_TEST(check_bridge_distribution_setting_valid, 0),
 +  CONFIG_TEST(check_bridge_distribution_setting_invalid, 0),
 +  CONFIG_TEST(check_bridge_distribution_setting_unrecognised, 0),
+   CONFIG_TEST(include_opened_file_list, 0),
    END_OF_TESTCASES
  };
  



More information about the tor-commits mailing list