From 779d08beeed45b765f3a696f209041d87bd9d5fd Mon Sep 17 00:00:00 2001
From: Lawrence Rust <lvr@softsystem.co.uk>
Date: Thu, 7 Jun 2012 11:52:29 +0200
Subject: [PATCH] libmyth: Prevent an access violation by the ALSA library
In audiooutputalsa.cpp, AudioOutputALSA::GetALSADevices calls the
ALSA API snd_device_name_hint with a card index of -1 to obtain a list
of hints for all cards. Unfortunately, with libasound.so.2.0 this API
can cause an access violation when the card index is -1.
Running with valgrind shows that snd_device_name_hint makes reference
to previously freed memory when the card index is -1.
This patch enumerates the cards using other ALSA APIs, thus avoiding
the SEGV.
Signed-off-by: Lawrence Rust <lvr@softsystem.co.uk>
---
mythtv/libs/libmyth/audio/audiooutputalsa.cpp | 52 +++++++++++++++++--------
1 files changed, 35 insertions(+), 17 deletions(-)
diff --git a/mythtv/libs/libmyth/audio/audiooutputalsa.cpp b/mythtv/libs/libmyth/audio/audiooutputalsa.cpp
index 176252a..5c6c202 100644
a
|
b
|
bool AudioOutputALSA::OpenMixer(void) |
1011 | 1011 | QMap<QString, QString> *AudioOutputALSA::GetDevices(const char *type) |
1012 | 1012 | { |
1013 | 1013 | QMap<QString, QString> *alsadevs = new QMap<QString, QString>(); |
1014 | | void **hints, **n; |
1015 | | char *name, *desc; |
1016 | 1014 | |
1017 | | if (snd_device_name_hint(-1, type, &hints) < 0) |
1018 | | return alsadevs; |
1019 | | n = hints; |
1020 | | |
1021 | | while (*n != NULL) |
| 1015 | // Loop through the sound cards to get Alsa device hints. |
| 1016 | // NB Don't use snd_device_name_hint(-1,..) since there is a potential |
| 1017 | // access violation using this ALSA API with libasound.so.2.0.0. |
| 1018 | // See http://code.google.com/p/chromium/issues/detail?id=95797 |
| 1019 | int card = -1; |
| 1020 | while (!snd_card_next(&card) && card >= 0) |
1022 | 1021 | { |
1023 | | name = snd_device_name_get_hint(*n, "NAME"); |
1024 | | desc = snd_device_name_get_hint(*n, "DESC"); |
1025 | | if (name && desc && strcmp(name, "null")) |
1026 | | alsadevs->insert(name, desc); |
1027 | | if (name) |
1028 | | free(name); |
1029 | | if (desc) |
1030 | | free(desc); |
1031 | | n++; |
| 1022 | void** hints = NULL; |
| 1023 | int error = snd_device_name_hint(card, type, &hints); |
| 1024 | if (error == 0) |
| 1025 | { |
| 1026 | void *hint; |
| 1027 | for (int i = 0; (hint = hints[i]) != NULL; ++i) |
| 1028 | { |
| 1029 | char *name = snd_device_name_get_hint(hint, "NAME"); |
| 1030 | if (name) |
| 1031 | { |
| 1032 | char *desc = snd_device_name_get_hint(hint, "DESC"); |
| 1033 | if (desc) |
| 1034 | { |
| 1035 | if (strcmp(name, "null")) |
| 1036 | alsadevs->insert(name, desc); |
| 1037 | free(desc); |
| 1038 | } |
| 1039 | free(name); |
| 1040 | } |
| 1041 | } |
| 1042 | |
| 1043 | snd_device_name_free_hint(hints); |
| 1044 | } |
| 1045 | else |
| 1046 | { |
| 1047 | VBERROR(QString("Failed to get device hints for card %1, error %2") |
| 1048 | .arg(card).arg(error)); |
| 1049 | } |
1032 | 1050 | } |
1033 | | snd_device_name_free_hint(hints); |
| 1051 | |
1034 | 1052 | // Work around ALSA bug < 1.0.22 ; where snd_device_name_hint can corrupt |
1035 | 1053 | // global ALSA memory context |
1036 | 1054 | #if SND_LIB_MAJOR == 1 |