if (!strncmp(str, "searchdir:", 10)) {
/* directory to search included files */
- char *tmp = _snd_config_path(str + 10);
+ char *tmp;
+ err = snd_relative_path_check(str + 10);
+ if (err < 0) {
+ snd_error(CONFIG, "Search dir path '%s' escapes the configuration directory", str + 10);
+ free(str);
+ return err;
+ }
+ tmp = _snd_config_path(str + 10);
free(str);
if (tmp == NULL)
return -ENOMEM;
if (!strncmp(str, "confdir:", 8)) {
/* file in the specified directory */
- char *tmp = _snd_config_path(str + 8);
+ char *tmp;
+ err = snd_relative_path_check(str + 8);
+ if (err < 0) {
+ snd_error(CONFIG, "Config dir path '%s' escapes the configuration directory", str + 8);
+ free(str);
+ return err;
+ }
+ tmp = _snd_config_path(str + 8);
free(str);
if (tmp == NULL)
return -ENOMEM;
/*
* compose the absolute ucm filename
*/
-static void ucm_filename(char *fn, size_t fn_len, long version,
- const char *dir, const char *file)
+static int ucm_filename(char *fn, size_t fn_len, long version,
+ const char *dir, const char *file)
{
const char *env = getenv(version > 1 ? ALSA_CONFIG_UCM2_VAR : ALSA_CONFIG_UCM_VAR);
if (file[0] == '/')
file++;
+ if (snd_relative_path_check(file) < 0 ||
+ (dir && snd_relative_path_check(dir) < 0)) {
+ snd_error(UCM, "config file path '%s%s%s' escapes the configuration directory",
+ dir ?: "", dir ? "/" : "", file);
+ return -EINVAL;
+ }
if (env == NULL)
snprintf(fn, fn_len, "%s/%s/%s%s%s",
snd_config_topdir(), version > 1 ? "ucm2" : "ucm",
else
snprintf(fn, fn_len, "%s/%s%s%s",
env, dir ?: "", dir ? "/" : "", file);
+ return 0;
}
/*
char filename[PATH_MAX];
int err;
- ucm_filename(filename, sizeof(filename), uc_mgr->conf_format,
- file[0] == '/' ? NULL : uc_mgr->conf_dir_name,
- file);
+ err = ucm_filename(filename, sizeof(filename), uc_mgr->conf_format,
+ file[0] == '/' ? NULL : uc_mgr->conf_dir_name,
+ file);
+ if (err < 0)
+ return err;
err = uc_mgr_config_load(uc_mgr->conf_format, filename, cfg, optional);
if (err < 0) {
if (!optional || (err != -ENOENT && err != -EACCES))
} else {
char filename[PATH_MAX];
- ucm_filename(filename, sizeof(filename), uc_mgr->conf_format,
- file[0] == '/' ? NULL : uc_mgr->conf_dir_name,
- file);
+ err = ucm_filename(filename, sizeof(filename), uc_mgr->conf_format,
+ file[0] == '/' ? NULL : uc_mgr->conf_dir_name,
+ file);
+ if (err < 0)
+ return err;
err = uc_mgr_config_load_into(uc_mgr->conf_format, filename, uc_mgr->local_config, false);
if (err < 0)
return err;
goto __next;
}
- ucm_filename(fn, sizeof(fn), version, dir, file);
+ if (ucm_filename(fn, sizeof(fn), version, dir, file) < 0)
+ goto __next;
snd_trace(UCM, "probing configuration file '%s'", fn);
if (access(fn, R_OK) == 0 && lstat64(fn, &st) == 0) {
if (S_ISLNK(st.st_mode)) {
d_name = namelist[i]->d_name;
snprintf(fn, sizeof(fn), "%s.conf", d_name);
- ucm_filename(filename, sizeof(filename), 2, d_name, fn);
+ if (ucm_filename(filename, sizeof(filename), 2, d_name, fn) < 0)
+ continue;
#ifdef HAVE_EACCESS
if (eaccess(filename, R_OK))
#else