Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

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: Jean-Yves Avenard <jyavenard@mythtv.org>
  • Loading branch information...
commit c35c00385f781e6736026848d54d75ffa6006219 1 parent 0a5d426
Lawrence Rust authored jyavenard committed
Showing with 35 additions and 17 deletions.
  1. +35 −17 mythtv/libs/libmyth/audio/audiooutputalsa.cpp
View
52 mythtv/libs/libmyth/audio/audiooutputalsa.cpp
@@ -1011,26 +1011,44 @@ bool AudioOutputALSA::OpenMixer(void)
QMap<QString, QString> *AudioOutputALSA::GetDevices(const char *type)
{
QMap<QString, QString> *alsadevs = new QMap<QString, QString>();
- void **hints, **n;
- char *name, *desc;
- if (snd_device_name_hint(-1, type, &hints) < 0)
- return alsadevs;
- n = hints;
-
- while (*n != NULL)
+ // Loop through the sound cards to get Alsa device hints.
+ // NB Don't use snd_device_name_hint(-1,..) since there is a potential
+ // access violation using this ALSA API with libasound.so.2.0.0.
+ // See http://code.google.com/p/chromium/issues/detail?id=95797
+ int card = -1;
+ while (!snd_card_next(&card) && card >= 0)
{
- name = snd_device_name_get_hint(*n, "NAME");
- desc = snd_device_name_get_hint(*n, "DESC");
- if (name && desc && strcmp(name, "null"))
- alsadevs->insert(name, desc);
- if (name)
- free(name);
- if (desc)
- free(desc);
- n++;
+ void** hints = NULL;
+ int error = snd_device_name_hint(card, type, &hints);
+ if (error == 0)
+ {
+ void *hint;
+ for (int i = 0; (hint = hints[i]) != NULL; ++i)
+ {
+ char *name = snd_device_name_get_hint(hint, "NAME");
+ if (name)
+ {
+ char *desc = snd_device_name_get_hint(hint, "DESC");
+ if (desc)
+ {
+ if (strcmp(name, "null"))
+ alsadevs->insert(name, desc);
+ free(desc);
+ }
+ free(name);
+ }
+ }
+
+ snd_device_name_free_hint(hints);
+ }
+ else
+ {
+ VBERROR(QString("Failed to get device hints for card %1, error %2")
+ .arg(card).arg(error));
+ }
}
- snd_device_name_free_hint(hints);
+
// Work around ALSA bug < 1.0.22 ; where snd_device_name_hint can corrupt
// global ALSA memory context
#if SND_LIB_MAJOR == 1
Please sign in to comment.
Something went wrong with that request. Please try again.