Index | Thread | Search

From:
Rafael Sadowski <rafael@sizeofvoid.org>
Subject:
Re: audio/lmms: Fix memory corruption during MIDI input/output
To:
Alexandre Ratchov <alex@caoua.org>
Cc:
izzy Meyer <izder456@disroot.org>, ports@openbsd.org
Date:
Mon, 25 May 2026 15:38:35 +0200

Download raw body.

Thread
On Mon May 25, 2026 at 02:46:39PM +0200, Alexandre Ratchov wrote:
> On Fri, Apr 25, 2025 at 05:32:33PM -0500, izzy Meyer wrote:
> > On Thu, 24 Apr 2025 15:33:18 +0200
> > Alexandre Ratchov <alex@caoua.org> wrote:
> > 
> > > MIDI output and input are handled on different threads, so a mutex is
> > > required to serialize access to the mio_hdl structure.
> > > 
> > > This diff fixes disconnection from sndiod caused by corruption of the
> > > mio_hdl structure.
> > > 
> > > While we're at it, fix the input event loop to not stop if a signal is
> > > received during poll(4). If so just recheck the m_quit flag and retry.
> > > 
> > > OK?
> > > 
> > 
> > Thanks for this fix Alexandre. I produce on OpenBSD using LMMS. Tested
> > on amd64. Seems good from some minimal testing on my production
> > machine.
> > 
> 
> I don't remember why, but this diff was forgotten. Here's a refreshed
> version, with better error handling.
> 
> OK?

Reads fine, ok rsadowski

> 
> Index: Makefile
> ===================================================================
> RCS file: /cvs/ports/audio/lmms/Makefile,v
> diff -u -p -u -p -r1.29 Makefile
> --- Makefile	13 Feb 2026 12:02:13 -0000	1.29
> +++ Makefile	25 May 2026 12:34:20 -0000
> @@ -5,7 +5,7 @@ DISTNAME =		lmms_$V
>  PKGNAME =		lmms-$V
>  WRKDIST =		${WRKDIR}/lmms
>  EXTRACT_SUFX =		.tar.xz
> -REVISION =		1
> +REVISION =		2
>  
>  CATEGORIES =		audio
>  
> Index: patches/patch-include_MidiSndio_h
> ===================================================================
> RCS file: patches/patch-include_MidiSndio_h
> diff -N patches/patch-include_MidiSndio_h
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ patches/patch-include_MidiSndio_h	25 May 2026 12:34:20 -0000
> @@ -0,0 +1,19 @@
> +Index: include/MidiSndio.h
> +--- include/MidiSndio.h.orig
> ++++ include/MidiSndio.h
> +@@ -32,6 +32,7 @@
> + 
> + #include <QtCore/QThread>
> + #include <QtCore/QFile>
> ++#include <QtCore/QMutex>
> + 
> + #include <sndio.h>
> + 
> +@@ -64,6 +65,7 @@ class MidiSndio : public MidiClientRaw, public QThread
> + 	virtual void run(void);
> + 
> + private:
> ++	QMutex m_hdlMutex;
> + 	struct mio_hdl *m_hdl;
> + 	volatile bool m_quit;
> + } ;
> Index: patches/patch-src_core_midi_MidiSndio_cpp
> ===================================================================
> RCS file: patches/patch-src_core_midi_MidiSndio_cpp
> diff -N patches/patch-src_core_midi_MidiSndio_cpp
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ patches/patch-src_core_midi_MidiSndio_cpp	25 May 2026 12:34:20 -0000
> @@ -0,0 +1,61 @@
> +␘Index: src/core/midi/MidiSndio.cpp
> +--- src/core/midi/MidiSndio.cpp.orig
> ++++ src/core/midi/MidiSndio.cpp
> +@@ -42,6 +42,7 @@
> + 
> + MidiSndio::MidiSndio( void ) :
> + 	MidiClientRaw(),
> ++	m_hdlMutex(),
> + 	m_quit( false )
> + {
> + 	QString dev = probeDevice();
> +@@ -86,7 +87,9 @@ QString MidiSndio::probeDevice( void )
> + 
> + void MidiSndio::sendByte( const unsigned char c )
> + {
> ++	m_hdlMutex.lock();
> + 	mio_write( m_hdl, &c, 1 );
> ++	m_hdlMutex.unlock();
> + }
> + 
> + 
> +@@ -96,20 +99,33 @@ void MidiSndio::run( void )
> + 	nfds_t nfds;
> + 	char buf[0x100], *p;
> + 	size_t n;
> ++	int revents;
> + 	int ret;
> ++
> + 	while( m_quit == false && m_hdl )
> + 	{
> ++		m_hdlMutex.lock();
> + 		nfds = mio_pollfd( m_hdl, &pfd, POLLIN );
> ++		m_hdlMutex.unlock();
> + 		ret = poll( &pfd, nfds, 100 );
> +-		if ( ret < 0 )
> ++		if ( ret < 0 ) {
> ++			if (errno == EINTR)
> ++				continue;
> ++			fprintf(stderr, "sndio: poll: %s\n", strerror(errno));
> + 			break;
> +-		if ( !ret || !( mio_revents( m_hdl, &pfd ) & POLLIN ) )
> +-			continue;
> +-		n = mio_read( m_hdl, buf, sizeof(buf) );
> +-		if ( !n )
> +-		{
> ++		}
> ++		m_hdlMutex.lock();
> ++		revents = mio_revents( m_hdl, &pfd );
> ++		if (revents & POLLHUP) {
> ++			fprintf(stderr, "sndio: device disconnected\n");
> ++			m_hdlMutex.unlock();
> + 			break;
> + 		}
> ++		if (revents & POLLIN) {
> ++			n = mio_read( m_hdl, buf, sizeof(buf) );
> ++		} else
> ++			n = 0;
> ++		m_hdlMutex.unlock();
> + 		for (p = buf; n > 0; n--, p++)
> + 		{
> + 			parseData( *p );
>