PAN and XOM: When Security Features Collide
Linux reverts support for XOM
At VDOO, we closely follow Linux kernel commit messages because they sometimes reveal sensitive security issues that may not be published any other way. When severe real-world attacks occur, the vendor, the researchers or the responders involved usually issue Common Vulnerability Enumeration IDs (CVEs) which are formally maintained and easy to track. White-hat researchers usually follow responsible disclosure guidelines, notifying the maintainers and giving them time to fix the issue before it is disclosed to the public. However, many vulnerabilities are fixed without a formal process.
There are cases where the maintainers themselves discover security bugs (for example, by applying security testing tools such as fuzzers). For this reason, some security weaknesses in open-source products can be detected through their commit logs, long before they are published (if they are published at all). Even when the product gets a fix, older versions in the field may remain vulnerable. Since the bad guys know how to exploit that gap, the good guys should also be aware of it. Our research team makes a concentrated effort to track down potential security issues when they show up in commit logs, analyze them, find mitigations where possible, and notify our customers.
For this reason, we were alerted when Linux issued a rollback on January 6th for an ARM security feature, the XOM (Execute Only Mappings), because it interferes with another security feature, the PAN (Privileged Access Never). On January 7th, a blog was published by a researcher named siguza who originally found the issue as early as October 2018, explaining the problem and its consequences. The PAN feature, as defined in the ARM v8.1 specification for 64-bit processors, can be broken by XOM pages, and now Linux has withdrawn its support for XOM until this flaw is fixed.
PAN and XOM
So what are PAN and XOM, and how do they interact?
XOM is a memory protection feature that’s activated at compilation time by marking code sections of the binary execute-only. If the memory bus architecture respects this marking, the application’s code can be fetched and executed by the CPU but cannot be read by user-mode code, including by a debugger. Privileged code can still read XOM memory. As such, XOM could protect against analysis and reverse-engineering by an attacker with local access.
On the other hand, PAN is a CPU and kernel-level mitigation that prevents access from the kernel to user-mode data, unless that’s specifically enabled. PAN protects against some exploit techniques used in local privilege escalations. It is also new and not widespread yet - it only appeared in the ARM v8.1 specification, it does not apply to the ARM Cortex M architecture (so most embedded devices are unaffected), and it currently seems to be found in only a few devices, for example - Apple phones.
Since we're talking about PAN, we will describe an exploitation scenario which it mitigates. This is a privilege escalation scenario, which assumes the attacker already has malicious code somewhere in the system, in user space, just unable to run it with root privileges yet. The attacker now wants the kernel to consume a malicious payload which the attacker has prepared in user-mode. If the attacker can overwrite a system call handler, or another function pointer, somewhere in the kernel, with pointer to their code, and then cause that pointer to get invoked - the kernel will start executing the malicious user-space code with kernel privileges. Game over, the bad guy wins. In another case, if the attacker can get the kernel to read data from user-space and overwrite kernel-space data or code, the attacker can overwrite sensitive kernel data (such as the process permissions structures). Again, game over for the system.
This is what mitigations such as Privileged Access Never (PAN) and its older brother, Privileged Execute Never (PXN), are supposed to protect against. PXN prevents execution of code from user-mode (EL0) pages, while the CPU is in kernel mode (EL1). PAN is supposed to prevent read/write access to user-mode (EL0) pages as data, while the CPU is in kernel mode (EL1). Both work with a specific bit which should be set on the user-mode memory pages - the UXN, User Execute Never. This bit is set by the OS kernel when the virtual page is mapped.
These mitigations are effective in stopping drive-by attacks and can increase the required research effort for a targeted attack. Except there's a catch, and the catch is a hardware bug. As explained in siguza's blog post, the ARM v8.1 specification contains an error where the PAN setting incorrectly ignores the UXN bit when running at a certain exception level, EL1. And that means attackers can continue to use the exploitation technique described above, as long as the relevant page is also marked with XOM. The bug affects any ARM hardware that's already produced based on this specification, and this is what made the Linux kernel developers roll back support for XOM pages, because currently it breaks another, already mature (and possibly more important) security feature.
It will now take some time until ARM can fix the bug, in the next version of their specification. In the meantime, PAN remains effective on non-XOM pages. ARM and ARM64-based devices also support PAN emulation in Linux kernels (starting from versions 4.3/4.10 respectively), via the
CONFIG_ARM64_SW_TTBR0_PAN Kconfig options.
ARM has a good track record in hardware security, not in the least because they perform rigorous formal verification of hardware security features, but formal verification can fail to find a problem if the specification itself is at fault. It would be interesting to see what the official ARM response to the issue will be. Either way, we believe vendors need products like VDOO Vision that can analyze the state of their entire device - from application code through kernel configurations and all the way to hardware security capabilities – in order to identify invalid or insecure configurations, such as when security mitigations are missing or are in a conflicting state.
Share this post