M1ssing Register Access Controls Leak EL0 State

M1RACLES (CVE-2021-30747) is a covert channel vulnerability in the Apple Silicon “M1” chip.

Original text by marcan

M1ssing Register Access Controls Leak EL0 State

M1RACLES (CVE-2021-30747) is a covert channel vulnerability in the Apple Silicon “M1” chip.

Executive Summary

A flaw in the design of the Apple Silicon “M1” chip allows any two applications running under an OS to covertly exchange data between them, without using memory, sockets, files, or any other normal operating system features. This works between processes running as different users and under different privilege levels, creating a covert channel for surreptitious data exchange.

The vulnerability is baked into Apple Silicon chips, and cannot be fixed without a new silicon revision.

Demo video

Watch video piped in real time through the covert channel!


Technical Details

The ARM system register encoded as s3_5_c15_c10_1 is accessible from EL0, and contains two implemented bits that can be read or written (bits 0 and 1). This is a per-cluster register that can be simultaneously accessed by all cores in a cluster. This makes it a two-bit covert channel that any arbitrary process can use to exchange data with another cooperating process. A demo app to access this register is available here.

A malicious pair of cooperating processes may build a robust channel out of this two-bit state, by using a clock-and-data protocol (e.g. one side writes 1x to send data, the other side writes 00 to request the next bit). This allows the processes to exchange an arbitrary amount of data, bound only by CPU overhead. CPU core affinity APIs can be used to ensure that both processes are scheduled on the same CPU core cluster. A PoC demonstrating this approach to achieve high-speed, robust data transfer is available here. This approach, without much optimization, can achieve transfer rates of over 1MB/s (less with data redundancy).

The original purpose of this register is unknown, but it is not believed to have been made accessible to EL0 intentionally, thus making this a silicon errata.


Who is affected?

All Apple M1 users, running any operating system on bare metal.

Am I affected?


  • macOS users: At least versions 11.0 and onwards are affected.
  • Linux users: Versions 5.13 and onwards are affected.
  • OpenBSD users: Hi Mark!
  • AmigaOS users: Look, Apple bought PASemi but the AmigaOne X1000 CPU doesn’t count as Apple Silicon, sorry.
  • Newton OS users: I guess those are technically Apple Silicon but…
  • iOS users: See below

Are other Apple CPUs affected?

Maybe, but I don’t have an iPhone or a DTK to test it. Feel free to report back if you try it. The A14 has been confirmed as also affected, which is expected, as it is a close relative of the M1.

Are non-Apple CPUs affected?


Are VMs affected?

No. Correctly implemented hypervisors should disable guest accesses to this register by default, and this feature works correctly on the M1, which mitigates the issue. Both Hypervisor.framework (on macOS) and KVM (on Linux) do this, and are not affected.

How can I protect myself?

The only mitigation available to users is to run your entire OS as a VM.

Does the mitigation have a performance impact?

Yes, running your entire OS as a VM has a performance impact.

That sounds bad.

Well, yeah. Don’t do that, it’d be silly.

Is there really no other way?

Mitigating this under macOS properly would require turning its entire VM hypervisor framework design on its head. We are not aware of any plans by Apple to do so at this time.

It’s a bit easier on Linux, but it still requires fairly intrusive changes due to the design of the M1, and comes at a performance cost for guest VMs. We’re not in a huge rush to do this. Sorry.

How was this bug found?

I was working on figuring out how the M1 CPU works to port Linux to it. Not understanding Apple proprietary features could lead to this sort of vulnerability. I found something, and it turned out to be an Apple proprietary bug, instead of an Apple proprietary feature, that they themselves also weren’t aware of.

How was this bug disclosed?

I e-mailed product-security@apple.com. They acknowledged the vulnerability and assigned it CVE-2021-30747. I published this disclosure 90 days after the initial disclosure to Apple.

Was this responsibly disclosed?

I tried, but I also talked about it on public IRC before I knew it was a bug and not a feature, so I couldn’t do much about that part. ¯\_(ツ)_/¯

Is the vulnerability fixed in future Apple Silicon chips?

We do not have information on Apple’s plans for silicon mitigations. An educated guess based on silicon design timelines would be that the flaw will likely affect the next generation of Apple Silicon after M1, but might be fixed in the subsequent one.

Can malware use this vulnerability to take over my computer?


Can malware use this vulnerability to steal my private information?


Can malware use this vulnerability to rickroll me?

Yes. I mean, it could also rickroll you without using it.

Can this be exploited from Javascript on a website?


Can this be exploited from Java apps?

Wait, people still use Java?

Can this be exploited from Flash applets?

Please stop.

Can I catch BadBIOS from this vulnerability?


Wait, is this even real?

It is.

So what’s the real danger?

If you already have malware on your computer, that malware can communicate with other malware on your computer in an unexpected way.

Chances are it could communicate in plenty of expected ways anyway.

That doesn’t sound too bad.

Honestly, I would expect advertising companies to try to abuse this kind of thing for cross-app tracking, more than criminals. Apple could catch them if they tried, though, for App Store apps (see below).

Wait. Oh no. Some game developer somewhere is going to try to use this as a synchronization primitive, aren’t they. Please don’t. The world has enough cursed code already. Don’t do it. Stop it. Noooooooooooooooo

What about iOS?

iOS is affected, like all other OSes. There are unique privacy implications to this vulnerability on iOS, as it could be used to bypass some of its stricter privacy protections. For example, keyboard apps are not allowed to access the internet, for privacy reasons. A malicious keyboard app could use this vulnerability to send text that the user types to another malicious app, which could then send it to the internet.

However, since iOS apps distributed through the App Store are not allowed to build code at runtime (JIT), Apple can automatically scan them at submission time and reliably detect any attempts to exploit this vulnerability using static analysis (which they already use). We do not have further information on whether Apple is planning to deploy these checks (or whether they have already done so), but they are aware of the potential issue and it would be reasonable to expect they will. It is even possible that the existing automated analysis already rejects any attempts to use system registers directly.

What about APTs?

They have better exploits anyway. They don’t care.

So you’re telling me I shouldn’t worry?


What, really?

Really, nobody’s going to actually find a nefarious use for this flaw in practical circumstances. Besides, there are already a million side channels you can use for cooperative cross-process communication (e.g. cache stuff), on every system. Covert channels can’t leak data from uncooperative apps or systems.

Actually, that one’s worth repeating: Covert channels are completely useless unless your system is already compromised.

So how is this a vulnerability if you can’t exploit it?

It violates the OS security model. You’re not supposed to be able to send data from one process to another secretly. And even if harmless in this case, you’re not supposed to be able to write to random CPU system registers from userspace either.

It was fairly lucky that the bug can be mitigated in VMs (as the register still responds to VM-related access controls); had this not been the case, the impact would have been more severe.

How did this happen anyway?

Someone in Apple’s silicon design team made a boo-boo. It happens. Engineers are human.

But Bloomberg says China hacked TSMC and put this in?!

Good time to buy TSMC stock then!*

* This site is for informational purposes only and is not intended to be a solicitation, offering or recommendation of any security, commodity, derivative, investment management service or advisory service and is not commodity trading advice. This site does not intend to provide investment, tax or legal advice on either a general basis or specific to any client accounts or portfolios. This website does not represent that the securities, products, or services discussed on this site are suitable or appropriate for any or all investors.

Wait, didn’t you say on Twitter that this could be mitigated really easily?

Yeah, but originally I thought the register was per-core. If it were, then you could just wipe it on context switches. But since it’s per-cluster, sadly, we’re kind of screwed, since you can do cross-core communication without going into the kernel. Other than running in EL1/0 with TGE=0 (i.e. inside a VM guest), there’s no known way to block it.

Can’t the OS just write garbage to the register to break apps using it?

No. It would have to do it so fast that it would peg a CPU core continuously, and you’d still get data through even with such noise. Lowering the signal-to-noise ratio almost never works for covert channels, and this case is particularly futile due to its high bandwidth.

Aren’t bugs like this rare and critical?

No, all CPUs have silly errata like this, you just don’t hear about it most of the time. Some vendors even occassionally hide some of these errata and don’t disclose them properly, because it makes them look bad. I hear some of them rhyme with “doorbell”.

But I’ve only heard about Spectre and Meltdown and…?

Because those are the ones that the discoverers chose to hype up. To be fair, those were kind of bad.

So what’s the point of this website?

Poking fun at how ridiculous infosec clickbait vulnerability reporting has become lately. Just because it has a flashy website or it makes the news doesn’t mean you need to care.

If you’ve read all the way to here, congratulations! You’re one of the rare people who doesn’t just retweet based on the page title 🙂

But how are journalists supposed to know which bugs are bad and which bugs aren’t?

Talk to people. In particular, talk to people other than the people who discovered the bug. The latter may or may not be honest about the real impact.

If you hear the words “covert channel”… it’s probably overhyped. Most of these come from paper mills who are endlessly recycling the same concept with approximately zero practical security impact. The titles are usually clickbait, and sometimes downright deceptive.

I came here from a news site and they didn’t tell me any of this at all!

Then perhaps you should stop reading that news site, just like they stopped reading this site after the first 2 paragraphs.

Are all news sites bad?

Nah, a few actually contacted me before running stories and got the facts and did a good job.

If this bug doesn’t matter, why did you go through all the trouble of putting this site and the demo together?

Honestly, I just wanted to play Bad Apple!! over an M1 vulnerability. You have to admit that’s kind of cool.

Can you go into more details about the possible mitigations and why you can’t just fix this in, like, 5 lines of code?

Sure. ARMv8 was originally designed to support Type 1 hypervisors. That’s like Xen for you x86 people: a small hypervisor (EL2) runs both the “host” OS and the “guest” OSes under it (EL1). Later, it was extended to support Type 2 hypervisors (“Virtualization Host Extensions”). That’s like KVM for you x86 people: the hypervisor is the host OS and both run at EL2.

Mitigating the problem requires running your OS at EL1, where the problem register can be disabled, and then having at least some kind of minimal hypervisor at EL2 to deal with those traps (otherwise running an app that uses the register would just crash your machine instead).

The macOS virtualization framework only supports running as a Type 2 hypervisor. So, to fix this, they’d have to re-design the entire thing to work as a Type 1 hypervisor.

Linux supports both modes, where KVM on ARMv8 can run as a little Type 1 hypervisor built into the OS, or as a Type 2 hypervisor like on x86. Running in Type 1 mode (“non-VHE”) would make mitigating the vulnerability possible. However, in their infinite wisdom, Apple decided to only support Type 2 (VHE) mode on Apple Silicon chips, in violation of the ARM architecture specification which requires Type 1 support (non-VHE). So you can’t actually run Linux in Type 1 mode on Apple Silicon. In fact, we had to patch Linux to work around this violation of the spec, because on every other ARM chip, it’ll always start in non-VHE mode and only switch to VHE mode later.

Nothing actually stops you from making a Type 1 hypervisor work in VHE mode (VHE mode adds features required to run as Type 2, but doesn’t remove anything), so it is possible to do Type 1 virtualization on Apple Silicon and work around this. However, because VHE mode changes the way virtualization works, Type 1 hypervisors meant to work in non-VHE mode won’t work in VHE mode without changes. So Linux would need a bunch of rework of its non-VHE Type 1 code to make it possible to use in VHE mode, where it was never intended to work because the ARM specification requires non-VHE mode to always be available.

Basically, Apple decided to break the ARM spec by removing a mandatory feature, because they figured they’d never need to use that feature for macOS. And then it turned out that removing that feature made it much harder for existing OSes to mitigate this vulnerability. Yay.

If you want to play around with this, you should know that setting the Apple-proprietary register bit HACR_EL2[48] to 1 will make accesses to the problem register (and a few others) trap to EL2, but only when running in VHE guest mode (with HCR_EL2.TGE = 0). They won’t trap in EL2/EL0 (VHE host) mode.

Who are you, anyway?


Any closing thoughts?

If you want to help me work on porting and upstreaming Linux for Apple Silicon, I have a Patreon and a GitHub Sponsors. I promise most of the time I’m working on Linux, not writing silly vulnerability PoCs! 🙂

Follow our Linux port progress at asahilinux.org! If you enjoyed the technical part of this PoC, you will probably enjoy our first progress report.

Oh yeah, this vulnerability was found using m1n1. It’s cool, you should check it out! I’m also turning it into a minimal hypervisor to investigate macOS’s usage of the M1 hardware… but thanks to this bug being mitigated by VMs, that will also turn m1n1 into a (somewhat) practical mitigation for this bug, without the overhead of a “full” VM. You lose virtualization features in the guest OS, though, as the M1 does not support nested virtualization.

Kernel RCE caused by buffer overflow in Apple’s ICMP packet-handling code (CVE-2018-4407)

( Original text )

This post is about a heap buffer overflow vulnerability which I found in Apple’s XNU operating system kernel. I have written a proof-of-concept exploit which can reboot any Mac or iOS device on the same network, without any user interaction. Apple have classified this vulnerability as a remote code execution vulnerability in the kernel, because it may be possible to exploit the buffer overflow to execute arbitrary code in the kernel.

The following operating system versions and devices are vulnerable:

  • Apple iOS 11 and earlier: all devices (upgrade to iOS 12)
  • Apple macOS High Sierra, up to and including 10.13.6: all devices (patched in security update 2018-001)
  • Apple macOS Sierra, up to and including 10.12.6: all devices (patched in security update 2018-005)
  • Apple OS X El Capitan and earlier: all devices

I reported the vulnerability in time for Apple to patch the vulnerability for iOS 12 (released on September 17) and macOS Mojave (released on September 24). Both patches were announced retrospectively on October 30.

Severity and Mitigation

The vulnerability is a heap buffer overflow in the networking code in the XNU operating system kernel. XNU is used by both iOS and macOS, which is why iPhones, iPads, and Macbooks are all affected. To trigger the vulnerability, an attacker merely needs to send a malicious IP packet to the IP address of the target device. No user interaction is required. The attacker only needs to be connected to the same network as the target device. For example, if you are using the free WiFi in a coffee shop then an attacker can join the same WiFi network and send a malicious packet to your device. (If an attacker is on the same network as you, it is easy for them to discover your device’s IP address using nmap.) To make matters worse, the vulnerability is in such a fundamental part of the networking code that anti-virus software will not protect you: I tested the vulnerability on a Mac running McAfee® Endpoint Security for Mac and it made no difference. It also doesn’t matter what software you are running on the device — the malicious packet will still trigger the vulnerability even if you don’t have any ports open.

Since an attacker can control the size and content of the heap buffer overflow, it may be possible for them to exploit this vulnerability to gain remote code execution on your device. I have not attempted to write an exploit which is capable of doing this. My exploit PoC just overwrites the heap with garbage, which causes an immediate kernel crash and device reboot.

I am only aware of two mitigations against this vulnerability:

  1. Enabling stealth mode in the macOS firewall prevents the attack from working. Kudos to my colleague Henti Smith for discovering this, because this is an obscure system setting which is not enabled by default. As far as I’m aware, stealth mode does not exist on iOS devices.
  2. Do not use public WiFi networks. The attacker needs to be on the same network as the target device. It is not usually possible to send the malicious packet across the internet. For example, I wrote a fake web server which sends back a malicious reply when the target device tries to load a webpage. In my experiments, the malicious packet never arrived, except when the web server was on the same network as the target device.

Proof-of-concept exploit

I have written a proof-of-concept exploit which triggers the vulnerability. To give Apple’s users time to upgrade, I will not publish the source code for the exploit PoC immediately. However, I have made a short video which shows the PoC in action, crashing all the Apple devices on the local network.

The vulnerability

The bug is a buffer overflow in this line of code (bsd/netinet/ip_icmp.c:339):

m_copydata(n, 0, icmplen, (caddr_t)&icp->icmp_ip);

This code is in the function icmp_error. According to the comment, the purpose of this function is to «Generate an error packet of type error in response to bad packet ip». It uses the ICMP protocol to send out the error message. The header of the packet that caused the error is included in the ICMP message, so the purpose of the call to m_copydata on line 339 is to copy the header of the bad packet into the ICMP message. The problem is that the header might be too big for the destination buffer. The destination buffer is an mbufmbuf is a datatype which is used to store both incoming and outgoing network packets. In this code, n is an incoming packet (containing untrusted data) and m is an outgoing ICMP packet. As we will see shortly, icp is a pointer into mm is allocated on line 294 or line 296:

if (MHLEN > (sizeof(struct ip) + ICMP_MINLEN + icmplen))
  m = m_gethdr(M_DONTWAIT, MT_HEADER);  /* MAC-OK */
  m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);

Slightly further down, on line 314mtod is used to get m‘s data pointer:

icp = mtod(m, struct icmp *);

mtod is just macro, so this line of code does not check that the mbuf is large enough to hold an icmp struct. Furthermore, the data is not copied to icp, but to &icp->icmp_ip, which is at an offset of +8 bytes from icp.

I do not have the necessary tools to be able to step through the XNU kernel in a debugger, so I am actually a little unsure about the exact allocation size of the mbuf. Based on what I see in the source code, I think that m_gethdr creates an mbuf that can hold 88 bytes, but I am less sure about m_getcl. Based on practical experiments, I have found that a buffer overflow is triggered when icmplen >= 84.

At this time, I will not say any more about how the exploit works. I want to give Apple users a chance to upgrade their devices first. However, in the relatively near future I will publish the source code for the exploit PoC in our SecurityExploits repository.

Finding the vulnerability with QL

I found this vulnerability by doing variant analysis on the bug that caused the buffer overflow vulnerability in the packet-mangler. That vulnerability was caused by a call to mbuf_copydata with a user-controlled size argument. So I wrote a simple query to look for similar bugs:

 * @name mbuf copydata with tainted size
 * @description Calling m_copydata with an untrusted size argument
 *              could cause a buffer overflow.
 * @kind path-problem
 * @problem.severity warning
 * @id apple-xnu/cpp/mbuf-copydata-with-tainted-size

import cpp
import semmle.code.cpp.dataflow.TaintTracking
import DataFlow::PathGraph

class Config extends TaintTracking::Configuration {
  Config() { this = "tcphdr_flow" }

  override predicate isSource(DataFlow::Node source) {
    source.asExpr().(FunctionCall).getTarget().getName() = "m_mtod"

  override predicate isSink(DataFlow::Node sink) {
    exists (FunctionCall call
    | call.getArgument(2) = sink.asExpr() and

from Config cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select sink, source, sink, "m_copydata with tainted size."

This is a simple taint-tracking query which looks for dataflow from m_mtod to the size of argument of a «copydata» function. The function named m_mtod returns the data pointer of an mbuf, so it is quite likely that it will return untrusted data. It is what the mtod macro expands to. Obviously m_mtod is just one of many sources of untrusted data in the XNU kernel, but I have not included any other sources to keep the query as simple as possible. This query returns 9 results, the first of which is the vulnerability in icmp_error. I believe the other 8 results are false positives, but the code is sufficiently complicated that I do consider them to be bad query results.

Try QL on XNU

Unlike most other open source projects, XNU is not available to query on LGTM. This is because LGTM uses Linux workers to build projects, but XNU can only be built on a Mac. Even on a Mac, XNU is highly non-trivial to build. I would not have been able to do it if I had not found this incredibly useful blog post by Jeremy Andrus. Using Jeremy Andrus’s instructions and scripts, I have manually built snapshots for the three most recent published versions of XNU. You can download the snapshots from these links: 10.13.410.13.510.13.6. Unfortunately, Apple have not yet released the source code for 10.14 (Mojave / iOS 12), so I cannot create a QL snapshot for running queries against it yet. To run queries on these QL snapshots, you will need to download QL for Eclipse. Instructions on how to use QL for Eclipse can be found here.


  • 2018-08-09: Privately disclosed to product-security@apple.com. Proof-of-concept exploit included.
  • 2018-08-09: Report acknowledged by product-security@apple.com.
  • 2018-08-20: product-security@apple.com asked me to send them the exact macOS version number and a panic log.
  • 2018-08-20: Returned the requested information to product-security@apple.com. Also sent them a slightly improved version of the exploit PoC.
  • 2018-08-22: product-security@apple.com confirmed that the issue is fixed in the betas of macOS Mojave and iOS 12. However, they also said that they are «investigating addressing this issue on additional platforms» and that they will not disclose the issue until November 2018.
  • 2018-09-17: iOS 12 released by Apple. The vulnerability was fixed.
  • 2018-09-24: macOS Mojave released by Apple. The vulnerability was fixed.
  • 2018-10-30: Vulnerabilities disclosed.

"Send it back"


  • «I am Error». Screenshot from Zelda II: The Adventure of Link. The screenshot copyright is believed to belong to Nintendo. Image downloaded from wikipedia.
  • «Send it back». By Edward Backhouse.

Apple T2 security chip on new Macbook prevents software from using the mic to eavesdrop

( Original text by BY  )

Apple MacBook is equipped with a new T2 security chip, which uses a hard-breaking design, can automatically disable the microphone when necessary – such as closing the laptop screen. It is reported that the Apple T2 security chip is bundled with the Secure Enclave security zone coprocessor, which is designed to support MacOS’s Apple File System (APFS) encrypted storage, Touch ID, secure boot and more.

In addition, the chip has a number of controllers that integrate management functions for the system, SSD, audio, and image signal processors. As described in the Apple T2 Chip Security Overview document published in October 2018:

“All Mac portables with the Apple T2 Security Chip feature a hardware disconnect that ensures that the microphone is disabled whenever the lid 
is closed.”

As a result, when the MacBook is closed, even users running with the kernel or root privileges cannot eavesdrop on users. The webcam won’t be disconnected from the hardware when the screen is closed. Apple said: “The camera is not disconnected in hardware because its field of view 
 is completely obstructed with the lid closed.” This hardware-based protection makes it extremely difficult for malicious attackers to eavesdrop.