Blob Blame Raw
From ddfc32abf5697de1618b9e7ffdf57a0f97013090 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 2 Jun 2021 08:49:32 +0200
Subject: [PATCH 01/28] conf: fix load_for_all_cards()

The 63f7745b commit is loading the driver specific configuration
multiple times which ends with the array merges (see the bug).

Introduce the loaded compound which traces the already loaded
driver configurations and skip the multiple load requests.

Fixes: https://github.com/alsa-project/alsa-lib/issues/143
Fixes: 63f7745b ("conf: extend load_for_all_cards hook (id/value table)")
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/conf.c | 33 ++++++++++++++++++++++++++++-----
 1 file changed, 28 insertions(+), 5 deletions(-)

diff --git a/src/conf.c b/src/conf.c
index f6c80031..d863dec6 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -4325,18 +4325,23 @@ static int _snd_config_hook_table(snd_config_t *root, snd_config_t *config, snd_
 int snd_config_hook_load_for_all_cards(snd_config_t *root, snd_config_t *config, snd_config_t **dst, snd_config_t *private_data ATTRIBUTE_UNUSED)
 {
 	int card = -1, err;
+	snd_config_t *loaded;	// trace loaded cards
 	
+	err = snd_config_top(&loaded);
+	if (err < 0)
+		return err;
 	do {
 		err = snd_card_next(&card);
 		if (err < 0)
-			return err;
+			goto __fin_err;
 		if (card >= 0) {
-			snd_config_t *n, *private_data = NULL;
+			snd_config_t *n, *m, *private_data = NULL;
 			const char *driver;
 			char *fdriver = NULL;
+			bool load;
 			err = snd_determine_driver(card, &fdriver);
 			if (err < 0)
-				return err;
+				goto __fin_err;
 			if (snd_config_search(root, fdriver, &n) >= 0) {
 				if (snd_config_get_string(n, &driver) < 0) {
 					if (snd_config_get_type(n) == SND_CONFIG_TYPE_COMPOUND) {
@@ -4357,6 +4362,19 @@ int snd_config_hook_load_for_all_cards(snd_config_t *root, snd_config_t *config,
 				driver = fdriver;
 			}
 		      __std:
+			load = true;
+			err = snd_config_imake_integer(&m, driver, 1);
+			if (err < 0)
+				goto __err;
+			err = snd_config_add(loaded, m);
+			if (err < 0) {
+				if (err == -EEXIST) {
+					snd_config_delete(m);
+					load = false;
+				} else {
+					goto __err;
+				}
+			}
 			private_data = _snd_config_hook_private_data(card, driver);
 			if (!private_data) {
 				err = -ENOMEM;
@@ -4365,17 +4383,22 @@ int snd_config_hook_load_for_all_cards(snd_config_t *root, snd_config_t *config,
 			err = _snd_config_hook_table(root, config, private_data);
 			if (err < 0)
 				goto __err;
-			err = snd_config_hook_load(root, config, &n, private_data);
+			if (load)
+				err = snd_config_hook_load(root, config, &n, private_data);
 		      __err:
 			if (private_data)
 				snd_config_delete(private_data);
 			free(fdriver);
 			if (err < 0)
-				return err;
+				goto __fin_err;
 		}
 	} while (card >= 0);
+	snd_config_delete(loaded);
 	*dst = NULL;
 	return 0;
+__fin_err:
+	snd_config_delete(loaded);
+	return err;
 }
 #ifndef DOC_HIDDEN
 SND_DLSYM_BUILD_VERSION(snd_config_hook_load_for_all_cards, SND_CONFIG_DLSYM_VERSION_HOOK);
-- 
2.30.2


From 0e4ba2ea8c0402f12a645032a14693eb9b1278e6 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 2 Jun 2021 11:09:43 +0200
Subject: [PATCH 02/28] ucm: add _alibpref to get the private device prefix

It may be useful to get the device prefix for the local configuration.

Link: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/1251
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 include/use-case.h |  1 +
 src/ucm/main.c     | 21 +++++++++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/include/use-case.h b/include/use-case.h
index ec1a97b0..7890358b 100644
--- a/include/use-case.h
+++ b/include/use-case.h
@@ -258,6 +258,7 @@ int snd_use_case_get_list(snd_use_case_mgr_t *uc_mgr,
  *   - _verb		- return current verb
  *   - _file		- return configuration file loaded for current card
  *   - _alibcfg		- return private alsa-lib's configuration for current card
+ *   - _alibpref	- return private alsa-lib's configuration device prefix for current card
  *
  *   - [=]{NAME}[/[{modifier}|{/device}][/{verb}]]
  *                      - value identifier {NAME}
diff --git a/src/ucm/main.c b/src/ucm/main.c
index 361952f6..3c9ea15d 100644
--- a/src/ucm/main.c
+++ b/src/ucm/main.c
@@ -2138,6 +2138,25 @@ static int get_alibcfg(snd_use_case_mgr_t *uc_mgr, char **str)
 	return 0;
 }
 
+/**
+ * \brief Get device prefix for private alsa-lib configuration
+ * \param uc_mgr Use case manager
+ * \param str Returned value string
+ * \return Zero on success (value is filled), otherwise a negative error code
+ */
+static int get_alibpref(snd_use_case_mgr_t *uc_mgr, char **str)
+{
+	const size_t l = 9;
+	char *s;
+
+	s = malloc(l);
+	if (s == NULL)
+		return -ENOMEM;
+	snprintf(s, l, "_ucm%04X", uc_mgr->ucm_card_number);
+	*str = s;
+	return 0;
+}
+
 /**
  * \brief Get current - string
  * \param uc_mgr Use case manager
@@ -2193,6 +2212,8 @@ int snd_use_case_get(snd_use_case_mgr_t *uc_mgr,
 
 	} else if (strcmp(identifier, "_alibcfg") == 0) {
 		err = get_alibcfg(uc_mgr, (char **)value);
+	} else if (strcmp(identifier, "_alibpref") == 0) {
+		err = get_alibpref(uc_mgr, (char **)value);
 	} else if (identifier[0] == '_') {
 		err = -ENOENT;
 	} else {
-- 
2.30.2


From 9621d0bff2e60b43e329ffa5059ab19f2914ec14 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 2 Jun 2021 11:21:54 +0200
Subject: [PATCH 03/28] ucm: fix _alibpref string (add '.' delimiter to the
 end)

Fixes: 0e4ba2ea ("ucm: add _alibpref to get the private device prefix")
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/ucm/main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/ucm/main.c b/src/ucm/main.c
index 3c9ea15d..c9b37b68 100644
--- a/src/ucm/main.c
+++ b/src/ucm/main.c
@@ -2146,13 +2146,13 @@ static int get_alibcfg(snd_use_case_mgr_t *uc_mgr, char **str)
  */
 static int get_alibpref(snd_use_case_mgr_t *uc_mgr, char **str)
 {
-	const size_t l = 9;
+	const size_t l = 10;
 	char *s;
 
 	s = malloc(l);
 	if (s == NULL)
 		return -ENOMEM;
-	snprintf(s, l, "_ucm%04X", uc_mgr->ucm_card_number);
+	snprintf(s, l, "_ucm%04X.", uc_mgr->ucm_card_number);
 	*str = s;
 	return 0;
 }
-- 
2.30.2


From 2a1dafdbe5932260aeb4db359ce5d630b8106889 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 2 Jun 2021 19:26:47 +0200
Subject: [PATCH 04/28] conf: remove dead code in snd_config_get_card()

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/confmisc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/confmisc.c b/src/confmisc.c
index 3663d164..a561040c 100644
--- a/src/confmisc.c
+++ b/src/confmisc.c
@@ -154,10 +154,10 @@ int snd_config_get_card(const snd_config_t *conf)
 	long v;
 	int err;
 
-	if ((err = snd_config_get_integer(conf, &v)) < 0) {
+	if (snd_config_get_integer(conf, &v) < 0) {
 		if ((err = snd_config_get_string(conf, &str)) < 0) {
-			snd_config_get_id(conf, &id);
-			SNDERR("Invalid field %s", id);
+			if (snd_config_get_id(conf, &id) >= 0)
+				SNDERR("Invalid field %s", id);
 			return -EINVAL;
 		}
 		err = snd_card_get_index(str);
-- 
2.30.2


From 013ec607db9de11b682f2b85d843be062ca0d046 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 2 Jun 2021 19:28:32 +0200
Subject: [PATCH 05/28] control: remap - fix uninitialized value in
 parse_map_vindex()

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/control/control_remap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/control/control_remap.c b/src/control/control_remap.c
index f3d65010..17c6558a 100644
--- a/src/control/control_remap.c
+++ b/src/control/control_remap.c
@@ -1040,7 +1040,7 @@ static int parse_map_vindex(struct snd_ctl_map_ctl *mctl, snd_config_t *conf)
 
 	snd_config_for_each(i, next, conf) {
 		snd_config_t *n = snd_config_iterator_entry(i);
-		long idx, chn;
+		long idx = -1, chn = -1;
 		const char *id;
 		if (snd_config_get_id(n, &id) < 0)
 			continue;
-- 
2.30.2


From 2fee6af9b6e157475159d284af8de1e879bb7a36 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 2 Jun 2021 19:35:44 +0200
Subject: [PATCH 06/28] pcm: direct - fix pcmp error path in
 _snd_pcm_direct_new()

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/pcm/pcm_direct.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c
index 0e5e0421..361805bd 100644
--- a/src/pcm/pcm_direct.c
+++ b/src/pcm/pcm_direct.c
@@ -2126,24 +2126,20 @@ int _snd_pcm_direct_new(snd_pcm_t **pcmp, snd_pcm_direct_t **_dmix, int type,
 	dmix->type = type;
 
 	ret = snd_pcm_new(pcmp, type, name, stream, mode);
-	if (ret < 0) {
-_err_nosem:
-		free(dmix->bindings);
-		free(dmix);
-		return ret;
-	}
+	if (ret < 0)
+		goto _err_nosem;
 
 	while (1) {
 		ret = snd_pcm_direct_semaphore_create_or_connect(dmix);
 		if (ret < 0) {
 			SNDERR("unable to create IPC semaphore");
-			goto _err_nosem;
+			goto _err_nosem_free;
 		}
 		ret = snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT);
 		if (ret < 0) {
 			snd_pcm_direct_semaphore_discard(dmix);
 			if (--fail_sem_loop <= 0)
-				goto _err_nosem;
+				goto _err_nosem_free;
 			continue;
 		}
 		break;
@@ -2153,10 +2149,17 @@ _err_nosem:
 	if (ret < 0) {
 		SNDERR("unable to create IPC shm instance");
 		snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
-		goto _err_nosem;
+		goto _err_nosem_free;
 	} else {
 		*_dmix = dmix;
 	}
 
+	return ret;
+_err_nosem_free:
+	snd_pcm_free(*pcmp);
+	*pcmp = NULL;
+_err_nosem:
+	free(dmix->bindings);
+	free(dmix);
 	return ret;
 }
-- 
2.30.2


From eb95cad4e22a0bf2577f1fa4a3f6fd18caed3362 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 2 Jun 2021 19:37:53 +0200
Subject: [PATCH 07/28] pcm: remove extra NULL checks in snd_pcm_dmix_open()

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/pcm/pcm_dmix.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c
index 8747450f..608593f1 100644
--- a/src/pcm/pcm_dmix.c
+++ b/src/pcm/pcm_dmix.c
@@ -998,7 +998,7 @@ int snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
 		      snd_config_t *root, snd_config_t *sconf,
 		      snd_pcm_stream_t stream, int mode)
 {
-	snd_pcm_t *pcm = NULL, *spcm = NULL;
+	snd_pcm_t *pcm, *spcm = NULL;
 	snd_pcm_direct_t *dmix;
 	int ret, first_instance;
 
@@ -1154,12 +1154,9 @@ int snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
 	} else
 		snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
  _err_nosem:
-	if (dmix) {
-		free(dmix->bindings);
-		free(dmix);
-	}
-	if (pcm)
-		snd_pcm_free(pcm);
+	free(dmix->bindings);
+	free(dmix);
+	snd_pcm_free(pcm);
 	return ret;
 }
 
-- 
2.30.2


From 01a45aec6fcd5a5378a5b5e0ae0f9dacde2068e4 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 2 Jun 2021 19:39:32 +0200
Subject: [PATCH 08/28] pcm: remove extra NULL checks in snd_pcm_dsnoop_open()

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/pcm/pcm_dsnoop.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/src/pcm/pcm_dsnoop.c b/src/pcm/pcm_dsnoop.c
index fb1b02c2..2c3b9f43 100644
--- a/src/pcm/pcm_dsnoop.c
+++ b/src/pcm/pcm_dsnoop.c
@@ -564,8 +564,8 @@ int snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
 			snd_config_t *root, snd_config_t *sconf,
 			snd_pcm_stream_t stream, int mode)
 {
-	snd_pcm_t *pcm = NULL, *spcm = NULL;
-	snd_pcm_direct_t *dsnoop = NULL;
+	snd_pcm_t *pcm, *spcm = NULL;
+	snd_pcm_direct_t *dsnoop;
 	int ret, first_instance;
 
 	assert(pcmp);
@@ -708,12 +708,9 @@ int snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
 		snd_pcm_direct_semaphore_up(dsnoop, DIRECT_IPC_SEM_CLIENT);
 
  _err_nosem:
-	if (dsnoop) {
-		free(dsnoop->bindings);
-		free(dsnoop);
-	}
-	if (pcm)
-		snd_pcm_free(pcm);
+	free(dsnoop->bindings);
+	free(dsnoop);
+	snd_pcm_free(pcm);
 	return ret;
 }
 
-- 
2.30.2


From 74c6382df6cf18b801659d8c5c53407a7ea1f02b Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 2 Jun 2021 19:46:46 +0200
Subject: [PATCH 09/28] pcm: remove extra NULL checks in snd_pcm_dshare_open()

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/pcm/pcm_dshare.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c
index 0f5238a6..a918512b 100644
--- a/src/pcm/pcm_dshare.c
+++ b/src/pcm/pcm_dshare.c
@@ -690,8 +690,8 @@ int snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
 			snd_config_t *root, snd_config_t *sconf,
 			snd_pcm_stream_t stream, int mode)
 {
-	snd_pcm_t *pcm = NULL, *spcm = NULL;
-	snd_pcm_direct_t *dshare = NULL;
+	snd_pcm_t *pcm, *spcm = NULL;
+	snd_pcm_direct_t *dshare;
 	int ret, first_instance;
 	unsigned int chn;
 
@@ -851,12 +851,9 @@ int snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
 	} else
 		snd_pcm_direct_semaphore_up(dshare, DIRECT_IPC_SEM_CLIENT);
  _err_nosem:
-	if (dshare) {
-		free(dshare->bindings);
-		free(dshare);
-	}
-	if (pcm)
-		snd_pcm_free(pcm);
+	free(dshare->bindings);
+	free(dshare);
+	snd_pcm_free(pcm);
 	return ret;
 }
 
-- 
2.30.2


From eabadf545c51d4c88c5f359db73726ec3ac653ba Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 2 Jun 2021 19:49:29 +0200
Subject: [PATCH 10/28] pcm: softvol - fix early exit in add_tlv_info()

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/pcm/pcm_softvol.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/pcm/pcm_softvol.c b/src/pcm/pcm_softvol.c
index e2bdd31a..eea322ca 100644
--- a/src/pcm/pcm_softvol.c
+++ b/src/pcm/pcm_softvol.c
@@ -711,13 +711,13 @@ static int add_tlv_info(snd_pcm_softvol_t *svol, snd_ctl_elem_info_t *cinfo,
 			unsigned int *old_tlv, size_t old_tlv_size)
 {
 	unsigned int tlv[4];
-	if (sizeof(tlv) <= old_tlv_size && memcmp(tlv, old_tlv, sizeof(tlv)) == 0)
-		return 0;
 	tlv[SNDRV_CTL_TLVO_TYPE] = SND_CTL_TLVT_DB_SCALE;
 	tlv[SNDRV_CTL_TLVO_LEN] = 2 * sizeof(int);
 	tlv[SNDRV_CTL_TLVO_DB_SCALE_MIN] = (int)(svol->min_dB * 100);
 	tlv[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] =
 		(int)((svol->max_dB - svol->min_dB) * 100 / svol->max_val);
+	if (sizeof(tlv) <= old_tlv_size && memcmp(tlv, old_tlv, sizeof(tlv)) == 0)
+		return 0;
 	return snd_ctl_elem_tlv_write(svol->ctl, &cinfo->id, tlv);
 }
 
-- 
2.30.2


From cf3846d46053b23006e6a9042b586fc78e81af55 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 2 Jun 2021 19:50:17 +0200
Subject: [PATCH 11/28] timer: remove dead code in _snd_timer_hw_open()

---
 src/timer/timer_hw.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/timer/timer_hw.c b/src/timer/timer_hw.c
index cfb77463..fe4e40bb 100644
--- a/src/timer/timer_hw.c
+++ b/src/timer/timer_hw.c
@@ -330,8 +330,6 @@ int _snd_timer_hw_open(snd_timer_t **timer, char *name,
 		SNDERR("Unexpected field %s", id);
 		return -EINVAL;
 	}
-	if (card < 0)
-		return -EINVAL;
 	return snd_timer_hw_open(timer, name, dev_class, dev_sclass, card, device, subdevice, mode);
 }
 SND_DLSYM_BUILD_VERSION(_snd_timer_hw_open, SND_TIMER_DLSYM_VERSION);
-- 
2.30.2


From 200d18cda7a700607c21ad5dc9faaea2a1e27dbd Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 2 Jun 2021 19:51:13 +0200
Subject: [PATCH 12/28] ucm: fix error path in execute_cfgsave()

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/ucm/main.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/ucm/main.c b/src/ucm/main.c
index c9b37b68..42fdaa1d 100644
--- a/src/ucm/main.c
+++ b/src/ucm/main.c
@@ -605,8 +605,10 @@ static int execute_cfgsave(snd_use_case_mgr_t *uc_mgr, const char *filename)
 		uc_error("unable to open file '%s': %s", file, snd_strerror(err));
 		goto _err;
 	}
-	if (!config || snd_config_is_empty(config))
+	if (!config || snd_config_is_empty(config)) {
+		snd_output_close(out);
 		goto _err;
+	}
 	if (with_root) {
 		snd_output_printf(out, "%s ", root);
 		err = _snd_config_save_node_value(config, out, 0);
-- 
2.30.2


From 9b71d53bde21c8bb0d900c17863664e12753d844 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 2 Jun 2021 19:52:12 +0200
Subject: [PATCH 13/28] ucm: fix use after free in if_eval_regex_match()

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/ucm/ucm_cond.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/ucm/ucm_cond.c b/src/ucm/ucm_cond.c
index 59d1a155..adb0ecd9 100644
--- a/src/ucm/ucm_cond.c
+++ b/src/ucm/ucm_cond.c
@@ -160,11 +160,12 @@ static int if_eval_regex_match(snd_use_case_mgr_t *uc_mgr, snd_config_t *eval)
 	if (err < 0)
 		return err;
 	err = regcomp(&re, s, options);
-	free(s);
 	if (err) {
 		uc_error("Regex '%s' compilation failed (code %d)", s, err);
+		free(s);
 		return -EINVAL;
 	}
+	free(s);
 
 	err = uc_mgr_get_substituted_value(uc_mgr, &s, string);
 	if (err < 0) {
-- 
2.30.2


From 7764e3e621a4c8a52327833d44e32c8b6fe3a131 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 2 Jun 2021 19:53:24 +0200
Subject: [PATCH 14/28] ucm: fix if_eval_path() - access NULL pointer

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/ucm/ucm_cond.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/ucm/ucm_cond.c b/src/ucm/ucm_cond.c
index adb0ecd9..0ed0b690 100644
--- a/src/ucm/ucm_cond.c
+++ b/src/ucm/ucm_cond.c
@@ -272,7 +272,7 @@ static int if_eval_control_exists(snd_use_case_mgr_t *uc_mgr, snd_config_t *eval
 
 static int if_eval_path(snd_use_case_mgr_t *uc_mgr, snd_config_t *eval)
 {
-	const char *path, *mode = NULL;
+	const char *path, *mode = "";
 	int err, amode = F_OK;
 
 	if (uc_mgr->conf_format < 4) {
-- 
2.30.2


From 7fcb1aadd56e94f03e51c4747e72d77279151c22 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 2 Jun 2021 19:56:01 +0200
Subject: [PATCH 15/28] ucm: find_exec() - fix memory leak (dir)

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/ucm/ucm_exec.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/ucm/ucm_exec.c b/src/ucm/ucm_exec.c
index a22df8fe..1cdb2633 100644
--- a/src/ucm/ucm_exec.c
+++ b/src/ucm/ucm_exec.c
@@ -73,6 +73,7 @@ static int find_exec(const char *name, char *out, size_t len)
 				    || !(st.st_mode & S_IEXEC))
 					continue;
 				snd_strlcpy(out, bin, len);
+				closedir(dir);
 				return 1;
 			}
 			closedir(dir);
-- 
2.30.2


From 26ab7fc3e4cba416cf51aa0fb48fdddaa0d861ee Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 2 Jun 2021 19:58:04 +0200
Subject: [PATCH 16/28] ucm: fix possible NULL pointer dereference in
 uc_mgr_exec()

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/ucm/ucm_exec.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/ucm/ucm_exec.c b/src/ucm/ucm_exec.c
index 1cdb2633..d83206d0 100644
--- a/src/ucm/ucm_exec.c
+++ b/src/ucm/ucm_exec.c
@@ -185,7 +185,11 @@ int uc_mgr_exec(const char *prog)
 		return -EINVAL;
 
 	prog = argv[0];
-	if (argv[0][0] != '/' && argv[0][0] != '.') {
+	if (prog == NULL) {
+		err = -EINVAL;
+		goto __error;
+	}
+	if (prog[0] != '/' && prog[0] != '.') {
 		if (!find_exec(argv[0], bin, sizeof(bin))) {
 			err = -ENOEXEC;
 			goto __error;
-- 
2.30.2


From 64a6d4d1e827732bef7c68e1e6d2cb6863b4597c Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 2 Jun 2021 19:59:10 +0200
Subject: [PATCH 17/28] ucm: check error value in parse_lookup_query()

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/ucm/ucm_subs.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/ucm/ucm_subs.c b/src/ucm/ucm_subs.c
index c56730c5..0bc4e63f 100644
--- a/src/ucm/ucm_subs.c
+++ b/src/ucm/ucm_subs.c
@@ -224,7 +224,11 @@ static snd_config_t *parse_lookup_query(const char *query)
 		uc_error("unable to create memory input buffer");
 		return NULL;
 	}
-	snd_config_top(&config);
+	err = snd_config_top(&config);
+	if (err < 0) {
+		snd_input_close(input);
+		return NULL;
+	}
 	err = snd_config_load(config, input);
 	snd_input_close(input);
 	if (err < 0) {
-- 
2.30.2


From 30d1d256e792fbabf14c57efb98c489541b19f37 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Wed, 2 Jun 2021 20:01:08 +0200
Subject: [PATCH 18/28] ucm: fix out-of-array access in
 rval_device_lookup_init()

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/ucm/ucm_subs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/ucm/ucm_subs.c b/src/ucm/ucm_subs.c
index 0bc4e63f..20905c3f 100644
--- a/src/ucm/ucm_subs.c
+++ b/src/ucm/ucm_subs.c
@@ -489,7 +489,7 @@ static int rval_device_lookup_init(snd_use_case_mgr_t *uc_mgr,
 		uc_error("Missing device type!");
 		return -EINVAL;
 	}
-	for (t = types; t; t++)
+	for (t = types; t->name; t++)
 		if (strcasecmp(t->name, s) == 0)
 			return t->init(iter, config);
 	uc_error("Device type '%s' is invalid", s);
-- 
2.30.2


From 42c0ccf3275fef523471fa7ea4feecd7b1052357 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Thu, 3 Jun 2021 07:29:11 +0200
Subject: [PATCH 19/28] conf: snd_config_get_card() remove unused assignment

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/confmisc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/confmisc.c b/src/confmisc.c
index a561040c..64af96fa 100644
--- a/src/confmisc.c
+++ b/src/confmisc.c
@@ -155,7 +155,7 @@ int snd_config_get_card(const snd_config_t *conf)
 	int err;
 
 	if (snd_config_get_integer(conf, &v) < 0) {
-		if ((err = snd_config_get_string(conf, &str)) < 0) {
+		if (snd_config_get_string(conf, &str)) {
 			if (snd_config_get_id(conf, &id) >= 0)
 				SNDERR("Invalid field %s", id);
 			return -EINVAL;
-- 
2.30.2


From a154cb29043a4db2fa92bc146fd4cf94c9851892 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Thu, 3 Jun 2021 07:29:43 +0200
Subject: [PATCH 20/28] pcm: direct - remove dead code

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/pcm/pcm_direct.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c
index 361805bd..d50503e3 100644
--- a/src/pcm/pcm_direct.c
+++ b/src/pcm/pcm_direct.c
@@ -1857,8 +1857,6 @@ static int _snd_pcm_direct_get_slave_ipc_offset(snd_config_t *root,
 			continue;
 		}
 	}
-	if (card < 0)
-		card = 0;
 	if (device < 0)
 		device = 0;
 	if (subdevice < 0)
-- 
2.30.2


From e2133090603a74c0b08cd45b689063071bc90c81 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Thu, 3 Jun 2021 07:30:27 +0200
Subject: [PATCH 21/28] ucm: fix possible memory leak in parse_verb_file()

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/ucm/parser.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/ucm/parser.c b/src/ucm/parser.c
index ed261fa2..fccf5791 100644
--- a/src/ucm/parser.c
+++ b/src/ucm/parser.c
@@ -1779,7 +1779,7 @@ static int parse_verb_file(snd_use_case_mgr_t *uc_mgr,
 			err = parse_libconfig(uc_mgr, n);
 			if (err < 0) {
 				uc_error("error: failed to parse LibConfig");
-				return err;
+				goto _err;
 			}
 			continue;
 		}
-- 
2.30.2


From 0325f4357d25f262400038f074512e1887c8e5f1 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Thu, 3 Jun 2021 09:00:51 +0200
Subject: [PATCH 22/28] ucm: compound_merge() - fix use after free (and logic)

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/ucm/ucm_include.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/ucm/ucm_include.c b/src/ucm/ucm_include.c
index 6945dd2e..a3a584a1 100644
--- a/src/ucm/ucm_include.c
+++ b/src/ucm/ucm_include.c
@@ -108,7 +108,7 @@ static int find_position_node(snd_config_t **res, snd_config_t *dst,
 	return 0;
 }
 
-static int merge_it(snd_config_t *dst, snd_config_t *n)
+static int merge_it(snd_config_t *dst, snd_config_t *n, snd_config_t **_dn)
 {
 	snd_config_t *dn;
 	const char *id;
@@ -123,6 +123,8 @@ static int merge_it(snd_config_t *dst, snd_config_t *n)
 	err = snd_config_merge(dn, n, 0); /* merge / append mode */
 	if (err < 0)
 		snd_config_delete(n);
+	else
+		*_dn = dn;
 	return err;
 }
 
@@ -198,7 +200,7 @@ static int compound_merge(const char *id,
 		if (_before) {
 			err = snd_config_add_before(_before, n);
 			if (err == -EEXIST)
-				err = merge_it(dst, n);
+				err = merge_it(dst, n, &n);
 			if (err < 0)
 				return err;
 			_before = NULL;
@@ -206,7 +208,7 @@ static int compound_merge(const char *id,
 		} else if (_after) {
 			err = snd_config_add_after(_after, n);
 			if (err == -EEXIST)
-				err = merge_it(dst, n);
+				err = merge_it(dst, n, &n);
 			if (err < 0)
 				return err;
 			_after = n;
-- 
2.30.2


From abe805ed6c7f38e48002e575535afd1f673b9bcd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andreas=20M=C3=BCller?= <schnitzeltony@gmail.com>
Date: Thu, 3 Jun 2021 12:29:03 +0200
Subject: [PATCH 23/28] ucm_exec.c: Include limits.h explicitly to fix build on
 musl
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Fixes:
| ../../../alsa-lib-1.2.5/src/ucm/ucm_exec.c: In function 'find_exec':
| ../../../alsa-lib-1.2.5/src/ucm/ucm_exec.c:43:18: error: 'PATH_MAX' undeclared (first use in this function)
|    43 |         char bin[PATH_MAX];
|       |                  ^~~~~~~~
| ../../../alsa-lib-1.2.5/src/ucm/ucm_exec.c:43:18: note: each undeclared identifier is reported only once for each function it appears in
| ../../../alsa-lib-1.2.5/src/ucm/ucm_exec.c: In function 'uc_mgr_exec':
| ../../../alsa-lib-1.2.5/src/ucm/ucm_exec.c:177:18: error: 'PATH_MAX' undeclared (first use in this function)
|   177 |         char bin[PATH_MAX];
|       |                  ^~~~~~~~

Fixes: https://github.com/alsa-project/alsa-lib/pull/145
Signed-off-by: Andreas Müller <schnitzeltony@gmail.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/ucm/ucm_exec.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/ucm/ucm_exec.c b/src/ucm/ucm_exec.c
index d83206d0..4ddf5d15 100644
--- a/src/ucm/ucm_exec.c
+++ b/src/ucm/ucm_exec.c
@@ -30,6 +30,7 @@
 #include "ucm_local.h"
 #include <sys/stat.h>
 #include <sys/wait.h>
+#include <limits.h>
 #include <dirent.h>
 
 static pthread_mutex_t fork_lock = PTHREAD_MUTEX_INITIALIZER;
-- 
2.30.2


From 01960fa85699686763e42eab537100909e8e6607 Mon Sep 17 00:00:00 2001
From: Chih-Wei Huang <cwhuang@linux.org.tw>
Date: Mon, 14 Jun 2021 12:21:35 +0800
Subject: [PATCH 24/28] ucm: include sys/wait.h to fix build on Android

    src/ucm/main.c:788:8: error: implicit declaration of function 'WIFSIGNALED' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
                        if (WIFSIGNALED(err)) {
                            ^
    src/ucm/main.c:790:10: error: implicit declaration of function 'WIFEXITED' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
                        } if (WIFEXITED(err)) {
                              ^
    src/ucm/main.c:791:34: error: implicit declaration of function 'WEXITSTATUS' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
                                if (ignore_error == false && WEXITSTATUS(err) != 0) {

Signed-off-by: Chih-Wei Huang <cwhuang@linux.org.tw>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/ucm/main.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/ucm/main.c b/src/ucm/main.c
index 42fdaa1d..d4645e4a 100644
--- a/src/ucm/main.c
+++ b/src/ucm/main.c
@@ -37,6 +37,7 @@
 #include <stdarg.h>
 #include <pthread.h>
 #include <sys/stat.h>
+#include <sys/wait.h>
 #include <limits.h>
 
 /*
-- 
2.30.2


From 76d1aa0cd7635f903bb1d48bb9c18279d46ec624 Mon Sep 17 00:00:00 2001
From: Chih-Wei Huang <cwhuang@linux.org.tw>
Date: Mon, 14 Jun 2021 12:24:10 +0800
Subject: [PATCH 25/28] configure: check if eaccess() is available

To fix the build error on Android:
  src/ucm/parser.c:2521:7: error: implicit declaration of function 'eaccess' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
                if (eaccess(filename, R_OK))
                    ^
  src/ucm/parser.c:2521:7: note: did you mean 'access'?

Signed-off-by: Chih-Wei Huang <cwhuang@linux.org.tw>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 configure.ac       | 1 +
 src/ucm/parser.c   | 4 ++++
 src/ucm/ucm_cond.c | 4 ++++
 3 files changed, 9 insertions(+)

diff --git a/configure.ac b/configure.ac
index 60271b8a..635bfeae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -50,6 +50,7 @@ AC_HEADER_TIME
 dnl Checks for library functions.
 AC_PROG_GCC_TRADITIONAL
 AC_CHECK_FUNCS([uselocale])
+AC_CHECK_FUNCS([eaccess])
 
 SAVE_LIBRARY_VERSION
 AC_SUBST(LIBTOOL_VERSION_INFO)
diff --git a/src/ucm/parser.c b/src/ucm/parser.c
index fccf5791..ee997800 100644
--- a/src/ucm/parser.c
+++ b/src/ucm/parser.c
@@ -2518,7 +2518,11 @@ int uc_mgr_scan_master_configs(const char **_list[])
 
 		snprintf(fn, sizeof(fn), "%s.conf", d_name);
 		ucm_filename(filename, sizeof(filename), 2, d_name, fn);
+#ifdef HAVE_EACCESS
 		if (eaccess(filename, R_OK))
+#else
+		if (access(filename, R_OK))
+#endif
 			continue;
 
 		err = uc_mgr_config_load(2, filename, &cfg);
diff --git a/src/ucm/ucm_cond.c b/src/ucm/ucm_cond.c
index 0ed0b690..985a366b 100644
--- a/src/ucm/ucm_cond.c
+++ b/src/ucm/ucm_cond.c
@@ -305,7 +305,11 @@ static int if_eval_path(snd_use_case_mgr_t *uc_mgr, snd_config_t *eval)
 		return -EINVAL;
 	}
 
+#ifdef HAVE_EACCESS
 	if (eaccess(path, amode))
+#else
+	if (access(path, amode))
+#endif
 		return 0;
 
 	return 1;
-- 
2.30.2


From 8253c1c1f9095901c7dbfbb8ca5147d05828651a Mon Sep 17 00:00:00 2001
From: Chih-Wei Huang <cwhuang@linux.org.tw>
Date: Mon, 14 Jun 2021 12:41:11 +0800
Subject: [PATCH 26/28] Fix EXPORT_SYMBOL attribute for clang

Clang doesn't have the externally_visible attribute.

    src/pcm/pcm.c:1503:1: error: unknown attribute 'externally_visible' ignored [-Werror,-Wunknown-attributes]
    #define EXPORT_SYMBOL __attribute__((visibility("default"),externally_visible))                                                         ^

Signed-off-by: Chih-Wei Huang <cwhuang@linux.org.tw>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 include/alsa-symbols.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/include/alsa-symbols.h b/include/alsa-symbols.h
index bba9a9d4..344f021a 100644
--- a/include/alsa-symbols.h
+++ b/include/alsa-symbols.h
@@ -34,7 +34,11 @@
 #define default_symbol_version(real, name, version) \
 	__asm__ (".symver " ASM_NAME(#real) "," ASM_NAME(#name) "@@" #version)
 
+#ifdef __clang__
+#define EXPORT_SYMBOL __attribute__((visibility("default")))
+#else
 #define EXPORT_SYMBOL __attribute__((visibility("default"),externally_visible))
+#endif
 
 #ifdef USE_VERSIONED_SYMBOLS
 #define use_symbol_version(real, name, version) \
-- 
2.30.2


From f4c061f349188c548497607efd4622c6e6a43270 Mon Sep 17 00:00:00 2001
From: Chih-Wei Huang <cwhuang@linux.org.tw>
Date: Mon, 14 Jun 2021 13:08:08 +0800
Subject: [PATCH 27/28] control: remap - fix an infinite recursive call in the
 async callback

The function snd_ctl_remap_async will call itself infinitely. Looks like
a typo.

Fixes: a64391a42 ("control: remap plugin - initial version")
Signed-off-by: Chih-Wei Huang <cwhuang@linux.org.tw>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 src/control/control_remap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/control/control_remap.c b/src/control/control_remap.c
index 17c6558a..a85c1725 100644
--- a/src/control/control_remap.c
+++ b/src/control/control_remap.c
@@ -323,7 +323,7 @@ static int snd_ctl_remap_nonblock(snd_ctl_t *ctl, int nonblock)
 static int snd_ctl_remap_async(snd_ctl_t *ctl, int sig, pid_t pid)
 {
 	snd_ctl_remap_t *priv = ctl->private_data;
-	return snd_ctl_remap_async(priv->child, sig, pid);
+	return snd_ctl_async(priv->child, sig, pid);
 }
 
 static int snd_ctl_remap_subscribe_events(snd_ctl_t *ctl, int subscribe)
-- 
2.30.2