GUARDER: a Tunable Secure Allocator
Total Page:16
File Type:pdf, Size:1020Kb
GUARDER: A Tunable Secure Allocator Sam Silvestro, Hongyu Liu, and Tianyi Liu, University of Texas at San Antonio; Zhiqiang Lin, Ohio State University; Tongping Liu, University of Texas at San Antonio https://www.usenix.org/conference/usenixsecurity18/presentation/silvestro This paper is included in the Proceedings of the 27th USENIX Security Symposium. August 15–17, 2018 • Baltimore, MD, USA ISBN 978-1-939133-04-5 Open access to the Proceedings of the 27th USENIX Security Symposium is sponsored by USENIX. GUARDER: A Tunable Secure Allocator Sam Silvestro∗ Hongyu Liu∗ Tianyi Liu∗ Zhiqiang Lin† Tongping Liu∗ ∗University of Texas at San Antonio †The Ohio State University Abstract Vulnerability Occurrences (#) Heap Overflow 673 Due to the on-going threats posed by heap vulnerabili- Heap Over-read 125 Invalid-free 35 ties, we design a novel secure allocator — GUARDER— Double-free 33 to defeat these vulnerabilities. GUARDER is different Use-after-free 264 from existing secure allocators in the following aspects. Existing allocators either have low/zero randomization Table 1: Heap vulnerabilities reported in 2017. entropy, or cannot provide stable security guarantees, where their entropies vary by object size classes, exe- dows versions [12]. Heap vulnerabilities still widely ex- cution phases, inputs, or applications. GUARDER en- ist in different types of in-production software, where Ta- sures the desired randomization entropy, and provides an ble 1 shows those reported in the past year at NVD [29]. unprecedented level of security guarantee by combining Secure memory allocators typically serve as the first all security features of existing allocators, with overhead line of defense against heap vulnerabilities. How- that is comparable to performance-oriented allocators. ever, existing secure allocators, including the OpenBSD Compared to the default Linux allocator, GUARDER’s allocator [28] (which we will simply refer to as performance overhead is less than 3% on average. This “OpenBSD”), DieHarder [30], Cling [2], and Free- overhead is similar to the previous state-of-the-art, Free- Guard [33], possess their own strong deficiencies. Guard, but comes with a much stronger security guaran- First, these allocators provide either low randomiza- tee. GUARDER also provides an additional feature that tion entropy, or cannot support a stable randomization allows users to customize security based on their perfor- guarantee, which indicates they may not effectively de- mance budget, without changing code or even recompil- fend against heap overflows and use-after-free attacks. ing. The combination of high security and low overhead Cling does not provide any randomization, while Free- makes GUARDER a practical solution for the deployed Guard only provides two bits of entropy. Although environment. OpenBSD and DieHarder supply higher entropy levels, their entropies are not stable, and vary across different 1 Introduction size classes, execution phases, inputs, and applications. Typically, their entropies are inversely proportional to an A range of heap vulnerabilities, such as heap over- object’s size class. For instance, OpenBSD has the high- reads, heap over-writes, use-after-frees, invalid-frees, est entropy for 16 byte objects, with as many as 10 bits, and double-frees, still plague applications written in while the entropy for objects with 2048 bytes is at most 3 C/C++ languages. They not only cause unexpected pro- bits. Therefore, attackers may exploit this fact to breach gram behavior, but also lead to security breaches, includ- security at the weakest point. ing information leakage and control flow hijacking [34]. Second, existing allocators cannot easily change their For instance, the Heartbleed bug, a buffer over-read prob- security guarantees, which prevents users from choos- lem in the OpenSSL cryptography library, results in the ing protection based on their budget for performance or leakage of sensitive private data [1]. Another example memory consumption. For instance, their randomization of a recent buffer overflow is the WannaCry ransomware entropy is primarily limited by bag size (e.g. DieHarder attack, which takes advantage of a vulnerability inside and OpenBSD), or the number of free lists (e.g. Free- Server Message Block [17], affecting a series of Win- Guard). For instance, simply incrementing FreeGuard’s USENIX Association 27th USENIX Security Symposium 117 entropy by a single bit may significantly increase mem- GUARDER ory consumption, due to doubling its number of free lists. Third, existing secure allocators have other problems that may affect their adoption. Both OpenBSD and Die- Harder impose large performance overhead, with 31% DieHarder and 74% on average. Also, they may slow down some FreeGuard Security Security applications by 4× and 9× respectively, as shown in OpenBSD Figure 3. This prohibitively high overhead may prevent their adoption in performance-sensitive scenarios. On Linux the other hand, although FreeGuard is very efficient, its Performance low entropy and deterministic memory layout make it an easier target to attack. Figure 1: Comparing to performance vs. security of This paper presents GUARDER, a novel allocator that existing work provides an unprecedented security guarantee, but with- out compromising its performance. GUARDER supports all necessary security features of existing secure alloca- be moved to the allocation buffer upon each allocation, tors, and offers the highest level of randomization en- and in a batched mode when the allocation buffer is re- tropy stably. In addition, GUARDER is also the first se- duced to half-full. More implementation details are de- cure allocator to allow users to specify their desired se- scribed in Section 4. curity guarantee, which is inspired by tiered Internet ser- The combination of allocation and deallocation vices [8]. buffers also seamlessly integrates with other customiza- Existing allocators provide unstable randomization tion mechanisms, such as guard pages and over- entropies because they randomly select an object from provisioning. When filling the allocation buffer with new those that remain available within a bag (e.g. OpenBSD), heap objects, GUARDER maintains a bump pointer that or among multiple bags belonging to the same size class always refers to the next new object at the top of the (e.g. DieHarder). However, the number of available ob- heap. It will skip all objects tied to randomly-selected jects is reduced with every allocation, unless immedi- guard pages (and set them as non-accessible), and ran- ately offset by a deallocation, thus decreasing entropy. domly skip objects in proportion to the user-defined Also, their entropies greatly depend on the bag size, over-provisioning factor. This mechanism ensures these which limits the total number of available objects inside. skipped objects will never participate in future alloca- GUARDER proposes an allocation buffer to track avail- tions and deallocations. In contrast, DieHarder is unable able objects for each size class, then randomly chooses to place guard pages within the interior of a bag, since one object from the buffer upon each allocation. The al- every object has a chance of being allocated in the fu- location buffer will be dynamically filled using both new ture. For this same reason, DieHarder may incur a larger and recently-freed objects on-demand, avoiding this de- memory footprint or additional cache misses. crease of entropy. The allocation buffer will simultane- GUARDER designs multiple mechanisms to further ously satisfy the following properties: (1) The buffer size improve its performance. First, it designs a novel heap can be easily adjusted, where a larger size will provide a layout to quickly locate the metadata of each freed ob- higher randomization entropy; (2) The buffer size is de- ject in order to detect double and invalid frees. Second, it fined independently from any size class in order to pro- minimizes lock acquisitions to further improve scalabil- vide stable entropy for objects of different size classes; ity and performance. Third, it manages pointers to avail- (3) It is very efficient to locate an item inside the buffer, able objects directly within the allocation buffer, remov- even when given an index randomly; (4) It is more effi- ing a level of indirection compared to existing bitmap- cient to search for an available object by separating avail- based (e.g. DieHarder or OpenBSD) or free-list-based able objects from the large amount of in-use ones. (e.g. FreeGuard) approaches. GUARDER also overcomes However, although it is possible to place deallocated the obvious shortcoming of FreeGuard’s deterministic objects into the allocation buffer directly, it can be very layout by constructing per-thread heaps randomly. Com- expensive to search for an empty slot in which to do so. pared to existing work, as shown in Figure 1, GUARDER In addition, it is difficult to handle a freed object when achieves the highest security, while also imposing small the allocation buffer is full. Instead, GUARDER pro- performance overhead. poses a separate deallocation buffer to track freed ob- Overall, GUARDER makes the following contributions. jects: freed objects will be recorded into the deallocation Supporting a stable and tunable security guarantee. buffer sequentially, which will be more efficient due to It is the first allocator to support customizable security avoiding the need for searching; these freed objects will guarantees on randomization entropy, guard pages, and 118 27th USENIX