Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -643,8 +643,11 @@ static int input_stdio_open(snd_input_t **inputp, const char *file,
char full_path[PATH_MAX];
int err;

if (file[0] == '/')
if (file[0] == '/') {
if (strstr(file, "/../"))
return -ENOENT;
return snd_input_stdio_open(inputp, file, "r");
}

/* search file in user specified include paths. These directories
* are subdirectories of /usr/share/alsa.
Expand Down
6 changes: 4 additions & 2 deletions src/pcm/pcm_multi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1121,8 +1121,10 @@ int snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
}
for (i = 0; i < channels_count; ++i) {
snd_pcm_multi_channel_t *bind = &multi->channels[i];
assert(sidxs[i] < (int)slaves_count);
assert(schannels[i] < schannels_count[sidxs[i]]);
if (sidxs[i] < 0 || sidxs[i] >= (int)slaves_count) {
SNDERR("multi: ch %d invalid slave idx %d", i, sidxs[i]); return -EINVAL; }
if (schannels[i] >= schannels_count[sidxs[i]]) {
SNDERR("multi: ch %d channel %d out of range", i, schannels[i]); return -EINVAL; }
bind->slave_idx = sidxs[i];
bind->slave_channel = schannels[i];
if (sidxs[i] < 0)
Expand Down
2 changes: 2 additions & 0 deletions src/pcm/pcm_route.c
Original file line number Diff line number Diff line change
Expand Up @@ -1098,6 +1098,7 @@ static int _snd_pcm_route_determine_ttable(snd_config_t *tt,
}
if (cchannel + 1 > csize)
csize = cchannel + 1;
if (csize > 1024) { SNDERR("route: client channel %d exceeds max (1024)", cchannel); return -EINVAL; }
if (snd_config_get_type(in) != SND_CONFIG_TYPE_COMPOUND)
return -EINVAL;
snd_config_for_each(j, jnext, in) {
Expand All @@ -1113,6 +1114,7 @@ static int _snd_pcm_route_determine_ttable(snd_config_t *tt,
}
if (schannel + 1 > ssize)
ssize = schannel + 1;
if (ssize > 1024) { SNDERR("route: slave channel %d exceeds max (1024)", schannel); return -EINVAL; }
}
}
if (csize == 0 || ssize == 0) {
Expand Down
21 changes: 18 additions & 3 deletions src/topology/ctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1315,7 +1315,12 @@ int tplg_decode_control_mixer(snd_tplg_t *tplg,
}
INIT_LIST_HEAD(&heap);
mc = bin;
size2 = mc->size + mc->priv.size;
if (mc->priv.size > size || mc->size > size - mc->priv.size) {
snd_error(TOPOLOGY, "mixer: element sizes overflow (%d, priv %d)",
mc->size, mc->priv.size);
return -EINVAL;
}
size2 = (size_t)mc->size + (size_t)mc->priv.size;
if (size2 > size) {
snd_error(TOPOLOGY, "mixer: wrong element size (%d, priv %d)",
mc->size, mc->priv.size);
Expand Down Expand Up @@ -1419,7 +1424,12 @@ int tplg_decode_control_enum(snd_tplg_t *tplg,
}
INIT_LIST_HEAD(&heap);
ec = bin;
size2 = ec->size + ec->priv.size;
if (ec->priv.size > size || ec->size > size - ec->priv.size) {
snd_error(TOPOLOGY, "enum: element sizes overflow (%d, priv %d)",
ec->size, ec->priv.size);
return -EINVAL;
}
size2 = (size_t)ec->size + (size_t)ec->priv.size;
if (size2 > size) {
snd_error(TOPOLOGY, "enum: wrong element size (%d, priv %d)",
ec->size, ec->priv.size);
Expand Down Expand Up @@ -1510,7 +1520,12 @@ int tplg_decode_control_bytes(snd_tplg_t *tplg,
return -EINVAL;
}
bc = bin;
size2 = bc->size + bc->priv.size;
if (bc->priv.size > size || bc->size > size - bc->priv.size) {
snd_error(TOPOLOGY, "bytes: element sizes overflow (%d, priv %d)",
bc->size, bc->priv.size);
return -EINVAL;
}
size2 = (size_t)bc->size + (size_t)bc->priv.size;
if (size2 > size) {
snd_error(TOPOLOGY, "bytes: wrong element size (%d, priv %d)",
bc->size, bc->priv.size);
Expand Down
11 changes: 11 additions & 0 deletions src/ucm/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,12 @@ static int execute_sysw(const char *sysw)
}
snprintf(path, sizeof(path), "%s/%s", e, s);

{ char *resolved = realpath(path, NULL); size_t rootlen = strlen(e);
if (!resolved || strncmp(resolved, e, rootlen) != 0) {
free(resolved); free(s);
snd_error(UCM, "sysw path escapes sysfs root: '%s'", path);
return -EINVAL; } free(resolved); }

fd = open(path, O_WRONLY|O_CLOEXEC);
if (fd < 0) {
free(s);
Expand Down Expand Up @@ -625,6 +631,11 @@ static int execute_cfgsave(snd_use_case_mgr_t *uc_mgr, const char *filename)
}
}

{ const char *runtime = getenv("XDG_RUNTIME_DIR"); if (!runtime) runtime = "/tmp";
char *resolved = realpath(file, NULL);
if (!resolved || strncmp(resolved, runtime, strlen(runtime)) != 0) {
free(resolved); snd_error(UCM, "cfg-save path escapes runtime dir: '%s'", file);
return -EINVAL; } free(resolved); }
err = snd_output_stdio_open(&out, file, "w+");
if (err < 0) {
snd_error(UCM, "unable to open file '%s': %s", file, snd_strerror(err));
Expand Down
Loading