Skip to content

Crash (SIGSEGV) in sound_coreaudio::build_device_list() on macOS with audio devices reporting >66 unlabeled channels (e.g. RME Fireface UFX III) #16195

Description

@ekwipt

MAME version

0.289 (also confirmed present on current master as of 2026-09-18)

System information

MacBook Pro (Apple Silicon, arm64)
macOS 27.0 (build 26A428)
OSD: sdl3

Summary

MAME crashes with EXC_BAD_ACCESS (SIGSEGV, null pointer) on startup whenever any real sound module is selected (-sound coreaudio, -sound sdl, -sound portaudio, or the default auto) — -sound none is the only value that avoids it. The crash happens during device enumeration in src/osd/modules/sound/coreaudio_sound.cpp, build_device_list(), and is triggered by any connected CoreAudio device that reports more than 66 channels with kAudioChannelLabel_Unknown (0xffffffff) descriptions — in my case an RME Fireface UFX III reporting 94 such channels on both input and output.

There are two independent bugs in this function:

Bug 1 — unbounded array index in the "unknown label" fallback path.

if ((chDesc.mChannelLabel == 0xffffffff) || (chDesc.mChannelLabel >= sMacChannelCount))
{
    if (chanLayout->mNumberChannelDescriptions > 1)
    {
        node.m_port_names.push_back(sMacChannelLabels[desc + 1]);
        node.m_port_positions.emplace_back(sChannelPositions[desc + 1]);
    }
    ...

sMacChannelLabels/sChannelPositions are fixed at sMacChannelCount = 67 entries, but desc (the loop index over mNumberChannelDescriptions) is never bounds-checked before being used here. A device with more than 66 channel descriptions (like the 94-channel Fireface) walks straight past the end of both arrays.

Bug 2 — missing comma causes silent string-literal concatenation, leaving a valid in-bounds table entry null.

In the sMacChannelLabels initializer:

"Haptic",
"", "", "",
"Left Top Middle"
"",                             // 50
"Right Top Middle",

There's no comma after "Left Top Middle", so the C++ compiler concatenates it with the following "" into a single string literal, silently consuming one array slot. Because the array has an explicit size ([sMacChannelCount]), this shifts every subsequent label down by one position and leaves the last slot (index 66, intended for "Right Edge of Screen") implicitly zero-initialized — i.e. a null char*. Any code path that ends up indexing sMacChannelLabels[66] (e.g. bug 1's fallback when desc == 65) then constructs a std::string from a null pointer, which crashes in strlen.

Steps to reproduce

Connect any CoreAudio device (real or virtual) that reports ≥67 channel descriptions with unknown/unlabeled channels, then run:

mame -sound coreaudio

(or -sound sdl, -sound portaudio, or no -sound flag at all). Crashes on startup during osd_common_t::init_subsystems().

Patch

--- a/src/osd/modules/sound/coreaudio_sound.cpp
+++ b/src/osd/modules/sound/coreaudio_sound.cpp
@@ -75,7 +75,7 @@
 	"Center Surround Direct",
 	"Haptic",
 	"", "", "",
-	"Left Top Middle"
+	"Left Top Middle",
 	"",                             // 50
 	"Right Top Middle",
 	"Left Top Rear",
@@ -1062,7 +1062,7 @@
 
 						if ((chDesc.mChannelLabel == 0xffffffff) || (chDesc.mChannelLabel >= sMacChannelCount))
 						{
-							if (chanLayout->mNumberChannelDescriptions > 1)
+							if ((chanLayout->mNumberChannelDescriptions > 1) && ((desc + 1) < sMacChannelCount))
 							{
 								node.m_port_names.push_back(sMacChannelLabels[desc + 1]);
 								node.m_port_positions.emplace_back(sChannelPositions[desc + 1]);

Verified fix: built MAME 0.289 locally with this patch applied; -sound coreaudio, -sound sdl, -sound portaudio, and the default all now start cleanly and repeatedly with the same audio hardware attached.

Happy to open this as a pull request instead if that's preferred.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions