From c1ba6da94de22fd21e2cf016f69ee101318a5576 Mon Sep 17 00:00:00 2001 From: George Hilliard Date: Mon, 9 Oct 2023 20:29:02 -0500 Subject: [PATCH] MidiALSA: Fix crash when snd_seq_subscribe_port fails The pthread and lock are never created if the "if" in the constructor fails, and the members are never initialized. But the destructor unconditionally destroys them. Fix this by adding a guard flag. This fixes a segfault I encountered on Arch with Pipewire as the ALSA server. Thread 1 "node" received signal SIGSEGV, Segmentation fault. 0x00007ffff428aebd in pthread_cancel () from /usr/bin/../lib/libc.so.6 (gdb) bt #0 0x00007ffff428aebd in pthread_cancel () from /usr/bin/../lib/libc.so.6 #1 0x00007ffff3b773ff in CMidiInHW::~CMidiInHW (this=0x55555572a430, __in_chrg=) at ../../midi/MidiALSA.cpp:366 #2 0x00007ffff3b77452 in CMidiInHW::~CMidiInHW (this=0x55555572a430, __in_chrg=) at ../../midi/MidiALSA.cpp:369 #3 0x00007ffff3b77105 in CMidiALSA::MidiInOpen[abi:cxx11](wchar_t const*, void*) (this=0x5555557b9880, name=0x5555556b3cf0 L"input", p=0x55555579e3a0) at ../../midi/MidiALSA.cpp:329 #4 0x00007ffff3b6f0c8 in MidiInOpen (env=0x55555579e410, args=0x7fffffff9e20) at ../jazz-midi.cpp:461 #5 0x00007ffff535bd33 in ?? () from /usr/bin/../lib/libnode.so.115 #6 0x00007ffff5840d97 in ?? () from /usr/bin/../lib/libnode.so.115 #7 0x00007ffff5841942 in v8::internal::Builtin_HandleApiCall(int, unsigned long*, v8::internal::Isolate*) () from /usr/bin/../lib/libnode.so.115 #8 0x00007ffff56cadf6 in ?? () from /usr/bin/../lib/libnode.so.115 --- midi/MidiALSA.cpp | 13 ++++++++----- midi/MidiALSA.h | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/midi/MidiALSA.cpp b/midi/MidiALSA.cpp index b858f7f..c14aa35 100644 --- a/midi/MidiALSA.cpp +++ b/midi/MidiALSA.cpp @@ -332,7 +332,7 @@ str_type CMidiALSA::MidiInOpen(const char_type*name, void* p) CMidiInHW::CMidiInHW(snd_seq_t* seq, int client, int port, const char_type* n, void* p) - : m_Seq(seq), m_C(-1), m_P(-1), plugin(p) + : m_Seq(seq), m_C(-1), m_P(-1), plugin(p), have_thread(false) { if (!m_Seq) return; name = n; @@ -349,6 +349,7 @@ CMidiInHW::CMidiInHW(snd_seq_t* seq, int client, int port, const char_type* n, v m_C = client; m_P = port; pthread_mutex_init(&lock, 0); pthread_create(&thread, 0, MidiInThread, this); + have_thread = true; } } @@ -359,10 +360,12 @@ CMidiInHW::~CMidiInHW() snd_seq_unsubscribe_port(m_Seq, m_Sub); snd_seq_port_subscribe_free(m_Sub); snd_seq_delete_port(m_Seq, m_Port); - pthread_mutex_lock(&lock); - pthread_cancel(thread); - pthread_mutex_unlock(&lock); - pthread_mutex_destroy(&lock); + if(have_thread) { + pthread_mutex_lock(&lock); + pthread_cancel(thread); + pthread_mutex_unlock(&lock); + pthread_mutex_destroy(&lock); + } } diff --git a/midi/MidiALSA.h b/midi/MidiALSA.h index 7faa13d..c0076fa 100644 --- a/midi/MidiALSA.h +++ b/midi/MidiALSA.h @@ -80,6 +80,7 @@ friend class CMidiALSA; snd_rawmidi_t* handle; pthread_mutex_t lock; pthread_t thread; + bool have_thread; CMidiInHW(snd_seq_t* seq, int client, int port, const char_type* n, void* p); ~CMidiInHW(); virtual void ReadMidiInput(void*,std::vector&);