From 33960b5dc7b4d44c1b5702c68777114b0ef878f3 Mon Sep 17 00:00:00 2001
From: Lawrence Rust <lvr@softsystem.co.uk>
Date: Wed, 6 Jun 2012 18:49:43 +0200
Subject: [PATCH] libmyth: Prevent an access violation by the ALSA library
In audiooutputalsa.cpp, AudioOutputALSA::GetDevices 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.
See http://code.google.com/p/chromium/issues/detail?id=95797
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 | 48 ++++++++++++++++---------
1 files changed, 31 insertions(+), 17 deletions(-)
diff --git a/mythtv/libs/libmyth/audio/audiooutputalsa.cpp b/mythtv/libs/libmyth/audio/audiooutputalsa.cpp
index 176252a..9739529 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 | char *name = snd_device_name_get_hint(*hints, "NAME"); |
| 1027 | if (name) |
| 1028 | { |
| 1029 | char *desc = snd_device_name_get_hint(*hints, "DESC"); |
| 1030 | if (desc) |
| 1031 | { |
| 1032 | if (strcmp(name, "null")) |
| 1033 | alsadevs->insert(name, desc); |
| 1034 | free(desc); |
| 1035 | } |
| 1036 | free(name); |
| 1037 | } |
| 1038 | |
| 1039 | snd_device_name_free_hint(hints); |
| 1040 | } |
| 1041 | else |
| 1042 | { |
| 1043 | VBERROR(QString("Failed to get device hints for card %1, error %2") |
| 1044 | .arg(card).arg(error)); |
| 1045 | } |
1032 | 1046 | } |
1033 | | snd_device_name_free_hint(hints); |
| 1047 | |
1034 | 1048 | // Work around ALSA bug < 1.0.22 ; where snd_device_name_hint can corrupt |
1035 | 1049 | // global ALSA memory context |
1036 | 1050 | #if SND_LIB_MAJOR == 1 |