commit b76a161e019dd808119f9e6d3bfa54990e7dcb2c Merge: 1f9764f90 ade9baaf9 Author: Nick Mathewson nickm@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 };