lib/base: heim_config_parse_file do not leak 'newfname'

Refactor heim_config_parse_file() to use a common exit and
ensure that 'newfname' is freed on all exit paths.

Change-Id: Ie805ce2f9d6cbd26a3b98dc944b40864945b6d80
This commit is contained in:
Jeffrey Altman
2020-05-25 21:17:42 -04:00
committed by Nicolas Williams
parent 58db0edea0
commit 5502fa4eca

View File

@@ -558,7 +558,7 @@ heim_config_parse_file_multi(heim_context context,
const char *str; const char *str;
char *newfname = NULL; char *newfname = NULL;
unsigned lineno = 0; unsigned lineno = 0;
heim_error_code ret; heim_error_code ret = 0;
struct fileptr f; struct fileptr f;
struct stat st; struct stat st;
@@ -580,10 +580,10 @@ heim_config_parse_file_multi(heim_context context,
char homebuf[MAX_PATH]; char homebuf[MAX_PATH];
if (!heim_context_get_homedir_access(context)) { if (!heim_context_get_homedir_access(context)) {
config_include_depth--;
heim_set_error_message(context, EPERM, heim_set_error_message(context, EPERM,
"Access to home directory not allowed"); "Access to home directory not allowed");
return EPERM; ret = EPERM;
goto out;
} }
home = roken_get_appdatadir(homebuf, sizeof(homebuf)); home = roken_get_appdatadir(homebuf, sizeof(homebuf));
@@ -592,8 +592,8 @@ heim_config_parse_file_multi(heim_context context,
aret = asprintf(&newfname, "%s%s", home, &fname[1]); aret = asprintf(&newfname, "%s%s", home, &fname[1]);
if (aret == -1 || newfname == NULL) { if (aret == -1 || newfname == NULL) {
config_include_depth--; ret = heim_enomem(context);
return heim_enomem(context); goto out;
} }
fname = newfname; fname = newfname;
} }
@@ -604,39 +604,34 @@ heim_config_parse_file_multi(heim_context context,
*/ */
if (asprintf(&newfname, "%%{USERCONFIG}%s", &fname[1]) < 0 || if (asprintf(&newfname, "%%{USERCONFIG}%s", &fname[1]) < 0 ||
newfname == NULL) { newfname == NULL) {
config_include_depth--; ret = heim_enomem(context);
return heim_enomem(context); goto out;
} }
fname = newfname; fname = newfname;
#endif /* HEIM_BASE_USE_PATH_TOKENS */ #endif /* HEIM_BASE_USE_PATH_TOKENS */
} }
if (is_plist_file(fname)) { if (is_plist_file(fname)) {
config_include_depth--;
#if defined(HAVE_FRAMEWORK_COREFOUNDATION) #if defined(HAVE_FRAMEWORK_COREFOUNDATION)
ret = parse_plist_config(context, fname, res); ret = parse_plist_config(context, fname, res);
if (ret) { if (ret) {
heim_set_error_message(context, ret, heim_set_error_message(context, ret,
"Failed to parse plist %s", fname); "Failed to parse plist %s", fname);
free(newfname); goto out;
return ret;
} }
#else #else
heim_set_error_message(context, ENOENT, heim_set_error_message(context, ENOENT,
"no support for plist configuration files"); "no support for plist configuration files");
return ENOENT; ret = ENOENT;
goto out;
#endif #endif
} else { } else {
#ifdef HEIM_BASE_USE_PATH_TOKENS #ifdef HEIM_BASE_USE_PATH_TOKENS
char *exp_fname; /* newfname might be non-NULL */ char *exp_fname; /* newfname might be non-NULL */
ret = heim_expand_path_tokens(context, fname, 1, &exp_fname, NULL); ret = heim_expand_path_tokens(context, fname, 1, &exp_fname, NULL);
if (ret) { if (ret)
config_include_depth--; goto out;
free(newfname); free(newfname);
return ret;
}
free(newfname);
fname = newfname = exp_fname; fname = newfname = exp_fname;
#endif /* HEIM_BASE_USE_PATH_TOKENS */ #endif /* HEIM_BASE_USE_PATH_TOKENS */
@@ -646,37 +641,36 @@ heim_config_parse_file_multi(heim_context context,
if (f.f == NULL || fstat(fileno(f.f), &st) == -1) { if (f.f == NULL || fstat(fileno(f.f), &st) == -1) {
if (f.f != NULL) if (f.f != NULL)
(void) fclose(f.f); (void) fclose(f.f);
config_include_depth--;
ret = errno; ret = errno;
heim_set_error_message(context, ret, "open or stat %s: %s", heim_set_error_message(context, ret, "open or stat %s: %s",
fname, strerror(ret)); fname, strerror(ret));
free(newfname); goto out;
return ret;
} }
if (!S_ISREG(st.st_mode)) { if (!S_ISREG(st.st_mode)) {
(void) fclose(f.f); (void) fclose(f.f);
config_include_depth--;
heim_set_error_message(context, EISDIR, "not a regular file %s: %s", heim_set_error_message(context, EISDIR, "not a regular file %s: %s",
fname, strerror(EISDIR)); fname, strerror(EISDIR));
free(newfname); ret = EISDIR;
return EISDIR; goto out;
} }
ret = heim_config_parse_debug(&f, res, &lineno, &str); ret = heim_config_parse_debug(&f, res, &lineno, &str);
config_include_depth--;
fclose(f.f); fclose(f.f);
if (ret) { if (ret) {
if (ret != HEIM_ERR_CONFIG_BADFORMAT) { if (ret != HEIM_ERR_CONFIG_BADFORMAT) {
ret = HEIM_ERR_CONFIG_BADFORMAT; ret = HEIM_ERR_CONFIG_BADFORMAT;
heim_set_error_message(context, ret, "%s:%u: %s", heim_set_error_message(context, ret, "%s:%u: %s",
fname, lineno, str); fname, lineno, str);
} }
free(newfname); goto out;
return ret;
} }
} }
return 0;
out:
config_include_depth--;
free(newfname);
return ret;
} }
heim_error_code heim_error_code