Refactor duplicate code out of rend_config_services

Put that code in rend_service_check_dir_and_add.

No behaviour change.

This is a defence in depth measure against similar bugs to 20529.
This commit is contained in:
teor 2016-11-04 16:04:05 +11:00
parent 98057d274c
commit 8bdedab8da
No known key found for this signature in database
GPG Key ID: 450CBA7F968F094B

View File

@ -218,6 +218,7 @@ rend_service_free_all(void)
/** Validate <b>service</b> and add it to rend_service_list if possible.
* Return 0 on success. On failure, free <b>service</b> and return -1.
* Takes ownership of <b>service</b>.
*/
static int
rend_add_service(rend_service_t *service)
@ -444,6 +445,34 @@ rend_service_port_config_free(rend_service_port_config_t *p)
tor_free(p);
}
/* Check the directory for <b>service</b>, and add the service to the global
* list if <b>validate_only</b> is false.
* If <b>validate_only</b> is true, free the service.
* If <b>service</b> is NULL, ignore it, and return 0.
* Returns 0 on success, and -1 on failure.
* Takes ownership of <b>service</b>.
*/
static int
rend_service_check_dir_and_add(const or_options_t *options,
rend_service_t *service,
int validate_only)
{
if (service) { /* register the one we just finished parsing */
if (rend_service_check_private_dir(options, service, !validate_only)
< 0) {
rend_service_free(service);
return -1;
}
if (validate_only)
rend_service_free(service);
else
rend_add_service(service);
}
return 0;
}
/** Set up rend_service_list, based on the values of HiddenServiceDir and
* HiddenServicePort in <b>options</b>. Return 0 on success and -1 on
* failure. (If <b>validate_only</b> is set, parse, warn and return as
@ -465,17 +494,12 @@ rend_config_services(const or_options_t *options, int validate_only)
for (line = options->RendConfigLines; line; line = line->next) {
if (!strcasecmp(line->key, "HiddenServiceDir")) {
if (service) { /* register the one we just finished parsing */
if (rend_service_check_private_dir(options, service, !validate_only)
< 0) {
rend_service_free(service);
/* register the service we just finished parsing
* this code registers every service except the last one parsed,
* which is registered below the loop */
if (rend_service_check_dir_and_add(options, service, !validate_only)
< 0) {
return -1;
}
if (validate_only)
rend_service_free(service);
else
rend_add_service(service);
}
service = tor_malloc_zero(sizeof(rend_service_t));
service->directory = tor_strdup(line->value);
@ -681,17 +705,12 @@ rend_config_services(const or_options_t *options, int validate_only)
}
}
}
if (service) {
if (rend_service_check_private_dir(options, service, !validate_only) < 0) {
rend_service_free(service);
return -1;
}
if (validate_only) {
rend_service_free(service);
} else {
rend_add_service(service);
}
/* register the final service after we have finished parsing all services
* this code only registers the last service, other services are registered
* within the loop */
if (rend_service_check_dir_and_add(options, service, !validate_only)
< 0) {
return -1;
}
/* If this is a reload and there were hidden services configured before,