evdns: Add additional validation for values of dns options

This commit is contained in:
ayuseleznev 2020-05-18 14:10:28 +03:00
parent 83ef3216e4
commit 8fe35c7614
2 changed files with 70 additions and 0 deletions

View File

@ -3531,6 +3531,7 @@ evdns_base_set_option_impl(struct evdns_base *base,
base->global_max_retransmits = retries; base->global_max_retransmits = retries;
} else if (str_matches_option(option, "randomize-case:")) { } else if (str_matches_option(option, "randomize-case:")) {
int randcase = strtoint(val); int randcase = strtoint(val);
if (randcase == -1) return -1;
if (!(flags & DNS_OPTION_MISC)) return 0; if (!(flags & DNS_OPTION_MISC)) return 0;
base->global_randomize_case = randcase; base->global_randomize_case = randcase;
} else if (str_matches_option(option, "bind-to:")) { } else if (str_matches_option(option, "bind-to:")) {
@ -3554,11 +3555,13 @@ evdns_base_set_option_impl(struct evdns_base *base,
sizeof(tv)); sizeof(tv));
} else if (str_matches_option(option, "so-rcvbuf:")) { } else if (str_matches_option(option, "so-rcvbuf:")) {
int buf = strtoint(val); int buf = strtoint(val);
if (buf == -1) return -1;
if (!(flags & DNS_OPTION_MISC)) return 0; if (!(flags & DNS_OPTION_MISC)) return 0;
log(EVDNS_LOG_DEBUG, "Setting SO_RCVBUF to %s", val); log(EVDNS_LOG_DEBUG, "Setting SO_RCVBUF to %s", val);
base->so_rcvbuf = buf; base->so_rcvbuf = buf;
} else if (str_matches_option(option, "so-sndbuf:")) { } else if (str_matches_option(option, "so-sndbuf:")) {
int buf = strtoint(val); int buf = strtoint(val);
if (buf == -1) return -1;
if (!(flags & DNS_OPTION_MISC)) return 0; if (!(flags & DNS_OPTION_MISC)) return 0;
log(EVDNS_LOG_DEBUG, "Setting SO_SNDBUF to %s", val); log(EVDNS_LOG_DEBUG, "Setting SO_SNDBUF to %s", val);
base->so_sndbuf = buf; base->so_sndbuf = buf;

View File

@ -2379,6 +2379,71 @@ end:
evdns_base_free(dns_base, 0); evdns_base_free(dns_base, 0);
} }
static void
test_set_option(void *arg)
{
#define SUCCESS 0
#define FAIL -1
struct basic_test_data *data = arg;
struct evdns_base *dns_base;
size_t i;
/* Option names are allowed to have ':' at the end.
* So all test option names come in pairs.
*/
const char *int_options[] = {
"ndots", "ndots:",
"max-timeouts", "max-timeouts:",
"max-inflight", "max-inflight:",
"attempts", "attempts:",
"randomize-case", "randomize-case:",
"so-rcvbuf", "so-rcvbuf:",
"so-sndbuf", "so-sndbuf:",
};
const char *timeval_options[] = {
"timeout", "timeout:",
"getaddrinfo-allow-skew", "getaddrinfo-allow-skew:",
"initial-probe-timeout", "initial-probe-timeout:",
};
const char *addr_port_options[] = {
"bind-to", "bind-to:",
};
dns_base = evdns_base_new(data->base, 0);
tt_assert(dns_base);
for (i = 0; i < ARRAY_SIZE(int_options); ++i) {
tt_assert(SUCCESS == evdns_base_set_option(dns_base, int_options[i], "0"));
tt_assert(SUCCESS == evdns_base_set_option(dns_base, int_options[i], "1"));
tt_assert(SUCCESS == evdns_base_set_option(dns_base, int_options[i], "10000"));
tt_assert(FAIL == evdns_base_set_option(dns_base, int_options[i], "foo"));
tt_assert(FAIL == evdns_base_set_option(dns_base, int_options[i], "3.14"));
}
for (i = 0; i < ARRAY_SIZE(timeval_options); ++i) {
tt_assert(SUCCESS == evdns_base_set_option(dns_base, timeval_options[i], "1"));
tt_assert(SUCCESS == evdns_base_set_option(dns_base, timeval_options[i], "0.001"));
tt_assert(SUCCESS == evdns_base_set_option(dns_base, timeval_options[i], "3.14"));
tt_assert(SUCCESS == evdns_base_set_option(dns_base, timeval_options[i], "10000"));
tt_assert(FAIL == evdns_base_set_option(dns_base, timeval_options[i], "0"));
tt_assert(FAIL == evdns_base_set_option(dns_base, timeval_options[i], "foo"));
}
for (i = 0; i < ARRAY_SIZE(addr_port_options); ++i) {
tt_assert(SUCCESS == evdns_base_set_option(dns_base, addr_port_options[i], "8.8.8.8:80"));
tt_assert(SUCCESS == evdns_base_set_option(dns_base, addr_port_options[i], "1.2.3.4"));
tt_assert(SUCCESS == evdns_base_set_option(dns_base, addr_port_options[i], "::1:82"));
tt_assert(SUCCESS == evdns_base_set_option(dns_base, addr_port_options[i], "3::4"));
tt_assert(FAIL == evdns_base_set_option(dns_base, addr_port_options[i], "3.14"));
tt_assert(FAIL == evdns_base_set_option(dns_base, addr_port_options[i], "foo"));
}
#undef SUCCESS
#undef FAIL
end:
if (dns_base)
evdns_base_free(dns_base, 0);
}
#define DNS_LEGACY(name, flags) \ #define DNS_LEGACY(name, flags) \
{ #name, run_legacy_test_fn, flags|TT_LEGACY, &legacy_setup, \ { #name, run_legacy_test_fn, flags|TT_LEGACY, &legacy_setup, \
dns_##name } dns_##name }
@ -2454,6 +2519,8 @@ struct testcase_t dns_testcases[] = {
{ "set_SO_RCVBUF_SO_SNDBUF", test_set_so_rcvbuf_so_sndbuf, { "set_SO_RCVBUF_SO_SNDBUF", test_set_so_rcvbuf_so_sndbuf,
TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
{ "set_options", test_set_option,
TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
END_OF_TESTCASES END_OF_TESTCASES
}; };