]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Fix corruption after snd_device_name_hint()
authorTakashi Iwai <tiwai@suse.de>
Tue, 3 Nov 2009 07:57:10 +0000 (08:57 +0100)
committerTakashi Iwai <tiwai@suse.de>
Tue, 3 Nov 2009 08:02:39 +0000 (09:02 +0100)
snd_device_name_hint() corrupts the config name space after its call.
This results in the error from the suceeding calls of snd_pcm_open()
after snd_device_name_hint().

The bug is in try_config() in namehint.c; it calls snd_config_delete(res)
but res can be two different objects in the function.  One is the object
obtained via snd_config_search_definition(), and another is the one from
snd_config_search_alias_hooks().  The former is the expanded objects,
thus it should be freed.  But, the latter is a reference, and must not be
freed.

This patch adds the check to free or not.

Reported-by: John Lindgren <john.lindgren@tds.net>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
src/control/namehint.c

index e878f830c20ec2a35748c123fa6ca4756e86452b..a134ed7e47349564a4a8c3659be6d7236f87d34e 100644 (file)
@@ -219,6 +219,7 @@ static int try_config(struct hint_list *list,
        const char *str;
        int err = 0, level;
        long dev = list->device;
+       int cleanup_res = 0;
 
        list->device_input = -1;
        list->device_output = -1;
@@ -244,6 +245,7 @@ static int try_config(struct hint_list *list,
        snd_lib_error_set_handler(eh);
        if (err < 0)
                goto __skip_add;
+       cleanup_res = 1;
        err = -EINVAL;
        if (snd_config_get_type(res) != SND_CONFIG_TYPE_COMPOUND)
                goto __cleanup;
@@ -330,6 +332,7 @@ static int try_config(struct hint_list *list,
                goto __hint;
        snd_config_delete(res);
        res = NULL;
+       cleanup_res = 0;
        if (strchr(buf, ':') != NULL)
                goto __ok;
        /* find, if all parameters have a default, */
@@ -379,7 +382,7 @@ static int try_config(struct hint_list *list,
                err = hint_list_add(list, buf, buf1);
        }
       __skip_add:
-       if (res)
+       if (res && cleanup_res)
                snd_config_delete(res);
        if (buf1)
                free(buf1);