mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2026-02-22 01:40:08 -05:00
pcm: dshare: Fix segfault when not binding channel 0
Configuration to reproduce:
~~~~
pcm.share_right {
type dshare
ipc_key 73
ipc_perm 0666
slave {
pcm "hw:0,0"
}
bindings {
# the seagfault happens when we don't bind channel 0
1 1
}
}
~~~~
Execute to reproduce:
~~~~
$ aplay -D plug:share_right test.wav
Playing WAVE 'test.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
Segmentation fault
~~~~
For channels whithout binding, values are set to UINT_MAX in function
`snd_pcm_direct_parse_bindings()`:
~~~~
for (chn = 0; chn < count; chn++)
bindings[chn] = UINT_MAX; /* don't route */
~~~~
But, these values are not checked when playing, which causes the segfault.
This commit fixes the issue.
Signed-off-by: Kirill Marinushkin <kmarinushkin@birdec.tech>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
6b058fda9d
commit
d3dfef24bf
1 changed files with 11 additions and 4 deletions
|
|
@ -67,7 +67,9 @@ static void do_silence(snd_pcm_t *pcm)
|
||||||
format = dshare->shmptr->s.format;
|
format = dshare->shmptr->s.format;
|
||||||
for (chn = 0; chn < channels; chn++) {
|
for (chn = 0; chn < channels; chn++) {
|
||||||
dchn = dshare->bindings ? dshare->bindings[chn] : chn;
|
dchn = dshare->bindings ? dshare->bindings[chn] : chn;
|
||||||
snd_pcm_area_silence(&dst_areas[dchn], 0, dshare->shmptr->s.buffer_size, format);
|
if (dchn != UINT_MAX)
|
||||||
|
snd_pcm_area_silence(&dst_areas[dchn], 0,
|
||||||
|
dshare->shmptr->s.buffer_size, format);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,7 +93,9 @@ static void share_areas(snd_pcm_direct_t *dshare,
|
||||||
} else {
|
} else {
|
||||||
for (chn = 0; chn < channels; chn++) {
|
for (chn = 0; chn < channels; chn++) {
|
||||||
dchn = dshare->bindings ? dshare->bindings[chn] : chn;
|
dchn = dshare->bindings ? dshare->bindings[chn] : chn;
|
||||||
snd_pcm_area_copy(&dst_areas[dchn], dst_ofs, &src_areas[chn], src_ofs, size, format);
|
if (dchn != UINT_MAX)
|
||||||
|
snd_pcm_area_copy(&dst_areas[dchn], dst_ofs,
|
||||||
|
&src_areas[chn], src_ofs, size, format);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -834,8 +838,11 @@ int snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
|
||||||
dshare->spcm = spcm;
|
dshare->spcm = spcm;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (chn = 0; chn < dshare->channels; chn++)
|
for (chn = 0; chn < dshare->channels; chn++) {
|
||||||
dshare->u.dshare.chn_mask |= (1ULL<<dshare->bindings[chn]);
|
unsigned int dchn = dshare->bindings ? dshare->bindings[chn] : chn;
|
||||||
|
if (dchn != UINT_MAX)
|
||||||
|
dshare->u.dshare.chn_mask |= (1ULL << dchn);
|
||||||
|
}
|
||||||
if (dshare->shmptr->u.dshare.chn_mask & dshare->u.dshare.chn_mask) {
|
if (dshare->shmptr->u.dshare.chn_mask & dshare->u.dshare.chn_mask) {
|
||||||
SNDERR("destination channel specified in bindings is already used");
|
SNDERR("destination channel specified in bindings is already used");
|
||||||
dshare->u.dshare.chn_mask = 0;
|
dshare->u.dshare.chn_mask = 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue