430 likes | 714 Views
Analyzing and Improving Linux Kernel Memory Protection. A Model Checking Approach. ACSAC 2010 Siarhei Liakh, North Carolina State University Michael Grace, North Carolina State University Xuxian Jiang, North Carolina State University. Agenda. About Code Injection Murphi
E N D
Analyzing and Improving Linux Kernel Memory Protection A Model Checking Approach ACSAC 2010 Siarhei Liakh, North Carolina State University Michael Grace, North Carolina State University Xuxian Jiang, North Carolina State University
Agenda • About Code Injection • Murphi • Linux Kernel Memory Model • Analysis • Improvement and Prototype • Evaluation • Discussion and Related Work
About Code Injection • A method whereby an attacker inserts malicious code into a running process and transfers execution to the malicious code. • W ⊕X
Agenda • About Code Injection • Murphi • Linux Kernel Memory Model • Analysis • Improvement and Prototype • Evaluation • Discussion and Related Work
What’s Murphi • Both a language and a tool for model verification with explicit state enumeration. • Steps • Write a finite state machine (FSM) description. (*.m) • Compile with Murphi to produce an executable. • Run it • A DFS or BFS enumeration. • Anything that can go wrong, will go wrong. ── Murphy’s law
Terminology in Murphi • State • The set of states is implicitly defined through the declaration of global variables. • Each combination of values of each variable naturally produces a unique state of the system. • Transition rule • The transitions between the states of FSM are defined through a set of transition rules • Guard • Action
Terminology in Murphi (2) • Initial state • A state defined by a special rule with an action which is executed only once. • Invariant • A set of logic expressions which define a set of safe states of FSM.
Agenda • About Code Injection • Murphi • Modeling Linux Kernel Memory Model • Analysis • Improvement and Prototype • Evaluation • Discussion and Related Work
Memory Layout Fig. 1: Typical Linux memory mapping
How High Memory is Mapped • There are two basic mechanisms through which high memory is mapped • vmalloc() • Long-term allocation of non-contiguous physical memory into contiguous virtual address space. • May allocate pages from either high or low memory. • An “alias” is created when allocating pages from low memory. That is , the same physical page will be mapped into the kernel virtual address space twice. • kmap() • Strictly short-term allocation. • Strictly used for high memory only.
Modeling Memory Model • In this work, vmalloc() and kmap() are treated as the same (that mapping non-contiguous physical pages into the kernel address space). • Since fixmap doesn’t represent an unique type of mapping, we don’t include it in the model.
Modeling Memory Model (2) Fig. 2: Global definition of page table array and physical memory array
Transition Rules • Base on source code and domain knowledge, we extract kernel function or API affecting kernel memory mapping • cpa_process_alias() • __change_page_attr_set_clr() • __change_page_att() • static_protections() • map_vm_area()
Transition Rules (2) Fig. 3: Transition rules
Invariant • P1: Kernel code should always be executable and read-only. • P2: Kernel data should always be non-executable, the read-only kernel data should remain read-only, and read-write kernel data should always be writable. • P3: No page will be writable and executable at the same time in order to not violate W ⊕ X. • P4: All virtual aliases of each physical page should have consistent access permissions.
Agenda • About Code Injection • Murphi • Linux Kernel Memory Model • Analysis • Improvement and Prototype • Evaluation • Discussion and Related Work
After Model Verification • There is no P1 violation in current Linux. • However, it reports violations for other three invariants. • Fig. 4: Property violations
P2 Violation • The violation of P2 arises when kernel read-write data region is set as read-only. • static_protections() doesn’t check for the correctness of new access flags set for the kernel read-write data region. • Could cause a denial of service attack that immediately follows the call of set_pages_ro() for read-write data region.
P3 Violation • The first occurs when BIOS32 is mapped into the kernel space during the initialization directly. • While BIOS is typically stored in ROM and should not be overwritten, Linux map it as writable and executable.
P3 Violation (2) Fig. 5: Original 2.6.33 kernel page tables
P3 Violation (3) • The second scenario is related to the original memory management interface that allows for pages to be mapped as writable and executable at the same time. • The source of problem is the absence of any access permission verification system for memory pages outside the static kernel image in the default memory management interface, such as when a kernel module is being loaded.
P4 Violation • Violation of P4 happens when a page from low memory region is being mapped into vmalloc() area as executable. • A module loader could use vmalloc() to load all modules sections, including code with execute permissions while linear mapping space with RW+NX permission.
Agenda • About Code Injection • Murphi • Linux Kernel Memory Model • Analysis • Improvement and Prototype • Evaluation • Discussion and Related Work
Authors’ Work • Revise the memory management subsystem in Linux and admit five kernel patches. • 4 of them are in the process of being integrated into mainline Linux kernel. • 1 still being assessed. • There are two distinct levels of abstraction interfaces to manage Linux kernel memory. They choose high-level interface for performance consideration.
Fix P2 Violation • Preserving the “write” access on kernel read-write data. • Fix static_protections() to preserve the write access to read-write data (including BSS). • Fix try_preserve_large_pages() that incorrectly processes access permission change requests for area that start on a boundary of a large page, but area smaller than the page itself.
Fix P3 Violation • Removing mixed pages in kernel space. • For BIOS32 • Implement a patch that dynamically maps BIOS32 services into the kernel space. • For Linux Kernel Module (LKM) • The linker choose minimal amount space necessary between each module’s section. • CONFIG_DEBUG_SET_MODULE_RONX
Fix P3 Violation (2) • For static kernel image • Similar to LKM. • Modify alignment in kernel/vmlinux.lds.S • Assign proper access permissions to the pages of each group at the end of kernel initialization (mm/init.c).
Fix P4 Violation • Disallowing memory aliasing with permission conflicts. • Fix cpa_process_alias() to check alias when _X bit is set. • Implement a helper routine process_WxorX_violation() in mm/pageattr.c to enfore W ⊕ X property.
Agenda • About Code Injection • Murphi • Linux Kernel Memory Model • Analysis • Improvement and Prototype • Evaluation • Discussion and Related Work
Simple Modeling • A system that contains • One virtual page of each type • Kernel text • Kernel read-only data • Kernel read-write data • Linear mapping • Two pages in non-contiguous mapping • Model the physical memory with one more page frame than the total size of the virtual address space. • Model checker examined 27,942 states and 7,823,760 rules without detecting any violations.
Ubuntu Server 8.04.4 Fig. 6: Comparison of original and patched kernel
Ubuntu Server 8.04.4 Fig. 7: Comparison of original and patched kernel (2)
Performance • The first four patches don’t introduce any performance overhead as all works are mainly performed at compile time. • Only run time penalty is checking for alias. (In the helper routine process_WxorX_violation()) • Fig. 8: Run time W ⊕ X enforcement overhead
Memory Overhead • Size of static kernel image increased from 6793KB to 6796KB, overhead = 0.04%. • Fig. 7: Comparison of original and patched kernel (2)
Memory Overhead (2) • We also load 44 kernel modules of varying sizes and check the total size by lsmod command. • Size increased from 1,265,502 B to 1,493,138 B. (22.01%) • If we can take the whole-page allocation into account, the memory overhead is increased from 322 pages (size of 4K) to 382 pages (an increase of 22.17%) • CONFIG_DEBUG_SET_MODULE_RONX
Agenda • About Code Injection • Murphi • Linux Kernel Memory Model • Analysis • Improvement and Prototype • Evaluation • Discussion and Related Work
Discussion • We assumes that the static kernel image and LKMs are trusted, and follow the transition rules to manage the kernel memory. • Kernel / driver signing • While providing W ⊕ X is helpful to block code injection attacks, W ⊕ X itself doesn’t prevent other types of attacks. • Our modeling is based on the correctness of the internal kernel APIs, any code inside the function that modifies page tables directly will not be prevented from doing so. • Few exceptions need to consider, e.g. ftrace.
Related Work • Model checking for improved security. • W ⊕ X enforcement • Use custom hypervisor that needs special authentication mechanisms. • Lead to significant performance degradation. • We analyze the protection in the Linux kernel memory space while others mainly concentrate on userspace application protection. • ASLR, ISR