Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH lib 0/5] alsa-lib namehint fixes
@ 2015-04-30 13:06 Takashi Iwai
  2015-04-30 13:06 ` [PATCH lib 1/5] namehint: Fix invalid list access in snd_device_name_hint() Takashi Iwai
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Takashi Iwai @ 2015-04-30 13:06 UTC (permalink / raw)
  To: alsa-devel

Hi,

here is a series of fixes for alsa-lib namehint stuff.
Currently snd_device_name_hint() doesn't return proper lists except
for PCM.  Also it may do bogus free() or segfault for wrong
operations.  This patchset addresses such issues and also adds the
missing hint descriptions to ctl, seq, hwdep, etc.


Takashi

===

Takashi Iwai (5):
  namehint: Fix invalid list access in snd_device_name_hint()
  namehint: Fix the listing without device number
  namehint: Fix bad free with invalid iface name
  Allow hint for ctl, hwdep, timer and seq
  conf: Add hint descriptions to ctl, hwdep, seq and timer devices

 include/local.h             |  2 ++
 src/conf/alsa.conf          | 15 ++++++++++++++-
 src/confmisc.c              | 13 +++++++++++++
 src/control/control_hw.c    |  4 +---
 src/control/control_shm.c   |  7 ++-----
 src/control/namehint.c      | 26 ++++++++++++--------------
 src/hwdep/hwdep_hw.c        |  4 +---
 src/pcm/pcm.c               | 12 ------------
 src/pcm/pcm_local.h         |  5 ++---
 src/rawmidi/rawmidi.c       | 18 ------------------
 src/rawmidi/rawmidi_local.h |  2 +-
 src/seq/seq_hw.c            |  4 +---
 src/timer/timer_hw.c        |  4 +---
 src/timer/timer_query_hw.c  |  4 +---
 14 files changed, 51 insertions(+), 69 deletions(-)

-- 
2.3.6

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH lib 1/5] namehint: Fix invalid list access in snd_device_name_hint()
  2015-04-30 13:06 [PATCH lib 0/5] alsa-lib namehint fixes Takashi Iwai
@ 2015-04-30 13:06 ` Takashi Iwai
  2015-04-30 13:06 ` [PATCH lib 2/5] namehint: Fix the listing without device number Takashi Iwai
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Takashi Iwai @ 2015-04-30 13:06 UTC (permalink / raw)
  To: alsa-devel

snd_device_name_hint() tries to free the allocated list at the error
path via snd_device_name_free_hint().  But snd_device_name_free_hint()
expects a list terminated by NULL while snd_device_name_hint() doesn't
add it.  Adding it may again result in an error and thus isn't
guaranteed to work.  Hence we can't add NULL at the error path.

Instead, now the code always allocates one entry more, and zero-clears
the newly allocated beforehand to guarantee the NULL termination.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/control/namehint.c | 21 ++++++++++-----------
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/src/control/namehint.c b/src/control/namehint.c
index 28975a400b75..66de634d3550 100644
--- a/src/control/namehint.c
+++ b/src/control/namehint.c
@@ -52,10 +52,11 @@ static int hint_list_add(struct hint_list *list,
 {
 	char *x;
 
-	if (list->count == list->allocated) {
+	if (list->count + 1 >= list->allocated) {
 		char **n = realloc(list->list, (list->allocated + 10) * sizeof(char *));
 		if (n == NULL)
 			return -ENOMEM;
+		memset(n + list->allocated, 0, 10 * sizeof(*n));
 		list->allocated += 10;
 		list->list = n;
 	}
@@ -620,18 +621,16 @@ int snd_device_name_hint(int card, const char *iface, void ***hints)
 	}
 	err = 0;
       __error:
-      	if (err < 0) {
+	/* add an empty entry if nothing has been added yet; the caller
+	 * expects non-NULL return
+	 */
+	if (!err && !list.list)
+		err = hint_list_add(&list, NULL, NULL);
+	if (err < 0)
       		snd_device_name_free_hint((void **)list.list);
-      		if (list.cardname)
-	      		free(list.cardname);
-      	} else {
-      		err = hint_list_add(&list, NULL, NULL);
-      		if (err < 0)
-      			goto __error;
+	else
       		*hints = (void **)list.list;
-      		if (list.cardname)
-	      		free(list.cardname);
-	}
+	free(list.cardname);
 	if (local_config_rw)
 		snd_config_delete(local_config_rw);
 	if (local_config)
-- 
2.3.6

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH lib 2/5] namehint: Fix the listing without device number
  2015-04-30 13:06 [PATCH lib 0/5] alsa-lib namehint fixes Takashi Iwai
  2015-04-30 13:06 ` [PATCH lib 1/5] namehint: Fix invalid list access in snd_device_name_hint() Takashi Iwai
@ 2015-04-30 13:06 ` Takashi Iwai
  2015-04-30 13:06 ` [PATCH lib 3/5] namehint: Fix bad free with invalid iface name Takashi Iwai
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Takashi Iwai @ 2015-04-30 13:06 UTC (permalink / raw)
  To: alsa-devel

The current code of snd_device_name_hint() has a bug when listing up
devices without the device index (e.g. ctl).  Because it assigns the
default device index 0 unconditionally and it has a check at the later
point to filter entries with dev >= 0, it ended up with empty
outputs.

The fix is simply to remove the bogus assignment of dev = 0.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/control/namehint.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/control/namehint.c b/src/control/namehint.c
index 66de634d3550..6c04143a185c 100644
--- a/src/control/namehint.c
+++ b/src/control/namehint.c
@@ -272,7 +272,6 @@ static int try_config(snd_config_t *config,
 	if (snd_config_search(cfg1, "type", &cfg) >= 0 &&
 	    snd_config_get_string(cfg, &str) >= 0 &&
 	    strcmp(str, "hw") == 0) {
-	    	dev = 0;
 		list->device_input = -1;
 		list->device_output = -1;
 		if (snd_config_search(cfg1, "device", &cfg) >= 0) {
-- 
2.3.6

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH lib 3/5] namehint: Fix bad free with invalid iface name
  2015-04-30 13:06 [PATCH lib 0/5] alsa-lib namehint fixes Takashi Iwai
  2015-04-30 13:06 ` [PATCH lib 1/5] namehint: Fix invalid list access in snd_device_name_hint() Takashi Iwai
  2015-04-30 13:06 ` [PATCH lib 2/5] namehint: Fix the listing without device number Takashi Iwai
@ 2015-04-30 13:06 ` Takashi Iwai
  2015-04-30 13:06 ` [PATCH lib 4/5] Allow hint for ctl, hwdep, timer and seq Takashi Iwai
  2015-04-30 13:06 ` [PATCH lib 5/5] conf: Add hint descriptions to ctl, hwdep, seq and timer devices Takashi Iwai
  4 siblings, 0 replies; 6+ messages in thread
From: Takashi Iwai @ 2015-04-30 13:06 UTC (permalink / raw)
  To: alsa-devel

Due to the uninitialized field before the error path, passing an
invalid iface argument may result in a bad free() call.  Initialize
the fields properly beforehand.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/control/namehint.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/control/namehint.c b/src/control/namehint.c
index 6c04143a185c..b3e646eb10af 100644
--- a/src/control/namehint.c
+++ b/src/control/namehint.c
@@ -562,6 +562,8 @@ int snd_device_name_hint(int card, const char *iface, void ***hints)
 	list.list = NULL;
 	list.count = list.allocated = 0;
 	list.siface = iface;
+	list.show_all = 0;
+	list.cardname = NULL;
 	if (strcmp(iface, "card") == 0)
 		list.iface = SND_CTL_ELEM_IFACE_CARD;
 	else if (strcmp(iface, "pcm") == 0)
@@ -581,8 +583,6 @@ int snd_device_name_hint(int card, const char *iface, void ***hints)
 		goto __error;
 	}
 
-	list.show_all = 0;
-	list.cardname = NULL;
 	if (snd_config_search(local_config, "defaults.namehint.showall", &conf) >= 0)
 		list.show_all = snd_config_get_bool(conf) > 0;
 	if (card >= 0) {
-- 
2.3.6

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH lib 4/5] Allow hint for ctl, hwdep, timer and seq
  2015-04-30 13:06 [PATCH lib 0/5] alsa-lib namehint fixes Takashi Iwai
                   ` (2 preceding siblings ...)
  2015-04-30 13:06 ` [PATCH lib 3/5] namehint: Fix bad free with invalid iface name Takashi Iwai
@ 2015-04-30 13:06 ` Takashi Iwai
  2015-04-30 13:06 ` [PATCH lib 5/5] conf: Add hint descriptions to ctl, hwdep, seq and timer devices Takashi Iwai
  4 siblings, 0 replies; 6+ messages in thread
From: Takashi Iwai @ 2015-04-30 13:06 UTC (permalink / raw)
  To: alsa-devel

Like pcm and rawmidi, each object parser needs to accept the hint
component.  Now a new local function _snd_conf_generic_id() was
introduced to replace each call of "comment" and "type" field checks.

Also, the two existing identical functions for pcm and rawmidi are
removed and the new function is used commonly.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 include/local.h             |  2 ++
 src/confmisc.c              | 13 +++++++++++++
 src/control/control_hw.c    |  4 +---
 src/control/control_shm.c   |  7 ++-----
 src/hwdep/hwdep_hw.c        |  4 +---
 src/pcm/pcm.c               | 12 ------------
 src/pcm/pcm_local.h         |  5 ++---
 src/rawmidi/rawmidi.c       | 18 ------------------
 src/rawmidi/rawmidi_local.h |  2 +-
 src/seq/seq_hw.c            |  4 +---
 src/timer/timer_hw.c        |  4 +---
 src/timer/timer_query_hw.c  |  4 +---
 12 files changed, 25 insertions(+), 54 deletions(-)

diff --git a/include/local.h b/include/local.h
index 2fe9a273f0b0..660081638a1c 100644
--- a/include/local.h
+++ b/include/local.h
@@ -348,4 +348,6 @@ int snd_config_search_alias_hooks(snd_config_t *config,
                                   const char *base, const char *key,
 				  snd_config_t **result);
 
+int _snd_conf_generic_id(const char *id);
+
 #endif
diff --git a/src/confmisc.c b/src/confmisc.c
index af686bea323c..1fb4f282217e 100644
--- a/src/confmisc.c
+++ b/src/confmisc.c
@@ -1302,3 +1302,16 @@ int snd_func_refer(snd_config_t **dst, snd_config_t *root, snd_config_t *src,
 #ifndef DOC_HIDDEN
 SND_DLSYM_BUILD_VERSION(snd_func_refer, SND_CONFIG_DLSYM_VERSION_EVALUATE);
 #endif
+
+#ifndef DOC_HIDDEN
+int _snd_conf_generic_id(const char *id)
+{
+	static const char ids[3][8] = { "comment", "type", "hint" };
+	unsigned int k;
+	for (k = 0; k < sizeof(ids) / sizeof(ids[0]); ++k) {
+		if (strcmp(id, ids[k]) == 0)
+			return 1;
+	}
+	return 0;
+}
+#endif
diff --git a/src/control/control_hw.c b/src/control/control_hw.c
index dfc9dcd51e20..7d23151c7d75 100644
--- a/src/control/control_hw.c
+++ b/src/control/control_hw.c
@@ -446,9 +446,7 @@ int _snd_ctl_hw_open(snd_ctl_t **handlep, char *name, snd_config_t *root ATTRIBU
 		const char *id;
 		if (snd_config_get_id(n, &id) < 0)
 			continue;
-		if (strcmp(id, "comment") == 0)
-			continue;
-		if (strcmp(id, "type") == 0)
+		if (_snd_conf_generic_id(id))
 			continue;
 		if (strcmp(id, "card") == 0) {
 			err = snd_config_get_integer(n, &card);
diff --git a/src/control/control_shm.c b/src/control/control_shm.c
index 40bc705d8036..bd07d4af503a 100644
--- a/src/control/control_shm.c
+++ b/src/control/control_shm.c
@@ -551,10 +551,7 @@ int _snd_ctl_shm_open(snd_ctl_t **handlep, char *name, snd_config_t *root, snd_c
 		const char *id;
 		if (snd_config_get_id(n, &id) < 0)
 			continue;
-		if (strcmp(id, "comment") == 0)
-			continue;
-		if (strcmp(id, "type") == 0)
-			continue;
+		if (_snd_conf_generic_id(id))
 		if (strcmp(id, "server") == 0) {
 			err = snd_config_get_string(n, &server);
 			if (err < 0) {
@@ -597,7 +594,7 @@ int _snd_ctl_shm_open(snd_ctl_t **handlep, char *name, snd_config_t *root, snd_c
 		const char *id;
 		if (snd_config_get_id(n, &id) < 0)
 			continue;
-		if (strcmp(id, "comment") == 0)
+		if (_snd_conf_generic_id(id))
 			continue;
 		if (strcmp(id, "host") == 0)
 			continue;
diff --git a/src/hwdep/hwdep_hw.c b/src/hwdep/hwdep_hw.c
index 4314e32bade6..12528c55bac7 100644
--- a/src/hwdep/hwdep_hw.c
+++ b/src/hwdep/hwdep_hw.c
@@ -158,9 +158,7 @@ int _snd_hwdep_hw_open(snd_hwdep_t **hwdep, char *name,
 		const char *id;
 		if (snd_config_get_id(n, &id) < 0)
 			continue;
-		if (strcmp(id, "comment") == 0)
-			continue;
-		if (strcmp(id, "type") == 0)
+		if (_snd_conf_generic_id(id))
 			continue;
 		if (strcmp(id, "card") == 0) {
 			err = snd_config_get_integer(n, &card);
diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
index e74e02fc568f..bc18954b92da 100644
--- a/src/pcm/pcm.c
+++ b/src/pcm/pcm.c
@@ -7059,18 +7059,6 @@ int snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf,
 	return err;
 }
 		
-
-int snd_pcm_conf_generic_id(const char *id)
-{
-	static const char ids[3][8] = { "comment", "type", "hint" };
-	unsigned int k;
-	for (k = 0; k < sizeof(ids) / sizeof(ids[0]); ++k) {
-		if (strcmp(id, ids[k]) == 0)
-			return 1;
-	}
-	return 0;
-}
-
 static void snd_pcm_set_ptr(snd_pcm_t *pcm, snd_pcm_rbptr_t *rbptr,
 			    volatile snd_pcm_uframes_t *hw_ptr, int fd, off_t offset)
 {
diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h
index 394505f978ac..326618ecd0c0 100644
--- a/src/pcm/pcm_local.h
+++ b/src/pcm/pcm_local.h
@@ -262,8 +262,6 @@ struct _snd_pcm {
 	snd1_pcm_areas_from_bufs
 #define snd_pcm_open_named_slave \
 	snd1_pcm_open_named_slave
-#define snd_pcm_conf_generic_id \
-	snd1_pcm_conf_generic_id
 #define snd_pcm_hw_open_fd \
 	snd1_pcm_hw_open_fd
 #define snd_pcm_wait_nocheck \
@@ -882,7 +880,8 @@ snd_pcm_open_slave(snd_pcm_t **pcmp, snd_config_t *root,
 	return snd_pcm_open_named_slave(pcmp, NULL, root, conf, stream,
 					mode, parent_conf);
 }
-int snd_pcm_conf_generic_id(const char *id);
+
+#define snd_pcm_conf_generic_id(id) _snd_conf_generic_id(id)
 
 int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name, int fd, int mmap_emulation, int sync_ptr_ioctl);
 int __snd_pcm_mmap_emul_open(snd_pcm_t **pcmp, const char *name,
diff --git a/src/rawmidi/rawmidi.c b/src/rawmidi/rawmidi.c
index ac699b439b11..0c89b8b984b9 100644
--- a/src/rawmidi/rawmidi.c
+++ b/src/rawmidi/rawmidi.c
@@ -990,21 +990,3 @@ ssize_t snd_rawmidi_read(snd_rawmidi_t *rawmidi, void *buffer, size_t size)
 	assert(buffer || size == 0);
 	return (rawmidi->ops->read)(rawmidi, buffer, size);
 }
-
-#ifndef DOC_HIDDEN
-int snd_rawmidi_conf_generic_id(const char *id)
-{
-	static const char ids[][8] = {
-		"comment",
-		"type",
-		"hint",
-	};
-	unsigned int k;
-
-	for (k = 0; k < sizeof ids / sizeof *ids; ++k) {
-		if (strcmp(id, ids[k]) == 0)
-			return 1;
-	}
-	return 0;
-}
-#endif
diff --git a/src/rawmidi/rawmidi_local.h b/src/rawmidi/rawmidi_local.h
index 3388502cece0..8992771eb5d3 100644
--- a/src/rawmidi/rawmidi_local.h
+++ b/src/rawmidi/rawmidi_local.h
@@ -58,4 +58,4 @@ int snd_rawmidi_virtual_open(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp,
 			     const char *name, snd_seq_t *seq_handle, int port,
 			     int merge, int mode);
 
-int snd_rawmidi_conf_generic_id(const char *id);
+#define snd_rawmidi_conf_generic_id(id)	_snd_conf_generic_id(id)
diff --git a/src/seq/seq_hw.c b/src/seq/seq_hw.c
index 6cb31d6f4c25..d03336738944 100644
--- a/src/seq/seq_hw.c
+++ b/src/seq/seq_hw.c
@@ -546,9 +546,7 @@ int _snd_seq_hw_open(snd_seq_t **handlep, char *name,
 		const char *id;
 		if (snd_config_get_id(n, &id) < 0)
 			continue;
-		if (strcmp(id, "comment") == 0)
-			continue;
-		if (strcmp(id, "type") == 0)
+		if (_snd_conf_generic_id(id))
 			continue;
 		return -EINVAL;
 	}
diff --git a/src/timer/timer_hw.c b/src/timer/timer_hw.c
index aa6a0b1b42f1..e833fc8cbb41 100644
--- a/src/timer/timer_hw.c
+++ b/src/timer/timer_hw.c
@@ -299,9 +299,7 @@ int _snd_timer_hw_open(snd_timer_t **timer, char *name,
 		const char *id;
 		if (snd_config_get_id(n, &id) < 0)
 			continue;
-		if (strcmp(id, "comment") == 0)
-			continue;
-		if (strcmp(id, "type") == 0)
+		if (_snd_conf_generic_id(id))
 			continue;
 		if (strcmp(id, "class") == 0) {
 			err = snd_config_get_integer(n, &dev_class);
diff --git a/src/timer/timer_query_hw.c b/src/timer/timer_query_hw.c
index 9f62b78aeb2e..289ca52f2afa 100644
--- a/src/timer/timer_query_hw.c
+++ b/src/timer/timer_query_hw.c
@@ -134,9 +134,7 @@ int _snd_timer_query_hw_open(snd_timer_query_t **timer, char *name,
 		const char *id;
 		if (snd_config_get_id(n, &id) < 0)
 			continue;
-		if (strcmp(id, "comment") == 0)
-			continue;
-		if (strcmp(id, "type") == 0)
+		if (_snd_conf_generic_id(id))
 			continue;
 		SNDERR("Unexpected field %s", id);
 		return -EINVAL;
-- 
2.3.6

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH lib 5/5] conf: Add hint descriptions to ctl, hwdep, seq and timer devices
  2015-04-30 13:06 [PATCH lib 0/5] alsa-lib namehint fixes Takashi Iwai
                   ` (3 preceding siblings ...)
  2015-04-30 13:06 ` [PATCH lib 4/5] Allow hint for ctl, hwdep, timer and seq Takashi Iwai
@ 2015-04-30 13:06 ` Takashi Iwai
  4 siblings, 0 replies; 6+ messages in thread
From: Takashi Iwai @ 2015-04-30 13:06 UTC (permalink / raw)
  To: alsa-devel

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/conf/alsa.conf | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/src/conf/alsa.conf b/src/conf/alsa.conf
index 5c928e8afbcd..f22918fbbf83 100644
--- a/src/conf/alsa.conf
+++ b/src/conf/alsa.conf
@@ -345,6 +345,7 @@ ctl.sysdefault {
 			name defaults.ctl.card
 		}
 	}
+	hint.description "Default control device"
 }
 ctl.default ctl.sysdefault
 
@@ -366,6 +367,7 @@ ctl.hw {
 	}
 	type hw
 	card $CARD
+	hint.description "Direct control device"
 }
 
 ctl.shm {
@@ -408,6 +410,7 @@ rawmidi.default {
 			name defaults.rawmidi.device
 		}
 	}
+	hint.description "Default raw MIDI device"
 }
 
 rawmidi.hw {
@@ -469,6 +472,7 @@ rawmidi.virtual {
 
 seq.default {
 	type hw
+	hint.description "Default sequencer device"
 }
 
 seq.hw {
@@ -502,6 +506,7 @@ hwdep.default {
 			name defaults.hwdep.device
 		}
 	}
+	hint.description "Default hardware dependent device"
 }
 
 hwdep.hw {
@@ -536,6 +541,10 @@ hwdep.hw {
 	type hw
 	card $CARD
 	device $DEV
+	hint {
+		description "Direct hardware dependent device"
+		device $DEV
+	}
 }
 
 #
@@ -572,7 +581,7 @@ timer.default {
 		@func refer
 		name defaults.timer.subdevice
 	}
-	hint.description "Default direct hardware timer device"
+	hint.description "Default timer device"
 }
 
 timer.hw {
@@ -618,4 +627,8 @@ timer.hw {
 	card $CARD
 	device $DEV
 	subdevice $SUBDEV
+	hint {
+		description "Direct timer device"
+		device $DEV
+	}
 }
-- 
2.3.6

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2015-04-30 13:06 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-04-30 13:06 [PATCH lib 0/5] alsa-lib namehint fixes Takashi Iwai
2015-04-30 13:06 ` [PATCH lib 1/5] namehint: Fix invalid list access in snd_device_name_hint() Takashi Iwai
2015-04-30 13:06 ` [PATCH lib 2/5] namehint: Fix the listing without device number Takashi Iwai
2015-04-30 13:06 ` [PATCH lib 3/5] namehint: Fix bad free with invalid iface name Takashi Iwai
2015-04-30 13:06 ` [PATCH lib 4/5] Allow hint for ctl, hwdep, timer and seq Takashi Iwai
2015-04-30 13:06 ` [PATCH lib 5/5] conf: Add hint descriptions to ctl, hwdep, seq and timer devices Takashi Iwai

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox