Do a firmware update for your AirPods – now

tldr: There’s a security vulnerability (CVE-2024-27867) in the firmware of Apple AirPods. Anyone who knows the Bluetooth MAC address (which is somewhat public) can connect to your AirPods and listen to the microphone or play music. Even while the AirPods are connected to your phone (although music would stop playing in case somebody turns on the microphone).

Update: Just to clarify, the vulnerability is not present while the AirPods are inside the closed charging case (or Smart Case for the AirPods Max), as then they are in a state where the radio is inactive and no connections at all are possible.

A firmware update is available for AirPods 2, 3, Pro, Pro 2, Max, and some Beats headphones. See here for how to update.

A story of stumbling upon a vulnerability in an Apple product

A few months ago I got a pair of AirPods 3. After some initial amazement at how magically they worked together with my (Apple) phone and (Apple) laptop, I switched back to my everyday world and rebooted the laptop back into Linux. And while the AirPods worked somewhat fine there too, they now refused to connect to both my phone and laptop at the same time.

That got me interested: It just worked when I was using macOS, but it didn’t work with Linux on the exact same laptop. I figured that they’re probably using a bunch of special Apple-specific protocols to get all of these fancy features that other Bluetooth headphones don’t have. So I decided to take a closer look and re-implement a few of them, to see if I could get all the functionality working on Linux as well.

In the process of all this (I’ll talk about the specifics in another blog post), I found a vulnerability in the “Fast Connect” feature that Apple has for connecting Bluetooth peripherals. Fast Connect is a proprietary and US-patented protocol by Apple that creatively uses the “ping” feature of the Bluetooth specification. Its main purpose seems to be reducing the time it takes to establish a connection between two Apple devices from roughly 1 second down to about 0.5 seconds.

The basic way Fast Connect works is that before authenticating with the device you’re connecting to (ie. the AirPods), both devices exchange L2CAP ping messages (think of them like normal pings in networking), and Apple puts protocol messages into the payload of the ping. With this trick, they can establish that both devices are speaking the Fast Connect protocol without violating the Bluetooth specification, and then go on to exchange 3 more back-and-forth messages, negotiating all the things necessary to fully connect the two devices.

The fact that this only takes 4 messages back-and-forth in total is what makes Fast Connect fancy, because usually in Bluetooth the phase of wiring up the individual channels for a connection is quite a complex negotiation and involves sending various SDP descriptors that describe which protocols/features both sides support.

The vulnerability

Turns out that Apple (most likely) forgot to do some checks in the separate code paths that implement Fast Connect. Some very important ones: The AirPods forget to check the security level of the connection, i.e. “did the other side actually authenticate itself and turn on encryption?

Authentication and enabling encryption is a step that is supposed to happen after the initial Fast Connect message. Of course iOS and macOS do that perfectly fine, but if an attacker decides to skip that step when connecting, the AirPods will happily continue on with the Fast Connect. This authentication step is somewhat implicit if you connect the AirPods without Fast Connect (ie. the way all non-Apple Bluetooth devices would connect), and that’s probably the reason why they forgot to add an explicit check for that in the Fast Connect code paths.

So yeah, with this vulnerability, anyone can connect to your AirPods, as long as they know the fixed Bluetooth MAC address of the AirPods. This address is not exactly private information, it’s advertised on the air when your Bluetooth device is in pairing mode, and it can be easily obtained on the air while the AirPods are active using hardware like the Ubertooth One.

Once connected, an attacker can do everything a legitimate device can do, listen to the microphone, play music, see and pause the music that is currently playing from another connected device, or do various things the AAP protocol can do (like changing settings, crashing the AirPods by sending badly formatted messages, and a lot more things I haven’t looked into).

The fix – and the Android problem

Apple has released various firmware updates with fixes for this vulnerability over the past few days, so if you own AirPods, you should make sure the firmware is up to date.

Of course this is all especially problematic for people who use AirPods without iOS or macOS devices (hello Android, Windows, or Linux users). That’s because AirPods auto-update their firmware by themselves, but only when they’re used together with an iPhone or MacBook, so Android users have no easy way to update their firmware. If you’re one of those users, it seems like you can go to an Apple Store and they will update the firmware for you.

Thanks

Finding and reporting all this was quite the journey. I’d like to give a special thanks to Jiska Classen from University of Potsdam for helping with a bunch of Bluetooth questions and tips about the disclosure process.

And of course a big thank you to the whole Linux community! Without awesome tools like BlueZ it wouldn’t have been possible to find any of these issues.

A dive into Jolla AppSupport

You might be aware of Jolla, a Finnish company that emerged after Nokia decided to stop using MeeGo and went with Windows Phone instead. Around 2012 Jolla started out by making their own hardware (these days they no longer do) and they have their own OS based on the MeeGo stack, SailfishOS.

Because the app availability on Sailfish OS is rather slim, Jolla has built excellent middleware to run Android apps on Sailfish OS: AppSupport, known as Aliendalvik internally in Sailfish OS. Conceptually, Aliendalvik is a lot like Waydroid: It runs a modified Android system inside an LXC container, sharing the kernel with the host system. Compared to Waydroid, Aliendalvik has much better integration with the host. It shows Android apps as individual Wayland windows, it forwards notifications and MPRIS from Android, syncs Contacts from the host into Android, uses the native on-screen keyboard, and much much more.

Sailfish OS itself is free software and Jolla appears to be quite proud of this and their connection with the community (they have a forum where developers hang out and even implement ideas from users regularly). However, Aliendalvik is unfortunately proprietary: You only get binaries, no source code, and it’s only shipped as part of the images for their officially supported phones. To try it you first have to get your hands on one of these four Sony Xperia phones and then buy the Sailfish OS image in the Jolla online shop.

That said, once you bought and installed that image, you can play around with Sailfish OS and Aliendalvik. My initial experience was that Sailfish OS works fairly well and feels a lot more mature than what we have with GNOME Shell Mobile or Phosh (that’s not really a surprise given that it’s largely the same stack that was powering the N900, whereas our stack is completely different and a lot more work-in-progress). What blew me away though was how seamless the Aliendalvik integration is: Once you managed to install an Android app store, these Android apps feel almost completely native. If you didn’t know better you couldn’t tell it’s actually a containerized second OS.

Naturally, this sparked my interest in reverse engineering. After all, the Sailfish OS stack is so similar to ours that this thing might run on different distros, too. So I SSHed (yes, you can enable SSH in developer options!) into the phone and started exploring the internals of the OS a bit more in depth.

Diving into the Sailfish OS stack

The Sailfish userspace is mostly based on the same technologies that GNOME and KDE use: glibc, systemd, DBus, RPM and PackageKit, PulseAudio, BlueZ, Wayland, and Qt. They run their own Wayland compositor (lipstick, based on QtCompositor), apps run sandboxed using Firejail, networking is handled by ConnMan, the modem is handled by oFono, and sensors (apparently together with various other things) are handled using MCE, which is probably the furthest away from our stack.

The interesting thing here is that due to the fairly standard userspace Sailfish is using, the Android integration is mostly using standard freedesktop APIs to integrate with the host OS: Running Android apps are exposed as individual Wayland surfaces/windows, notifications from Android appear as org.freedesktop.Notification messages on DBus, music player controls are exposed using MPRIS, and even text input for android apps can be provided using the Wayland text input protocol.

This means that basically Aliendalvik should work just as well on a standard Linux distribution like Fedora, Arch Linux, or Debian. The Android container can be started using standard linux container tooling and the host integration binaries are compiled for ARM64 and mostly link to various open source Qt libraries.

Running it on Arch

So yeah, by now you probably have an idea where this is going: I replaced the underlying OS with Arch Linux ARM, and after a day or two I had bootup logs from the Android container. Another few days of getting all the system services inside Android to start and I had the Android settings app popping up as a Wayland window in GNOME Shell. By then I was pretty much hooked and wanted to get all the host integration working.

With a bunch of DBus API shimming, providing Qt libraries needed by the host-integration and small adjustments in the compositor and libwayland, the whole thing “just works”.

I’ve documented the reverse engineering work on this Github repo, including a very rough step-by-step manual of how to run things. Obviously I can’t share any binaries or other files proprietary to Jolla.

It’s closed source, how is any of this useful?

Well, first of all, reverse engineering is fun, and getting software like Aliendalvik to run on GNOME is a great challenge. From my personal standpoint, this is already enough justification 🙂

The usefulness of this work to the greater community depends on what Jolla will do going forward.

The Linux mobile community is growing, there’s better upstream software and hardware support than ever, and we have amazing communities of talented people; postmarketOS, KDE, GNOME, UBPorts, to name just a few. I’m convinced though that if we want Linux on phones to become an option for everyone, there’s no way around the need for well-integrated support for Android apps.

One option might be for Jolla to officially support running Aliendalvik on other desktop environments than Sailfish OS and offer the Aliendalvik binaries using a third-party repo. Users could then buy the software and get personalized access credentials to this repo, similar to how it works on Sailfish OS (Aliendalvik itself already implements a bunch of Wayland protocols which aren’t used in Lipstick, so it’s probably running under different compositors and trying to be a standard-compliant Wayland client already).

But in my opinion, the real potential for Aliendalvik would be in making it part of the open source community. Availability to the broader Linux community would mean we could work together and help fixing bugs, implement new features, and cooperate on the underlying stack to better meet Aliendalvik’s needs. And while Waydroid as the current FLOSS solution is great already, getting it to the point where Aliendalvik currently is at will take a lot of time and effort. It’s a shame we’ll have to redo that work when there’s a great solution out there already.

What’s next?

I’d like this post to be seen as invitation to both the FLOSS community and to Jolla.

As a community I think we should put more focus on Waydroid, sadly development there has slowed down recently. We need Android app compatibility if we want to get anywhere close to competing with Apple and Google. Every day we leave this problem unsolved is a win for them and a loss for the rest of the world.

On the other hand, I’d like to invite Jolla (or whoever actually owns Aliendalvik) to get in touch with the community about this. The industry is moving towards open source solutions, these days faster than ever. FLOSS software has become the standard in basically all areas. Aliendalvik could profit a lot from making this step, too.

Thanks for reading! If you have any insights or want to help figuring this problem out, please reach out to me at verdre@v0yd.nl.