From e47c11822d6b459a9b3704b3ee6a4a5c9a1b85be Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 29 Jun 2021 18:02:27 +0200 Subject: [PATCH 1/2] control: remap - assign right name to the child handle for no-op Fixes: https://github.com/alsa-project/alsa-utils/issues/100 Signed-off-by: Jaroslav Kysela --- src/control/control_remap.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/control/control_remap.c b/src/control/control_remap.c index a85c1725..81524014 100644 --- a/src/control/control_remap.c +++ b/src/control/control_remap.c @@ -1173,6 +1173,10 @@ int snd_ctl_remap_open(snd_ctl_t **handlep, const char *name, snd_config_t *rema /* no-op check, remove the plugin */ if (priv->map_items == 0 && priv->remap_items == 0) { remap_free(priv); + free(child->name); + child->name = name ? strdup(name) : NULL; + if (name && !child->name) + return -ENOMEM; *handlep = child; return 0; } -- 2.31.1 From 23a191a82c693456e61431ab699cddc1e5782a26 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 29 Jun 2021 19:31:28 +0200 Subject: [PATCH 2/2] control: remap - assign right name to the child handle for no-op (2nd case) Fixes: https://github.com/alsa-project/alsa-utils/issues/100 Signed-off-by: Jaroslav Kysela --- src/control/control_remap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/control/control_remap.c b/src/control/control_remap.c index 81524014..4914f960 100644 --- a/src/control/control_remap.c +++ b/src/control/control_remap.c @@ -1154,6 +1154,10 @@ int snd_ctl_remap_open(snd_ctl_t **handlep, const char *name, snd_config_t *rema snd_ctl_t *ctl; int result, err; + /* no-op, remove the plugin */ + if (!remap && !map) + goto _noop; + priv = calloc(1, sizeof(*priv)); if (priv == NULL) return -ENOMEM; @@ -1173,6 +1177,7 @@ int snd_ctl_remap_open(snd_ctl_t **handlep, const char *name, snd_config_t *rema /* no-op check, remove the plugin */ if (priv->map_items == 0 && priv->remap_items == 0) { remap_free(priv); + _noop: free(child->name); child->name = name ? strdup(name) : NULL; if (name && !child->name) @@ -1316,11 +1321,6 @@ int _snd_ctl_remap_open(snd_ctl_t **handlep, char *name, snd_config_t *root, snd err = _snd_ctl_open_child(&cctl, root, child, mode, conf); if (err < 0) return err; - /* no-op, remove the plugin */ - if (!remap && !map) { - *handlep = cctl; - return 0; - } err = snd_ctl_remap_open(handlep, name, remap, map, cctl, mode); if (err < 0) snd_ctl_close(cctl); -- 2.31.1 From dd609ef9684987d3ca61d5c5cc3c77589ff9c29f Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 21 Jun 2021 09:28:41 +0200 Subject: [PATCH] pcm: direct plugins - fix hw_ptr in the status callback The parent hw_ptr may be in another range (boundary limit). Set the correct value for the caller. BugLink: https://github.com/alsa-project/alsa-lib/issues/155 Signed-off-by: Jaroslav Kysela --- src/pcm/pcm_dmix.c | 1 + src/pcm/pcm_dshare.c | 1 + src/pcm/pcm_dsnoop.c | 1 + 3 files changed, 3 insertions(+) diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c index 0d0d0bff..94dbb1e0 100644 --- a/src/pcm/pcm_dmix.c +++ b/src/pcm/pcm_dmix.c @@ -491,6 +491,7 @@ static int snd_pcm_dmix_status(snd_pcm_t *pcm, snd_pcm_status_t * status) } status->state = snd_pcm_dmix_state(pcm); + status->hw_ptr = *pcm->hw.ptr; /* boundary may be different */ status->appl_ptr = *pcm->appl.ptr; /* slave PCM doesn't set appl_ptr */ status->trigger_tstamp = dmix->trigger_tstamp; status->avail = snd_pcm_mmap_playback_avail(pcm); diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c index a918512b..01814dc8 100644 --- a/src/pcm/pcm_dshare.c +++ b/src/pcm/pcm_dshare.c @@ -243,6 +243,7 @@ static int snd_pcm_dshare_status(snd_pcm_t *pcm, snd_pcm_status_t * status) break; } status->state = snd_pcm_dshare_state(pcm); + status->hw_ptr = *pcm->hw.ptr; /* boundary may be different */ status->appl_ptr = *pcm->appl.ptr; /* slave PCM doesn't set appl_ptr */ status->trigger_tstamp = dshare->trigger_tstamp; status->avail = snd_pcm_mmap_playback_avail(pcm); diff --git a/src/pcm/pcm_dsnoop.c b/src/pcm/pcm_dsnoop.c index 2c3b9f43..3f28df99 100644 --- a/src/pcm/pcm_dsnoop.c +++ b/src/pcm/pcm_dsnoop.c @@ -193,6 +193,7 @@ static int snd_pcm_dsnoop_status(snd_pcm_t *pcm, snd_pcm_status_t * status) snd_pcm_status(dsnoop->spcm, status); state = snd_pcm_state(dsnoop->spcm); status->state = state == SND_PCM_STATE_RUNNING ? dsnoop->state : state; + status->hw_ptr = *pcm->hw.ptr; /* boundary may be different */ status->appl_ptr = *pcm->appl.ptr; /* slave PCM doesn't set appl_ptr */ status->trigger_tstamp = dsnoop->trigger_tstamp; status->avail = snd_pcm_mmap_capture_avail(pcm); -- 2.31.1 From e0e084659083c2ab75d5c894f24227ea2f67010f Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 21 Jun 2021 15:14:18 +0200 Subject: [PATCH] pcm: direct plugins - fix bad memory access when channel bindings do not match hw Fix and cleanup snd_pcm_direct_check_interleave() function. Add requested / hardware channel check and use goto when the interleaved Fixes: https://github.com/alsa-project/alsa-lib/issues/117 Signed-off-by: Jaroslav Kysela --- src/pcm/pcm_direct.c | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c index d50503e3..90417b2f 100644 --- a/src/pcm/pcm_direct.c +++ b/src/pcm/pcm_direct.c @@ -1627,43 +1627,37 @@ int snd_pcm_direct_set_timer_params(snd_pcm_direct_t *dmix) int snd_pcm_direct_check_interleave(snd_pcm_direct_t *dmix, snd_pcm_t *pcm) { unsigned int chn, channels; - int bits, interleaved = 1; + int bits; const snd_pcm_channel_area_t *dst_areas; const snd_pcm_channel_area_t *src_areas; bits = snd_pcm_format_physical_width(pcm->format); if ((bits % 8) != 0) - interleaved = 0; + goto __nointerleaved; channels = dmix->channels; + if (channels != dmix->spcm->channels) + goto __nointerleaved; dst_areas = snd_pcm_mmap_areas(dmix->spcm); src_areas = snd_pcm_mmap_areas(pcm); for (chn = 1; chn < channels; chn++) { - if (dst_areas[chn-1].addr != dst_areas[chn].addr) { - interleaved = 0; - break; - } - if (src_areas[chn-1].addr != src_areas[chn].addr) { - interleaved = 0; - break; - } + if (dst_areas[chn-1].addr != dst_areas[chn].addr) + goto __nointerleaved; + if (src_areas[chn-1].addr != src_areas[chn].addr) + goto __nointerleaved; } for (chn = 0; chn < channels; chn++) { - if (dmix->bindings && dmix->bindings[chn] != chn) { - interleaved = 0; - break; - } + if (dmix->bindings && dmix->bindings[chn] != chn) + goto __nointerleaved; if (dst_areas[chn].first != chn * bits || - dst_areas[chn].step != channels * bits) { - interleaved = 0; - break; - } + dst_areas[chn].step != channels * bits) + goto __nointerleaved; if (src_areas[chn].first != chn * bits || - src_areas[chn].step != channels * bits) { - interleaved = 0; - break; - } + src_areas[chn].step != channels * bits) + goto __nointerleaved; } - return dmix->interleaved = interleaved; + return dmix->interleaved = 1; +__nointerleaved: + return dmix->interleaved = 0; } /* -- 2.31.1