68 lines
2.1 KiB
Diff
68 lines
2.1 KiB
Diff
|
From bf98b4e3166c28343429119135644ba70c6e5277 Mon Sep 17 00:00:00 2001
|
||
|
From: Takashi Iwai <tiwai@suse.de>
|
||
|
Date: Thu, 30 Apr 2015 12:26:43 +0200
|
||
|
Subject: [PATCH 09/16] namehint: Fix invalid list access in
|
||
|
snd_device_name_hint()
|
||
|
|
||
|
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.4.1
|
||
|
|