The security of the kernel is essential to the security of the whole system. An attack that compromises the kernel has the ability to arbitrarily access system sensitive data, hide malicious activities, escalate the privilege of malicious user processes, change the system behavior or simply take control of the system. As mentioned previously, Trusted Boot measurements can be used to determine what kernel was loaded and run when the device was started. However, this protection does not guarantee the integrity of the kernel after the system runs and starts to interact with potential attackers. Clever attackers can sometimes exploit an already booted and running kernel. In such cases, it is important to continuously monitor the kernel during the system runtime in order to detect and prevent modifications to the kernel code or critical data structures.
Intuitively, the kernel protection mechanism cannot itself exist completely in the kernel, or it could be circumvented by an attacker. Therefore, Samsung Knox introduces Real-time Kernel Protection (RKP), a unique solution that provides the required protection using a security monitor located within an isolated execution environment. Depending on the device model, this isolated execution environment is either the Secure World of ARM TrustZone or a thin hypervisor that is protected by the hardware virtualization extensions. RKP’s Trusted Computing Base (TCB) is part of this isolated environment and thus is secure from attacks that may potentially compromise the kernel.
Running in an isolated execution environment may cripple the ability of the security protection mechanisms to closely monitor events that happen inside the target kernel. To solve this problem, RKP uses special techniques to take full control over the Normal World memory management and intercept critical events and inspect their impact on security before allowing them to be executed. Hence, RKP complements TIMA-PKM’s periodic kernel integrity checking, which has limited effectiveness against attacks that can take place and properly hide their traces between periodic checks.
RKP achieves three important security features:
- First, it completely prevents running unauthorized privileged code (i.e., code that has the kernel privilege) on the system, which is accomplished by preventing modification of the kernel code, injection of unauthorized code into the kernel, or execution of the user space code in the privileged mode.
- Second, it prevents kernel data from being directly accessed by user processes. This includes preventing double mapping of physical memory that contains critical kernel data into user space virtual memory. This is an important step to prevent kernel exploits that attempt to map kernel data regions into malicious processes where they could be modified by an attacker.
- Third, RKP monitors some critical kernel data structures to verify that they are not exploited by attacks. In particular, RKP protects the data that defines the credentials assigned to running user processes to prevent attackers from escalating this credential by modifying this data.
NOTE: The first feature is present on all models, while the second and third features are available on select models. Additional protection features are under development.
Figure 5 shows the architecture of RKP, which is hosted in an isolated execution environment that is protected even if Android’s Linux kernel is compromised. The kernel is forced to request RKP to perform two operations on its behalf: (1) emulating control instructions that change the system state and (2) updating the Normal World memory translation tables. This monitoring is enforced by depriving the kernel of its ability to control these critical functions.
System control instructions allow the Normal World to control security critical system state, such as defining the location of memory translation tables and exception handlers. These instructions can be only executed by privileged code, such as the kernel code. RKP instruments the kernel so that certain system control instructions are removed from its executable memory, which is the only memory that can execute privileged instructions in the Normal World. Therefore, the only way to execute these instructions is through emulating them from the Secure World. We call this operation Control Instruction Emulation. On models that use the virtualization extensions, intercepting system control instructions can also be done using the hardware virtualization extensions.
Memory translation tables (also called page tables), define the virtual to physical address mapping and the access permissions of virtual memory. If the kernel attempts to change the current memory layout of the system through modifying translation tables, then RKP inspects these changes to confirm that they do not impact the system security. RKP ensures that translation tables cannot be modified by the Normal World through making them read-only to the Normal World kernel. Hence, the only way for the kernel to update the translation tables is to request these updates from RKP. As a result, RKP guarantees that this interception is non-bypassable.
RKP Architecture (On select models, RKP runs in the virtualization protected environment rather than TrustZone Secure World)
Kernel code protection
Kernel code protection is the main security feature that RKP provides. The main guarantee is that an attacker that can get past the Linux kernel defenses would not be allowed to modify the kernel executable code, which greatly reduces the impact of kernel attacks on the whole system. To achieve this objective, RKP examines memory translation table modifications to enforce a set of rules that guarantee that the kernel is not writable by any code in the Normal World. These rules also guarantee that the RKP monitoring cannot be bypassed even if an attacker finds a way to break the Normal World kernel protections. Thus, the kernel is not able to modify its own code, even if it is compromised.
The rules are:
- Kernel code pages are never mapped writable
- Kernel data pages are never mapped executable
- All memory translation tables are mapped read-only to the Normal World
- No double mappings of kernel code or any memory translation tables is allowed (Double mapping happens when the same physical memory is mapped to multiple virtual memory addresses, which might allow two different parts of the system to access the same memory with different permissions)
- All mapped memory regions should have the Privileged eXecute Never (PXN) permission, with the exception of the OS kernel
The first two rules guarantee that the initial image of the kernel, as measured by Trusted Boot, cannot be directly modified by any potential attacker, unless it changes the memory mapping of the system by modifying the memory translation tables. This feature is still true even if the attacker takes control of the kernel itself. The rest of the rules guarantee that the memory translation tables themselves cannot be modified by the kernel, unless it sends a request to RKP. When such a request is sent, RKP verifies that the memory translation table modification does not violate the above rules. Combining these two sets of rules together, the kernel is not modified without RKP’s knowledge.
These protections still require a basic assumption that the system memory management state has not been modified. Modifying the memory management system state (e.g., through changing the effective memory translation tables’ base address or disabling the virtual memory protection completely) may allow an attacker to bypass the RKP monitoring. Thus, RKP uses the Control Instruction Emulation feature explained above to inspect these events to guarantee that they do not tamper with its monitoring.
In models that use the virtualization extensions, system control instructions are forced to trap into RKP through hardware controls. In models that use the TrustZone-based solution, this feature is complicated by the fact that TrustZone is not capable of trapping changes to the Normal World state. Hence, RKP instruments the kernel to remove all instances of these system control instructions. Since these instructions can only run from privileged code, and RKP grants that privilege exclusively to the measured and protected kernel code, then it is absolutely impossible for the Normal World to run these instructions without trapping to RKP. In turn, RKP validates the values to be written to the system control instructions to guarantee that they do not invalidate its kernel code protection assumptions.
Preventing double mapping of kernel data
Kernel data structures are critical to the security of the system. Maliciously modifying kernel data can lead to wide range of damage from privilege escalation to user process hiding. Since RKP completely protects the kernel code base and prevents return-to-user attacks using the PXN protection of user pages, there are only two possible methods to exploit kernel data. The first is through double mapping the memory hosting kernel data into the address space of the malicious process. The second is to alter the kernel control flow so that it maliciously modifies its own data (such as using pointer manipulation or pointer overflow).The first class of attacks, double mapping of kernel data to malicious user processes, is a real threat to the kernel. For instance, a real-world Android exploit used an integer overflow to trick the kernel into mapping a huge range of the physical memory into the address space of the attacking process.
To prevent malicious double mapping of the kernel data, RKP ensures that physical memory pages hosting this data are not mapped to user space processes. They can only be mapped as privileged pages that cannot be accessed by the user space. RKP enforces this rule using its control of the Normal World memory translation. RKP rejects any page table modification that maps kernel data to user space. To handle a related problem, RKP makes sure that no executable kernel pages are ever double-mapped to be writeable, and vice versa.
RKP relies on the target kernel to inform it about the location of its critical data. RKP embeds hooks inside the kernel code so it is informed whenever a new memory area is going to be allocated to the kernel. It then prevents this memory from being double mapped to writable memory anywhere else in the system.
This protection is effective against attacks that use double mapping to exploit kernel data. Although RKP relies on the kernel to inform it about the allocated data memory areas, this dependency does not weaken the protection. The kernel is assumed to be secure when it sends the information to RKP because this happens before the data pages are allocated. Afterwards, RKP prevents the data from being modified, except by the kernel itself.
Protecting the kernel data that defines user process credentials
After preventing kernel code modifications and double mapping of kernel data, the last class of attacks that threatens the kernel security is to alter the kernel control flow so that it maliciously modifies its own data. These attacks may include pointer manipulation, pointer overflow or return-oriented attacks.
Although RKP cannot fully protect against this class of attacks, it implements a novel technique to mitigate their effect through protecting selective kernel data structures that are critical to the system security. The data structure of choice is the process credentials data structure, which define the privilege level of the user processes running inside the device. User processes represent different running applications, such as user apps. In Linux, there is an instance of the credentials structure that is associated with each running process. This is frequently the target of rooting attacks, as by modifying this, a normal process can elevate its privilege.
RKP implements a three-step solution to protect the credential structure from malicious modifications. First, RKP makes all instances of the credential data structure read-only through controlling the memory translation tables. Second, it instruments the kernel so that all writes to the credential structures would be routed through RKP. This is guaranteed by the fact that the kernel now would not be able to write to this data from within the Normal World. Before writing to the credential data, RKP examines the values to be written to make sure that they do not maliciously escalate the privileges of their corresponding user process. Determining if a user process is legitimately entitled to an escalated privilege, such as the administrative privilege, is done through combining multiple techniques. For instance, RKP prevents processes that start with regular user privilege from escalating their privilege after they start. In another example, processes that are started by applications that interface with potential attackers, such as zygote and adb shell, are not allowed to have an escalated privilege. Finally, RKP adds a check to the kernel security hooks to verify that a credential structure actually belongs to the read-only memory protected by RKP before it is effectively used to determine the privilege of the user process. Hence, it is guaranteed that a potential attacker cannot forge a malicious instance of the credential structures that is not monitored and verified by RKP.
For detailed information on RKP and the TrustZone-based implementation of RKP, see the following link on the ACM Digital Library website.