Closed Bug 1945967 Opened 1 year ago Closed 6 months ago

Sending a large MIDI message crashes FireFox on MacOS

Categories

(Core :: DOM: Device Interfaces, defect, P2)

Firefox 134
ARM64
macOS
defect

Tracking

()

RESOLVED FIXED
149 Branch
Tracking Status
firefox149 --- fixed

People

(Reporter: mark, Assigned: nish, Mentored)

Details

(Keywords: good-first-bug, Whiteboard: [lang=Rust])

Attachments

(1 file, 1 obsolete file)

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:134.0) Gecko/20100101 Firefox/134.0

Steps to reproduce:

Use WebMIDI to send a MIDI SysEx message greater than 65k bytes. This is not uncommon for things like patch managers for synthesizers.

Actual results:

Sending such a message on Linux works just fine.
Same thing running on Mac OS X crashes the entire browser immediately.

This crash stems from a bug in /dom/midi/midir_impl/src/lib.rs:

WebMIDI is implemented using a Rust crate called midir_impl in the Gecko codebase.
...which is built on the Rust crate midir (https://github.com/Boddlnagg/midir)
...which, for MacOS, is built on the Rust crate coremidi (https://github.com/chris-zen/coremidi)
...which is built on the Rust crate coremidi-sys (https://github.com/jonas-k/coremidi-sys)
...which finall calls CoreMIDI in the Mac OS.

Gecko's midir_impl makes this call to send bytes from WebMIDI:

connection.send(data)

This calls midir's MidiOutputConnection::send() which starts by creating a PacketBuffer:

let packets = PacketBuffer::new(send_time, message);

This uses coremidi's PacketBuffer which is a thin wrapper around coremidi-sys's (and ultimately CoreMIDI's) MIDIPacketList and MIDIPacket.

The bug is that Mac OS's MIDIPacketList can be no bigger than 64k...
...coremidi-sys doesn't check the size of the PacketLists created
...coremidi doesn't check the size of the data passed to MIDIPacketList functions
...midir doesn't check the size of the data it passes to PacketBuffer()
...midir_impl doesn't check the size of the data it passes to send()

... and the result is a corrupted MIDIPacketList that when ulitimately sent to CoreMIDI (via MIDISend) - crashes the process hard.

It is arguable that the API presented by coremidi-sys and coremidi are correct, in that they are thin wrappers around Apple's CoreMIDI.

It is arguable that the API presented by midir should do the work to take large sysex's and break them up and send them in chunks on Mac OS. I have filed a bug on that project to this effect: https://github.com/Boddlnagg/midir/issues/165

Chromium handles this situation properly in it's MacOS backend: It breaks the large
message up into chunks (currently 32k, but that is probably pessamistic) - and sends them one by one. While it would be nice for midir to fix this -- currently it is a hard crash for FireFox - so perhaps FireFox should in the midir_impl crate.

It isn't reasonable to fix this in the WebMIDI code or in applications that send WebMIDI: WebMIDI insistes that sends be complete messages, and so do not accept the SysEx broken up in the segments.

Expected results:

Shouldn't have crashed.

I'm more than happy to provide details, source line references, sample programs that demo the bug, etc.... I'm just not in an environment where I can build FireFox and give a patch.

Component: Untriaged → DOM: Device Interfaces
OS: Unspecified → macOS
Product: Firefox → Core

The severity field is not set for this bug.
:cmartin, could you have a look please?

For more information, please visit BugBot documentation.

Flags: needinfo?(cmartin)

+Gabriele for WebMIDI-related stuff.

Severity: -- → S3
Flags: needinfo?(cmartin)
Priority: -- → P1
Flags: needinfo?(gsvelto)
Status: UNCONFIRMED → NEW
Ever confirmed: true
Flags: needinfo?(gsvelto)
Priority: P1 → P2
Mentor: gsvelto, cmartin
Keywords: good-first-bug
Whiteboard: [lang=Rust]
Hardware: Unspecified → ARM64
Attachment #9491659 - Attachment is obsolete: true

Hello! i would like to try to fix this issue :D
Below are some questions i have:

  1. it looks like from the midi docs, messages this huge (bigger than 65536 bytes) are only possible when a SysEx message is sent. (other all midi messages are 1 to 3 bytes)
  2. do we chunk messages like chrome does at 32k or is exact size fine (im chunking it with u16::MAX as per MIDIPacket length

if all looks well, can i submit a patch? thank you!

Flags: needinfo?(gsvelto)

(In reply to [:nish] Nishchay from comment #5)

  1. it looks like from the midi docs, messages this huge (bigger than 65536 bytes) are only possible when a SysEx message is sent. (other all midi messages are 1 to 3 bytes)

Yes, that's also my understanding.

  1. do we chunk messages like chrome does at 32k or is exact size fine (im chunking it with u16::MAX as per MIDIPacket length

I guess we'll have to test. If u16::MAX works then why not?

if all looks well, can i submit a patch? thank you!

Sure, go ahead, and if you need help jump into the #introduction channel on chat.mozilla.org. You'll find me there.

Flags: needinfo?(gsvelto)
Assignee: nobody → sua8kjwyy
Status: NEW → ASSIGNED
Status: ASSIGNED → RESOLVED
Closed: 6 months ago
Resolution: --- → FIXED
Target Milestone: --- → 149 Branch
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: