Fix Coverity CID 204355, resource leak on error path.

This commit is contained in:
Todd C. Miller
2019-10-24 20:04:32 -06:00
parent 822fd99b60
commit 16b3513a95

View File

@@ -562,49 +562,15 @@ static struct logsrvd_config_section logsrvd_config_sections[] = {
{ NULL } { NULL }
}; };
/* static bool
* Read .ini style logsrvd.conf file. logsrvd_conf_parse(FILE *fp, const char *path)
* Note that we use '#' not ';' for the comment character.
*/
/* XXX - split into read and apply so we don't overwrite good config with bad */
bool
logsrvd_conf_read(const char *path)
{ {
struct logsrvd_config_section *conf_section = NULL; struct logsrvd_config_section *conf_section = NULL;
unsigned int lineno = 0; unsigned int lineno = 0;
size_t linesize = 0; size_t linesize = 0;
char *line = NULL; char *line = NULL;
FILE *fp; bool ret = false;
debug_decl(read_config, SUDO_DEBUG_UTIL) debug_decl(logsrvd_conf_parse, SUDO_DEBUG_UTIL)
if ((fp = fopen(path, "r")) == NULL) {
if (errno == ENOENT)
debug_return_bool(true);
sudo_warn("%s", path);
debug_return_bool(false);
}
/* Initialize default values for settings that take int values. */
logsrvd_conf_reset();
logsrvd_config.eventlog.log_type = EVLOG_SYSLOG;
logsrvd_config.eventlog.log_format = EVLOG_SUDO;
logsrvd_config.syslog.maxlen = 960;
if (!cb_syslog_facility(LOGFAC)) {
sudo_warnx(U_("unknown syslog facility %s"), LOGFAC);
debug_return_bool(false);
}
if (!cb_syslog_acceptpri(PRI_SUCCESS)) {
sudo_warnx(U_("unknown syslog priority %s"), PRI_SUCCESS);
debug_return_bool(false);
}
if (!cb_syslog_rejectpri(PRI_FAILURE)) {
sudo_warnx(U_("unknown syslog priority %s"), PRI_FAILURE);
debug_return_bool(false);
}
if (!cb_syslog_alertpri(PRI_FAILURE)) {
sudo_warnx(U_("unknown syslog priority %s"), PRI_FAILURE);
debug_return_bool(false);
}
while (sudo_parseln(&line, &linesize, &lineno, fp, 0) != -1) { while (sudo_parseln(&line, &linesize, &lineno, fp, 0) != -1) {
struct logsrvd_config_entry *entry; struct logsrvd_config_entry *entry;
@@ -621,7 +587,7 @@ logsrvd_conf_read(const char *path)
if (cp == NULL) { if (cp == NULL) {
sudo_warnx(U_("%s:%d unmatched '[': %s"), sudo_warnx(U_("%s:%d unmatched '[': %s"),
path, lineno, line); path, lineno, line);
debug_return_bool(false); goto done;
} }
*cp = '\0'; *cp = '\0';
for (conf_section = logsrvd_config_sections; conf_section->name != NULL; for (conf_section = logsrvd_config_sections; conf_section->name != NULL;
@@ -632,7 +598,7 @@ logsrvd_conf_read(const char *path)
if (conf_section->name == NULL) { if (conf_section->name == NULL) {
sudo_warnx(U_("%s:%d invalid config section: %s"), sudo_warnx(U_("%s:%d invalid config section: %s"),
path, lineno, section_name); path, lineno, section_name);
debug_return_bool(false); goto done;
} }
continue; continue;
} }
@@ -640,13 +606,13 @@ logsrvd_conf_read(const char *path)
if ((ep = strchr(line, '=')) == NULL) { if ((ep = strchr(line, '=')) == NULL) {
sudo_warnx(U_("%s:%d invalid configuration line: %s"), sudo_warnx(U_("%s:%d invalid configuration line: %s"),
path, lineno, line); path, lineno, line);
debug_return_bool(false); goto done;
} }
if (conf_section == NULL) { if (conf_section == NULL) {
sudo_warnx(U_("%s:%d expected section name: %s"), sudo_warnx(U_("%s:%d expected section name: %s"),
path, lineno, line); path, lineno, line);
debug_return_bool(false); goto done;
} }
val = ep + 1; val = ep + 1;
@@ -660,39 +626,92 @@ logsrvd_conf_read(const char *path)
if (!entry->setter(val)) { if (!entry->setter(val)) {
sudo_warnx(U_("invalid value for %s: %s"), sudo_warnx(U_("invalid value for %s: %s"),
entry->conf_str, val); entry->conf_str, val);
debug_return_bool(false); goto done;
} }
break; break;
} }
} }
if (entry->conf_str == NULL) { if (entry->conf_str == NULL) {
sudo_warnx(U_("%s:%d unknown key: %s"), sudo_warnx(U_("%s:%d unknown key: %s"), path, lineno, line);
path, lineno, line); goto done;
debug_return_bool(false);
} }
} }
ret = true;
done:
free(line);
debug_return_bool(ret);
}
/*
* Read .ini style logsrvd.conf file.
* Note that we use '#' not ';' for the comment character.
*/
/* XXX - split into read and apply so we don't overwrite good config with bad */
bool
logsrvd_conf_read(const char *path)
{
bool ret = false;
FILE *fp = NULL;
debug_decl(logsrvd_conf_read, SUDO_DEBUG_UTIL)
/* Initialize default values for settings that take int values. */
logsrvd_conf_reset();
logsrvd_config.eventlog.log_type = EVLOG_SYSLOG;
logsrvd_config.eventlog.log_format = EVLOG_SUDO;
logsrvd_config.syslog.maxlen = 960;
if (!cb_syslog_facility(LOGFAC)) {
sudo_warnx(U_("unknown syslog facility %s"), LOGFAC);
goto done;
}
if (!cb_syslog_acceptpri(PRI_SUCCESS)) {
sudo_warnx(U_("unknown syslog priority %s"), PRI_SUCCESS);
goto done;
}
if (!cb_syslog_rejectpri(PRI_FAILURE)) {
sudo_warnx(U_("unknown syslog priority %s"), PRI_FAILURE);
goto done;
}
if (!cb_syslog_alertpri(PRI_FAILURE)) {
sudo_warnx(U_("unknown syslog priority %s"), PRI_FAILURE);
goto done;
}
if ((fp = fopen(path, "r")) == NULL) {
if (errno != ENOENT) {
sudo_warn("%s", path);
goto done;
}
} else {
if (!logsrvd_conf_parse(fp, path))
goto done;
}
/* For settings with pointer values we can tell what is unset. */ /* For settings with pointer values we can tell what is unset. */
if (logsrvd_config.iolog.iolog_dir == NULL) { if (logsrvd_config.iolog.iolog_dir == NULL) {
if (!cb_iolog_dir(_PATH_SUDO_IO_LOGDIR)) if (!cb_iolog_dir(_PATH_SUDO_IO_LOGDIR))
debug_return_bool(false); goto done;
} }
if (logsrvd_config.iolog.iolog_file == NULL) { if (logsrvd_config.iolog.iolog_file == NULL) {
if (!cb_iolog_file("%{seq}")) if (!cb_iolog_file("%{seq}"))
debug_return_bool(false); goto done;
} }
if (TAILQ_EMPTY(&logsrvd_config.server.addresses)) { if (TAILQ_EMPTY(&logsrvd_config.server.addresses)) {
if (!cb_listen_address("*:30344")) if (!cb_listen_address("*:30344"))
debug_return_bool(false); goto done;
} }
if (logsrvd_config.logfile.time_format == NULL) { if (logsrvd_config.logfile.time_format == NULL) {
if (!cb_logfile_time_format("%h %e %T")) if (!cb_logfile_time_format("%h %e %T"))
debug_return_bool(false); goto done;
} }
if (logsrvd_config.logfile.path == NULL) { if (logsrvd_config.logfile.path == NULL) {
if (!cb_logfile_path(_PATH_SUDO_LOGFILE)) if (!cb_logfile_path(_PATH_SUDO_LOGFILE))
debug_return_bool(false); goto done;
} }
ret = true;
debug_return_bool(true); done:
if (fp != NULL)
fclose(fp);
debug_return_bool(ret);
} }