Preventing invalid memory references
By utilizing unused bits of object pointers to store boundary information at the hardware level and performing boundary checks in load and store instructions, the memory error problem of heap objects in C/C++ applications is solved, achieving space and time safety with minimal performance impact.
Patent Information
- Application Number
- CN202111197956.1
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- Priority Date
- 2020-10-15
- Filing Date
- 2021-10-14
- Publication Date
- 2025-12-05
- Estimated Expiration
- 2041-10-14
AI Technical Summary
Existing technologies are insufficient to effectively prevent memory errors in C/C++ applications, especially out-of-bounds access to heap objects and errors in using them after they have been freed. Furthermore, existing solutions often involve significant performance overhead or changes to the source code and binary layout.
By reusing unused bits of the object pointer at the hardware level to store boundary information, BITable is used to track object boundaries, and boundary checks are performed in load and store instructions, avoiding changes to the binary layout.
It achieves space and time safety for heap objects, preventing out-of-bounds access and misuse after freeing, while maintaining low performance impact and requiring no changes to source code or binary layout.
Smart Images

Figure CN114371951B_ABST
Abstract
Description
BACKGROUND
[0001] The present disclosure relates to computing devices, and more specifically, to techniques that facilitate hardware-based memory error mitigation for heap objects. SUMMARY
[0002] The following presents a summary to provide a basic understanding of one or more embodiments of the application. This summary is not intended to identify key or critical elements, or delineate any scope of certain embodiments or any scope of the claims. Its sole purpose is to present concepts in a simplified form as a prelude to the more detailed description that is presented later. In one or more embodiments described herein, systems, apparatus, computer-implemented methods, and / or computer program products that facilitate hardware-based memory error mitigation for heap objects are described.
[0003] According to an embodiment, a system can include a processor that executes computer executable components stored in a non-transitory computer readable medium. The computer executable components include: an entry component; and a re-purpose component. The entry component can allocate an entry in a table to store bound information when an object is allocated in memory. The re-purpose component can re-purpose unused bits of an object address to store an index to the table entry.
[0004] According to another embodiment, a computer implemented method can include allocating, using a processor, an entry in a table to store bound information when an object is allocated in memory. The computer implemented method can also include re-purposing, using the processor, unused bits of an object address to store an index to the table entry.
[0005] According to another embodiment, a computer program product can include a computer readable storage medium having program instructions. The program instructions can be executable by a processor to cause the processor to perform operations. The operations include allocating an entry in a table to store bound information when an object is allocated. The operations also include re-purposing unused bits of an object address to store an index to the table entry. BRIEF DESCRIPTION OF DRAWINGS
[0006] Figure 1 Example non-limiting grouping of bound check based techniques based on respective bound metadata location is illustrated in accordance with one or more embodiments described herein.
[0007] Figure 2 A block diagram of an example non-limiting system that can facilitate hardware-based memory error mitigation for heap objects is illustrated in accordance with one or more embodiments described herein.
[0008] Figure 3An example non-limiting high-level conceptual overview of reusing unused bits of object pointers to perform space and time safe for heap objects is shown in accordance with one or more embodiments described herein.
[0009] Figure 4 An example non-limiting high-level conceptual overview of the lifetime of pointers during program runtime is shown in accordance with one or more embodiments described herein.
[0010] Figure 5 An example non-limiting organization layout of a bounds checking framework is shown in accordance with one or more embodiments described herein.
[0011] Figure 6 An example non-limiting BITable is shown in accordance with one or more embodiments described herein.
[0012] Figure 7 An example non-limiting layout of a 64-bit virtual address space for a program is shown in accordance with one or more embodiments described herein.
[0013] Figure 8 An example non-limiting hardware organization for implementing hardware-based bounds checking is shown in accordance with one or more embodiments described herein.
[0014] Figure 9 An example non-limiting scenario for slowdown involving hardware-based bounds checking is shown in accordance with one or more embodiments described herein.
[0015] Figure 10 An example non-limiting diagram depicting functionality in which out-of-bounds accesses are detected with a hardware-based bounds checking framework is shown in accordance with one or more embodiments described herein.
[0016] Figure 11 An example non-limiting diagram depicting instructions in SPEC-CPU 2017 applications that cause out-of-bounds is shown in accordance with one or more embodiments described herein.
[0017] Figure 12 An example non-limiting diagram depicting performance impact of software instrumentation for BITable management is shown in accordance with one or more embodiments described herein.
[0018] Figure 13 An example non-limiting diagram depicting performance impact of hardware bounds checking is shown in accordance with one or more embodiments described herein.
[0019] Figure 14An example, non-limiting chart depicting loads per 1000 instructions with BICache misses, in accordance with one or more embodiments described herein is shown.
[0020] Figure 15 An example, non-limiting chart depicting percentage of loads with BICache misses, in accordance with one or more embodiments described herein is shown.
[0021] Figure 16 An example, non-limiting chart depicting average slowdown associated with bound checks at BICache size changes, in accordance with one or more embodiments described herein is shown.
[0022] Figure 17 An example, non-limiting chart depicting BICache miss rate at BICache size changes, in accordance with one or more embodiments described herein is shown.
[0023] Figure 18 An example, non-limiting chart depicting memory bandwidth overhead associated with bound checks, in accordance with one or more embodiments described herein is shown.
[0024] Figure 19 An example, non-limiting chart depicting memory bandwidth overhead associated with the BITable, in accordance with one or more embodiments described herein is shown.
[0025] Figures 20A-20G An example, non-limiting operational flow for initializing the BITable in memory, in accordance with one or more embodiments described herein is shown.
[0026] Figures 21A-21E An example, non-limiting operational flow for processing a memory allocation function, in accordance with one or more embodiments described herein is shown.
[0027] Figures 22A-22K An example, non-limiting operational flow for processing a load instruction, in accordance with one or more embodiments described herein is shown.
[0028] Figure 23 An example, non-limiting pointer, in accordance with one or more embodiments described herein is shown.
[0029] Figure 24 An example, non-limiting pointer, in accordance with one or more embodiments described herein is shown.
[0030] Figure 25 An example, non-limiting addition operation performed on a pointer to Figure 24 is shown.
[0031] Figure 26A flow diagram illustrating an example, non-limiting computer-implemented method that can facilitate hardware-based memory error mitigation for heap objects in accordance with one or more embodiments described herein is shown.
[0032] Figure 27 A block diagram illustrating an example, non-limiting operating environment in which one or more embodiments described herein can be facilitated is shown. DETAILED DESCRIPTION
[0033] The following detailed description is merely illustrative and is not intended to limit embodiments and / or the application or uses of embodiments. Furthermore, there is no intention to be bound by any expressed or implied information presented in the preceding Background or Summary sections or the Detailed Description section.
[0034] One or more embodiments will now be described, by way of example only, with reference to the attached figures, in which like references are used to refer to like elements throughout. In the following description, for purposes of explanation, numerous specific details are set forth in order to provide a more thorough understanding. Flowever, it is apparent that the one or more embodiments can be practiced without these specific details.
[0035] Applications written in memory-unsafe languages such as C or C++ that utilize user code to explicitly manage memory are vulnerable to memory safety errors such as buffer overflows, use-after-free, and the like. Such errors have been exploited in many attacks, including high-profile attacks such as the Morris worm and Heartbleed. Moreover, such errors are ranked by MITRE as some of the most dangerous software flaws. A recent study by a technology company revealed that such errors remain the root cause of approximately 70% of Common Vulnerability Exposures (CVEs) identified in its production software. In particular, errors specific to heap objects, including heap corruption, out-of-bound access, and use-after-free, accounted for nearly 50% of CVEs in 2019.
[0036] To date, a number of solutions have been proposed to detect or prevent such errors, which can be broadly classified as either blacklist-based or whitelist-based. Blacklist-based approaches prevent (some) unsafe locations from being accessed (e.g., by inserting trip-wires around objects), and generally face fewer adoption barriers, such as prohibitive performance overhead or intrusive changes to program source code. However, blacklist-based approaches lack complete coverage, allowing errors to remain undetected, free to develop in the wild. In contrast, whitelist-based approaches enforce safe program behavior based on authorization (e.g., a bounds checking mechanism that verifies all pointer dereferences are within object bounds), and allow for more precise enforcement of spatial and temporal memory safety. However, whitelist-based approaches often incur prohibitive slowdowns, ranging from 24% to 116% slowdowns. Furthermore, whitelist-based approaches often require destructive changes to source code or binary layout, making them difficult to adopt. Ideally, a practical solution for memory safety involves the strong safety of whitelist-based approaches, but without their performance or compatibility drawbacks.
[0037] As noted above, applications written in C / C++ (where pointer operations are allowed without safety checks) are prone to memory errors in which a pointer dereference invalidates a memory region. Spatial errors (out-of-bounds accesses) can arise from pointer arithmetic using unverified inputs that cause a buffer pointer to access memory beyond the bounds of the buffer. Similarly, temporal errors (e.g., use-after-free) can result from reads or writes using dangling pointers (pointers to freed objects whose memory has since been reused). Memory leaks and corruption resulting from such errors have been exploited by attacks that compromise data confidentiality, attempt privilege escalation, compromise system integrity, and the like. Enforcing memory safety and preventing memory errors can facilitate prevention of such attacks on production software. Various techniques can be implemented to enforce memory safety and prevent memory errors.
[0038] Such techniques include probabilistic techniques that can use tripwires, randomization, or marked memory to probabilistically detect memory accesses across object boundaries. An example of tripwire-based techniques is AddressSanitizer (ASAN) provided by Google LLC of MountainView, California. Tripwire-based techniques typically insert red zones or tripwires around an object to detect common spatial defects that extend slightly beyond the object's boundaries. An example of randomization-based techniques is DieHard. Randomization-based techniques typically randomize the memory layout with the support of a memory allocator to make defects easier to detect. An example of hardware-based memory marking techniques is Memory Mark Extension (MTE) provided by ARM Ltd. of Cambridge, UK. Hardware-based memory marking techniques typically assign random 4-bit tags, or "colors," to object pointer pairs to probabilistically detect defects based on "color" mismatches. While relatively easy to adopt due to minimal slowdowns or compatibility issues, probabilistic techniques may not be designed to provide complete coverage for error detection.
[0039] Such technologies can also include boundary-checking-based techniques, which can provide precise enforcement of secure procedural behavior by tracking object base addresses and boundaries and performing boundary checks on all object accesses. For example... Figure 1 As shown, the boundary-checking techniques 100 can be grouped based on the location of their respective boundary metadata. For example, the boundary-checking techniques 100 include adjacent boundary groups 110, which include fat pointer-based techniques such as CCured and Cyclone. Fat pointer-based techniques can store the base address and boundary metadata along with the actual pointer value in a separate word. This storage of the base address and boundary metadata facilitates boundary checks to detect space errors when the actual pointer is dereferenced. Similarly, some instances of fat pointer-based techniques can replace the pointer with 256-bit "capabilities," which may include addresses, boundary information, permission bits, and other metadata necessary for implementing fine-grained partitioning and boundary checks. Unfortunately, adjacent boundary groups 110 of boundary-checking techniques typically involve changes to the source code and also changes to the binary layout that affect compatibility with library code.
[0040] Inline bounds group 120 of bound-checking based techniques, including Low-Fat-pointer based techniques, provides another example. Low-Fat-pointer based techniques can encode object bounds inline with pointers without affecting binary layout. One instance of Low-Fat-pointer based techniques can use a compact floating point format to store (the least significant bits of) object base addresses and bound addresses in the top 18 bits of a 64-bit pointer. Other instances of Low-Fat-pointer based techniques can allocate objects in size-specific partitions of memory with size-aligned base addresses to implicitly encode base addresses and bounds in pointer values. These instances of Low-Fat-pointer based techniques can track pointer arithmetic (in hardware or via explicit instructions inserted by a compiler / just-in-time) to ensure that pointers never cross inline bounds. Unfortunately, inline bounds group 120 of bound-checking based techniques generally do not provide temporal safety because insertional checks using bounds within dangling pointers continue to pass even after the memory it references is re-used.
[0041] Disjoint bounds group 130 of bound-checking based techniques provides another example. Bound-checking based techniques within disjoint bounds group 130 can store bound metadata (per pointer or per object) in disjoint tables in shadow memory to avoid altering binary layout. Bound tables are generally indexed using pointer values as linear table lookups or using multi-level trie lookups. Such bound-checking based techniques can detect spatial errors (and some designs detect temporal errors) by performing bound checks on pointer dereferences or all pointer arithmetic with table lookups (inserted by software or implicitly by hardware). Pure software-based techniques within disjoint bounds group 130 involving additional instructions to propagate bound metadata for pointer arithmetic and for table lookups can incur high performance overhead (e.g., approximately 50%-112% on average). Hardware-based techniques within disjoint bounds group 130 can incur lower overhead by using microcode or specialized hardware to propagate bounds and perform checks compared to software-based techniques. However, such hardware-based techniques can continue to cause moderate to high slowdowns due to expensive table lookups to access bound metadata using pointer values.
[0042] Unlike the various memory safety techniques described above, implementations of the present disclosure involve a hardware-based bound checker that can precisely enforce object bounds to prevent spatial errors. Embodiments of the hardware-based bound checking framework facilitate efficient use of bound invalidation for dangling pointers to detect temporal errors. For practical adoption, embodiments of the hardware-based bound checking framework include low performance overhead and avoid changes to binary layout. To this end, implementations of the present disclosure involve a bound metadata design that can associate a pointer with a unique inline identifier that can be used to index into disjoint bound tables. One or more implementations of the present disclosure include an inline indexed disjoint bound group 140 of bound checking based techniques.
[0043] Figure 2 A block diagram of an example, non-limiting system 200 that can mitigate memory errors for heap objects in accordance with one or more embodiments described herein is shown. The system 200 includes a non-transitory computer-readable storage medium (storage medium) 210 to store computer-executable components and one or more processors 220 operatively coupled to the storage medium 210 for executing the computer-executable components stored in the storage medium 210 via one or more communication buses 230. As Figure 2 As shown, the computer-executable components include an entry component 240 and a reuse component 250.
[0044] When an object is allocated in memory, the entry component 240 can allocate an entry in a table to store bound information. The reuse component 250 can reuse unused bits of the object address to store an index to the table entry. In embodiments, the reuse component 250 can utilize the unused bits in the object address to track a range of memory addresses that can be accessed.
[0045] In embodiments, the computer-executable components stored in the storage medium 210 can also include a check component 260. The check component 260 can perform bound checks on load and store instructions in hardware by using the index bits in the address to access the bound information. In embodiments, the check component 260 can check array bounds. In embodiments, the check component 260 can determine whether an array reference is in bounds or out of bounds and mitigate the occurrence of out of bounds array references.
[0046] In embodiments, the computer-executable components stored in the storage medium 210 can also include a propagation component 270. The propagation component 270 can automatically propagate the index when a subsequent object address is derived via assignment statements or pointer arithmetic. In embodiments, the propagation component 270 can propagate extra information in unused bits when the object address is copied in an assignment statement. In embodiments, the propagation component 270 can propagate extra information in unused bits when the object address is passed as an argument in a function call. In embodiments, the propagation component 270 can propagate extra information in unused bits when the object address is used to compute an address. The functionality of the computer-executable components used by embodiments will be covered in more detail below.
[0047] The following disclosure presents a low-cost and minimally-invasive framework for bound checking in hardware. The disclosed technology relates to a hardware-enabled pointer bound checking framework for low-cost but precise enforcement of memory safety for heap objects. In embodiments, the disclosed bound checking framework for heap objects can be implemented using LLVM instrumentation to replace malloc / free calls in a program with custom library functions for maintaining bound information.
[0048] As discussed in more detail below, implementations of the disclosed technology use precise enforcement of object bounds on pointer dereferences to facilitate mitigation of memory errors for heap objects to prevent out-of-bounds access and use-after-free errors. The disclosed technology facilitates precise enforcement of such object bounds while ensuring minimal performance impact, and can be implemented without changing source code or binary layout. Embodiments of the disclosed technology can mitigate memory errors for heap objects by rethinking hardware-enforced bound checking in a vertically integrated hardware / software (HW / SW) ecosystem, with minimal changes to C / C++ memory allocation functions, instruction set architectures (ISAs), and hardware.
[0049] One aspect of the disclosed technology involves reusing "unused bits" in pointers to check or track the range of addresses that can be legally accessed via the pointers. In 64-bit architectures, object pointers have unused bits because they typically store virtual addresses with 48 bits or less information. The disclosed technology can exploit these unused bits to: (a) allocate an entry in a bound table to store bound information when an object is allocated; (b) reuse the unused bits (e.g., top-bits) of an object pointer to store an index to a bound table entry; (c) automatically propagate the index when a subsequent address is derived via assignment statements or pointer arithmetic; and / or (d) enforce bound checks on load and store instructions in hardware by using the index bits in the address to access the appropriate bound information.
[0050] By utilizing these unused bits, the disclosed technology facilitates spatial and temporal safe solutions for heap objects that prevent errors such as heap out-of-bounds reads and writes and use-after-free. In addition to mitigating heap errors, one or more embodiments of the disclosed technology are generally applicable to memory safety for global and stack objects as well. Preventing such errors can be desirable as they constitute almost 50% of the CVEs discussed above with respect to the Technology Company Institute and almost 60% of the memory safety defects detected by the OSS-Fuzz service provided by Google LLC of Mountain View, California.
[0051] Figure 3 An example non-limiting high-level conceptual overview of reusing unused bits (e.g., top bits) of object pointers to enforce spatial and temporal safety for heap objects is shown in accordance with one or more embodiments described herein. As shown, the disclosed technology generally reuses unused bits (e.g., top bits) of object pointers to store an index of an entry in a bound information table (BTAble) that contains bound metadata corresponding to the object pointer. In embodiments, the BTAble is a per-process BTAble. In one or more embodiments, the disclosed technology intercepts C library memory allocation functions to allocate an entry for malloc (dynamic allocation) in the BTAble and invalidate an entry for free (de-allocation). As shown, the disclosed technology can facilitate checking or tracking bound metadata for each object on the heap. This metadata can be used to enforce bounds checking on pointer dereferences via bound check operations in load / store execution in hardware. Using the index of the bound table entry in the unused bits (e.g., top bits) of the object pointer, the disclosed technology detects out-of-bounds accesses during the lifetime of the object. Figure 3 Figure 3 Further shown, the BTAble can facilitate checking or tracking bound metadata for each object on the heap. This metadata can be used to enforce bounds checking on pointer dereferences via bound check operations in load / store execution in hardware. Using the index of the bound table entry in the unused bits (e.g., top bits) of the object pointer, the disclosed technology detects out-of-bounds accesses during the lifetime of the object. Figure 3 Also shown, the disclosed technology uses the index pointing to an invalid bound table entry in the dangling pointer to detect use-after-free errors after the object is deallocated.
[0052] Notably, unlike existing fat pointer based approaches, the disclosed technology can facilitate keeping the binary layout unchanged. Additionally, the disclosed technology does not incur any overhead for propagation of the index when one pointer is assigned to another or passed in a function call or used to compute another address in array indexing or pointer arithmetic, which can happen “automatically” via program semantics. In contrast, existing solutions can require additional instructions or micro-operations to propagate the pointer metadata. In embodiments, the propagation of the index happens “automatically” without any “extra” instructions being fetched or executed.
[0053] Furthermore, the performance impact of actual bound checking can be minimal, at least for two reasons. First, since all addresses associated with a given buffer can have the same index, the index bits for the address and the bound information will typically be available in an on-chip bound information (BI) cache. Simulations of an example implementation show that the hit rate on bound information using an 8KB on-chip BI cache is greater than 98%. Second, bound checking for a load or store operation can be performed in parallel with the address translation for the load or store operation, typically adding no additional delay to the load or store instruction. Finally, since the location of the bound information (which can be determined by the index) is independent of the pointer value, the disclosed techniques can also maintain an invalid bound state for dangling pointers, even after the freed memory is re-used. The disclosed techniques can also provide temporal safety without additional cost, unlike existing hardware-based bound checking solutions in which the bound metadata location is typically linked to the pointer value.
[0054] In embodiments, the disclosed bound checking framework for heap objects can involve a threat model that includes one or more assumptions. One example assumption can be that a program can have heap memory safety flaws, such as out-of-bounds access, use-after-free, double-free, and invalid free. Another example assumption is that an adversary can pass unverified input to a program in an attempt to exploit such memory errors. Another example assumption is that an adversary cannot modify the user program code to introduce flaws, or directly access or tamper with bound metadata. Another example assumption is that the memory allocator functions that can be used by the disclosed framework to manage bound metadata are trustworthy and free of flaws.
[0055] One aspect of the disclosed bound checking framework is to store the bound metadata for an object throughout its lifetime in a B! Table within the program's virtual address space. In one embodiment, the B! Table is a per-process B! Table. Another aspect of the disclosed bound checking framework is to implement hardware-based bound checking on all object accesses at runtime.
[0056] Figure 4 An example non-limiting high-level conceptual overview of the lifetime of a pointer during program runtime is shown in accordance with one or more embodiments described herein. As Figure 4As shown, when an object is created, an entry (BIEntry) can be created in the BITable. The BIEntry can be used to store the base address and size of the object. In another embodiment, the BIEntry can be used to store addresses corresponding to the upper and lower bounds of the object. The index of the corresponding entry of the BITable can be embedded within the unused bits of the pointer. As used herein, the term "index bit" refers to the unused bit(s) of the pointer in which the index of the corresponding entry of the BITable is embedded. For simplicity, the following disclosure describes that the top 24 bits of the pointer can be used as the index bit. However, embodiments of the present invention are not limited to the index bit being the top 24 bits or contiguous bits of the pointer. In embodiments, the index bit is non-contiguous. In embodiments, one or more bits of the pointer precede the index bit in the pointer. Figure 4 Further shown is that the hardware can use the index within the top bits to access the corresponding BIEntry and perform a bounds check when the pointer is dereferenced to detect out-of-bounds access. Moreover, as Figure 4 As shown, when an object is released, the corresponding BIEntry can be invalidated. If a dangling pointer to such a released object is subsequently used, invalidating the corresponding BIEntry can facilitate detection of the time error.
[0057] Figure 5 An example non-limiting organization layout 500 of a bounds checking framework in accordance with one or more embodiments described herein is shown. As Figure 5 As shown, a software unit can manage the BITable. For example, hooks for the malloc and free functions can be used to intercept calls to these functions and perform the associated BITable operations, such as allocation and invalidation of BIEntries. Such hooks can be defined in a shared library added by the linker during program compilation. Moreover, such hooks can be added during program compilation without any changes to the source code and without any compatibility issues due to changes to the binary layout. Figure 5 Further shown is that a hardware unit on which the binary runs can transparently perform bounds checks for each load and / or store instruction to detect memory safety violations. The load and / or store instruction execution can be modified in hardware to also access the BITable and obtain bounds metadata for the bounds check. A bounds information cache (BICache) can be added to limit any slowdown of accessing the BITable in memory.
[0058] Figure 6An example non-limiting BITable 600 is shown in accordance with one or more embodiments described herein. As described above, the BITable 600 can be maintained within the virtual address space of a program. The BITable 600 can store bound metadata for each heap object in the program. Further, for each load instruction and / or store instruction targeting a heap object, the BITable 600 can be accessed to perform a bounds check.
[0059] Figure 6 The BITable 600 can be organized as a linear table comprising a plurality of BIEntries (e.g., BIEntry 610), where each BIEntry comprises a base address field 620 and an object size field 630. In Figure 6 In an embodiment, each BIEntry of the BITable 600 is implemented as a 16-byte BIEntry containing a 64-bit base address field and a 64-bit object size field. In an embodiment, each BIEntry of the BITable 600 can be implemented as a 12-byte BIEntry containing a 48-bit base address field and a 48-bit object size field. Each BIEntry of the BITable 600 can be associated with a heap object. Accessing a particular BIEntry of the BITable 600 corresponding to a given object can involve a single table lookup (BITable[index]). The single table lookup can involve using the index 640 that can be embedded in the pointer 650 during object allocation. In contrast, accessing bounds metadata using some implementations of the disjoint bounds group 130 based on the bounds checking techniques discussed above with respect to Figure 1 The disjoint bounds group 130 based on the bounds checking techniques discussed above with respect to
[0060] The memory space for the BITable can be reserved at program initialization using the mmap call with the MAP_ANONYMOUS flag to facilitate lazy allocation of physical pages at access time. Thus, the memory consumed by the BITable can grow in proportion to the number of malloced-objects in the program. The virtual address of the base address of the BITable and its size can be stored in special hardware registers (BTBASE and BTSIZE, respectively). In embodiments, the special hardware registers can only be accessed from privileged software or from within the hardware. The virtual address of the base address of the BITable and its size can be saved and / or restored with other process state at context switch time in a similar manner to the CR3 register storing the page table base address in the x86 architecture. This facilitates the hardware to compute the virtual address of a BIEntry as BTBASE + index * 16 when performing bounds checks. The size of the BITABLE can determine when to re-use entries that need to be invalidated upon deallocation. Typically, the BITable should be large enough to accommodate the maximum number of live objects (allocated but not yet deallocated) in the program. While the BITABLE size can be set to 16 million entries (the maximum live object count value among the SPEC-CPU2017 workloads analyzed below is 2.4 million), the user can choose a lower value at compile time to reduce memory consumption.
[0061] LLVM-based instrumentation can be used to initialize the malloc / free hooks before the main program is executed. In embodiments, the LLVM-based instrumentation can insert functions to initialize the malloc / free hooks. These hooks can intercept subsequent calls to malloc from the program and to free from the program. Those subsequent calls involve calling the internal memory allocation functions and creating or deleting BIEntries. Special instructions (setBIEntry / getBIEntry) can be used to update or check BIEntries within the trusted hook functions. To facilitate preventing unauthorized reads or writes to the BITable, other non-privileged software (outside of the trusted memory allocator functions) can be prohibited from using these special instructions to access the BITable (this can be enforced by the trusted compiler or runtime with binary checks). In embodiments, the createBIEntry and deleteBIEntry functions can be implemented as new ISA instructions to facilitate BITable security, where non-privileged usage is only allowed in our malloc / free functions (this can be ensured with binary checks). The hardware can explicitly prevent loads / stores to the BITable from non-privileged software.
[0062] Lists 1 and 2 show example function hooks that can be called on malloc / free. When malloc is intercepted, real_malloc can be called. When malloc is intercepted using the setBIEntry instruction, the returned base address and requested object size can also be stored in the BIEntry. For the first 16 million mallocs, a new BIEntry can be used in the BITable. Otherwise, a BIEntry that is invalidated on a free can be reused in a FIFO order using a FIFO that can store the index value of the freed BIEntry. The index of the BIEntry can then be embedded in the top 24 bits of the pointer and returned to the program. When free is intercepted, the index in the top 24 bits of the pointer can be used to obtain the BIEntry using the getBIEntry instruction. The index in the top 24 bits of the pointer can also be used to verify that the pointer value matches the object base address. The BIEntry can then be invalidated (e.g., the corresponding object base address and object size can be set to 0) and real_free can be called to free the object.
[0063]
[0064] List 1 : malloc_hook
[0065]
[0066] List 2: free_hook
[0067] Figure 7 An example non-limiting layout 700 of a 64-bit virtual address space for a program according to one or more embodiments described herein is shown. As described above, one or more embodiments of the disclosed bound checking framework can replace the top 24 bits of a heap object pointer with an index of a corresponding BIEntry in the BITable. On a 64-bit Linux system with a 4-level page table, a program can typically use a 48-bit user virtual address space. Since the index bits can overlap with the top 8 bits of a 48-bit user address, the program virtual address space can be restricted to a 2 terabyte (TB) region to avoid a collision of program addresses with heap addresses containing the 24-bit index bits, as shown. Figure 7 Examples of how embodiments of the disclosed bound checking framework can handle uncommon cases will be discussed in more detail below. Such uncommon cases can include instances where a program needs more than 2 TB of virtual address space, instances where there are not enough index bits available in a pointer, or instances where the BITable size is insufficient.
[0068] In the layout 700, the heap grows from 0x0 upwards to 0xFFFFFFFFFF, and the stack grows from 0x7FFFFFFFFFFF downwards to 0x7F0000000000. The remaining 254 TB of user virtual address space (i.e., the remaining portion of the 48-bit virtual address space) can be reserved with an mmap call using a PROT_NONE memory protection argument. For heap objects, the use of index value 0x7F in the layout 700 can be skipped to avoid collision with stack addresses. In addition, the use of index values from 0xFFFF80-0xFFFFFF in the layout 700 can be skipped to avoid collision with kernel addresses. Index 0x0 can be reserved for a NULL pointer (e.g., a pointer value of "0") to support free calls to NULL pointers, which can be a valid program behavior.
[0069] Detecting out-of-bounds accesses and post-free use in the disclosed bounds checking framework can depend on the bounds checks inserted by the hardware on loads and stores. The following disclosure provides an example design and implementation of such hardware-based bounds checking. In this example of the disclosed bounds checking framework, all loads and stores to heap objects (which can be identified by the presence of an index in the top 24 bits) can have hardware-based bounds checks included as part of the load / store execution. The bounds check can involve using the index to look up the corresponding BITable entry and obtain the base address and size of the object. Based on the obtained base address and size of the object, the hardware-based bounds check can assert that the access is within [base address, base address + object size]; otherwise, an out-of-bounds exception can be triggered. If the BIEntry base and object size are 0, a post-free use exception can be raised. If the BIEntry has been re-used, a dangling pointer access can still be detected with high probability due to the mismatch of bounds, but flagged as an out-of-bounds exception.
[0070] Figure 8 An example non-limiting hardware organization 800 for implementing hardware-based bounds checking is shown in accordance with one or more embodiments described herein. For hardware-based bounds checking, the address of the BIEntry for the bounds check can be computed as BTBASE + index * 16 using the BITableBase register and the index bits from the load / store address AS, and the address translation can be the same as a regular load. The execution of the bounds check can start when the virtual address of the load / store is ready, and can continue in parallel with the load / store execution without affecting its execution. The hardware-based bounds check is only on the critical path of the load / store commit phase, which only commits the load / store if the check passes; otherwise, it is deferred until the bounds check is complete. Figure 8It is shown that the BITable entries can be cached in a dedicated cache (BI Cache) within the hardware organization 800, which can be similar to the L1-D cache. For hardware-based bound checking, the BI Cache can be accessed in parallel with the L1-D cache on loads / stores, which can minimize the performance impact of hardware-based bound checking. Hardware-based bound checking that hits the BI Cache can have minimal or no impact on load / store latency.
[0071] Figure 9 An example non-limiting scenario involving slowdown of hardware-based bound checking is shown in accordance with one or more embodiments described herein. Figure 9 It is shown that the slowdown typically occurs only when the bound check has a BI Cache miss and the bound check is still pending before the corresponding load / store instruction reaches the commit stage.
[0072] In an embodiment, the disclosed bound checking framework can use a dedicated 8 kilobyte (KB), 8-way BI Cache for the BITable entries. All accesses to the BITable (for bound checking as well as loads and stores to the BITable from malloc and free) can be routed through the BI Cache. The design of the BI Cache can be virtually indexed, physically tagged (VIPT), and can be substantially similar to the L1-D cache with substantially similar latency (but much smaller size). This design can facilitate ensuring that if the hardware-based bound check hits in the BI Cache, the load / store execution does not perceive a performance impact. On a miss, the BI Entry can be serviced from memory for simplicity. In an embodiment, the entries can also be cached in the last level cache to facilitate further reduction in overhead. The load / store queue entry can be extended to store the state of the pending bound check in case of a BI Cache miss delay bound check. Storing the state of the pending bound check can involve storing a 48-bit BI Entry address, a 1-bit checkIssued flag, and a 1-bit checkComplete flag.
[0073] In embodiments, the disclosed bound checking framework can leverage the ISA's support for some instructions to prevent unauthorized access to the BITable by non-privileged adversaries. Such instructions can include an initBITable instruction. An operating system (OS) can use the initBITable instruction to set the BITable base address to an arbitrary virtual address at program initialization in the hardware's BTBASE register and the size in the BTSIZE register. Any access to the BTBASE register and / or the BTSIZE register from non-privileged software can result in an exception.
[0074] Such instructions can also include a setBIEntry instruction and a getBIEntry instruction, which can allow the trusted malloc / free functions to write or read BIEntries. For example, the setBIEntry instruction can set a particular BIEntry (BITable[index] = {base address, size}) and can be used to allocate or invalidate BIEntries in malloc or free. The getBIEntry instruction can allow free to read a BIEntry and check if the pointer to be freed is valid (BITable[index].base == ptr_val). The trusted compiler or runtime can facilitate ensuring that the setBIEntry instruction and / or the getBIEntry instruction are only used in trusted memory allocator functions. Furthermore, the hardware can facilitate preventing explicit loads and stores to the addresses mapped by the BITABLE from non-privileged software. This can ensure that non-privileged adversaries cannot read or write to the BITable, even if the adversary guesses the BITable address.
[0075] In embodiments, the malloc and free hook functions can be implemented in a thread-safe manner by using locks to ensure atomic updates to the BITable and BITable management data structures (e.g., free-entry FIFO). Additionally, the existing hardware's cache coherency structures can be used to maintain coherency across BICaches (with VIPT design) from different cores. Updates to the BITable from one core can be reflected in accesses from other cores without any additional software intervention. As long as the program itself is written in a thread-safe manner (e.g., there is no data race between a free and an access to the same object from different threads) and the internal memory allocator itself is thread-safe, the disclosed bound checking framework can maintain compatibility with multi-threaded programs.
[0076] As noted above, there are some unusual cases that can arise when implementing embodiments of the disclosed bound checking framework. In exceptional cases, the BI Table can not be able to store all of the program's BI Entries. For example, if the program has more live objects than the size of the BI Table, then the BI Table can not be able to store all of the program's BI Entries. As another example, if there is not a sufficient number of index bits available in the pointers, then the BI Table can not be able to store all of the program's BI Entries.
[0077] In such cases, an overflow table can be used to store the bound metadata. The pointers in the metadata that are kept in the overflow table can be identified by embedding a special value in their index bits. For such pointers, the pointer value itself can be used to look up the overflow table. Since such lookups can involve expensive multi-level table lookups, the program can ensure that only infrequently used BI Entries are placed in such an overflow table. For the SPEC-CPU2017 workloads evaluated with an implementation of the disclosed bound checking framework, a 16 million entry capacity BI Table was more than sufficient (at most less than 3 million entries were used), and no overflow table was needed.
[0078] The following disclosure provides example types of memory safety flaws that one or more embodiments of the disclosed bound checking framework can detect. The following disclosure further discusses examples of how to prevent an adversary from accessing the bound checking metadata. New potential flaws that can be detected using one or more embodiments of the disclosed bound checking framework are also discussed.
[0079] Example implementations of the disclosed bound checking framework were tested with 25 exploits from the How2Heap exploit suite that exploit heap space and time safety flaws, such as out-of-bounds access, use-after-free, invalid free, and double free. Example implementations of the disclosed bound checking framework were able to detect flaws in all 25 of these programs and raised exceptions to terminate the programs before the exploits' goals were achieved. Of these, example implementations of the disclosed bound checking framework detected out-of-bounds access in 8 exploits, use-after-free in 10 exploits, and invalid / double free in 7 exploits.
[0080] With respect to out-of-bounds access, the bound check inserted in parallel with the load / store can check the BIEntry and can ensure that the access is within the bounds of the object to which the load and store are directed. With respect to post- release use, if the bound check on the load / store finds a BIEntry with base = 0 and size = 0, then the object was recently released or the BIEntry was not initialized (the object was never dynamically allocated). In this instance, the example implementation of the disclosed bound check framework can flag both scenarios as errors and identify these flaws in 10 out of 25 exploit attempts. If the BIEntry is reallocated between release and post-release use, then post-release use can be detected with high probability as an out-of-bounds access. Alternatively, an overflow table can also be used to avoid BIEntry reuse together. With respect to double free and invalid free, if a mismatch is detected by the check on the released BIEntry, which verifies that the pointer to be released matches the object base address in the corresponding BIEntry, then it can indicate an invalid or double free flaw. If the index in the top bit of the pointer is not a valid value, or if the BIEntry object base address does not match, then an invalid free flaw can be flagged. Otherwise, if the BIEntry base address and size are 0, then a double free flaw can be flagged.
[0081] The two types of metadata used by one or more embodiments of the disclosed bound check framework to check the bounds of a load or store are: (i) the BIEntry in the BITable containing the bounds; and (ii) the index bits in the pointer used to access it. The following disclosure discusses examples of how the two types of metadata can be protected according to one or more embodiments described herein.
[0082] With respect to protecting the BITable, a non-privileged adversary cannot directly read or modify the BITable. Non-privileged software execution to the virtual memory where the BITable is mapped by the hardware can be prevented from loading or storing. This check can be performed by the load / store unit by preventing any non-privileged loads or stores to the address range starting at BTBase to BTBase + BITableSize. The setBIEntry and getBIEntry instructions that allow non-privileged software to access the BITable are typically only permissible within trusted memory allocator functions (which can be performed by a trusted compiler or runtime). Typically, only privileged OS or system software or hardware can directly access the BITable.
[0083] With respect to the index bits of a protection pointer, it can be assumed that an adversary cannot change the victim code to arbitrarily overwrite a pointer or generate a wild pointer. However, an adversary can attempt to exploit any unsafe pointer arithmetic in the victim code and use unverified input to cause an overflow or underflow that corrupts the index bits. Such corruption is typically detected as an error during bounds checking implemented in accordance with one or more embodiments described herein. Corruption of the index bits can also be prevented by extending the central processing unit (CPU) registers to separately store the index bits of a pointer so as to explicitly isolate the index bits from pointer arithmetic.
[0084] The following disclosure presents results of example testing of example bounds checking implemented by embodiments of the disclosed bounds checking framework, which was modeled with Gem5. The example testing was performed using 13 C / C++ SPEC-CPU2017 binaries, which were compiled using clang-11 and Glibc-v2.27. The following disclosure discusses out-of-bounds accesses detected by the example bounds checking when checking pointer accesses against allocation bounds for objects, where the BIEntry stores 16-byte aligned sizes allocated by malloc. One or more embodiments of the disclosed bounds checking framework also support byte-granular bounds checking by storing in the BIEntry the object size requested by the program.
[0085] Figure 10 Results of the example testing are depicted. In particular, Figure 10 An example non-limiting chart 1000 is shown that depicts functions in which out-of-bounds accesses were detected with embodiments of the disclosed bounds checking framework. Chart 1000 shows functions in which out-of-bounds accesses were detected with an example implementation of the bounds checking framework across 13 SPEC / C++ binaries, which were run for 110 billion instructions on a Gem5 simulator. Overall, as shown in chart 1000, Figure 10 of the example bounds checking framework detected out-of-bounds accesses in 87 lines of code. Of these 87 lines of code, 80 lines of code were in highly optimized Glibc-v2.27 functions for string processing (including strlen, strchr, strcmp, etc.), and 7 lines of code were in four user functions of the blender program. In this example testing, the maximum number of bytes accessed out-of-bounds was 62 bytes for the Glibc functions, and only 4 bytes for the functions in blender.
[0086] All of these defects detected in the example testing were observed to be due to SIMD instructions that load data from memory into SIMD registers. Figure 11An example non-limiting graph 1100 depicting instructions in SPEC-CPU 2017 applications that cause out-of-bounds is shown in accordance with one or more embodiments described herein. As shown Figure 11 Such instructions in Glibc string handling functions include SIMD move (MOVDQA, MOVDQU, MOVHPD, MOVLPD) or compare (PCMPEQB) or minimize (PMINUP) instructions, as shown. Figure 11 Such instructions in blender also include SIMD arithmetic instructions (MUSS, ADSS, SUBSS). On inspection, when compiled with the O3 flag, when the compiler uses unaligned 16-byte SIMD loads to access memory at the bounds of an object, a flaw in blender occurs, causing partial out-of-bounds access; these disappear when using the O0 flag because no SIMD arithmetic is used. The flaws in Glibc functions appear to be more serious because they are in shared libraries (libc.a) distributed with Ubuntu 18.04, and because they access up to 62 bytes of memory out-of-bounds.
[0087] Inspection of strlen, the function with the most lines of code (20) with out-of-bounds access, determined that most (11 of 20) of its flaws were due to the instruction PCMPEQB used to perform a byte-by-byte comparison of 16B operands (one from memory, the other from a register). The strlen function uses these to perform a quick check for the “\0” (null) character in the input string to compute the string length. Listing 3 shows example assembly code for strlen generated from an object-dump of libc.a in Glibc-v2.27. This code emits three (and up to four elsewhere) 16-byte comparisons together before using test and jump instructions to stop the comparison when a null value is encountered. This unsafe code can access up to 47 bytes of memory (and up to 63 bytes with four 16-byte comparisons) outside the string object. These binaries were also tested with the default version of ASAN, which could not detect any of these flaws because ASAN requires recompilation of shared libraries to be able to detect any flaws in them. Moreover, the default implementation of ASAN does not detect the partial out-of-bounds access of unaligned loads detected in blender by embodiments with the disclosed bounds checking framework.
[0088]
[0089] Listing 3: Disassembly of _strlen_sse2 from libc.a
[0090] The following disclosure outlines an evaluation methodology used to implement the above example tests. The following disclosure further discusses the overhead of example software and hardware modifications that can be involved in implementing one or more embodiments of the disclosed bound checking framework.
[0091] The evaluation methodology involved packaging software changes (including malloc / free hooks) for embodiments of the disclosed bound checking framework into shared libraries. The methodology also involved utilizing a patch added with LLVM10 to add an initialization function before the program main. Hardware changes for embodiments of the disclosed bound checking framework were modeled in Gem5 v 20.0. For performance evaluation, the evaluation methodology involved utilizing 13 of the 16 C / C++ benchmarks available in SPEC-CPU2017 with the ref dataset (3 workloads were not run with the evaluation methodology). The evaluation methodology also involved evaluating the overhead of software patching by running patched binaries to completion (emulating ISA changes in C code) on native (3.80 GHz Xeon CPU E-2174G provided by Intel Corporation of Santa Clara, CA) and comparing them to unpatched binaries. For hardware overhead, the evaluation methodology involved using patched binaries on Gem5 in system call emulation mode and running it with and without bound checking. The evaluation methodology further involved fast forwarding the first 10 billion instructions to skip the initialization phase and warm up the caches, and tracking statistics for 10 billion instructions. The hardware configuration for the evaluation methodology for Gem5 is shown in Table 1.
[0092]
[0093] Table 1
[0094] Figure 12 FIGURE illustrates an example, non-limiting chart 1200 depicting performance impact of software patching for BITable management in accordance with one or more embodiments described herein. In particular, chart 1200 depicts execution time of an application linked with a shared library that intercepts malloc / free calls to update a BITable. Chart 1200 generally facilitates evaluating slowdowns that can be associated with malloc / free patching. Execution times depicted in chart 1200 have been normalized to the execution time of the unpatched binary. Each execution time depicted in chart 1200 was obtained by running the corresponding program to completion on a native system and measuring the total execution time. To facilitate native execution and also model BITable management overhead, BIEntries are allocated at malloc without embedding the index bits into the pointer and are deleted at free at random BIEntries. Figure 12It is shown that, on average, software instrumentation for BITable management (without bound checks) can increase slowdown by approximately 0.5% across all programs. Due to increased cache accesses for BITable updates, workloads with high malloc frequency (e.g., gcc and perlbench) can have up to 1.8%-2.4% slowdown. Other workloads with small amount of malloc can see negligible performance impact.
[0095] Figure 13 An example non-limiting chart 1300 depicting performance impact of hardware bound checks is shown in accordance with one or more embodiments described herein. In particular, chart 1300 depicts execution times for 1 billion instructions of instrumented binaries running with bound checks, each normalized to the execution time of the corresponding binary without bound checks. Chart 1300 generally facilitates evaluating slowdowns that can be associated with hardware-based bound checks using instrumented binaries in Gem5. Figure 13 It is shown that, on average, hardware bound checks can increase slowdown by approximately 1%. A major driver of these overheads can be memory accesses caused by bound checks due to misses in the BICache. Workloads with high malloc frequency (e.g., xalancbmk, gcc, and parest) tend to have smaller buffers and, thus, fewer buffer accesses share the same index. This can result in a larger bound metadata working set, which can result in higher BICache miss rates (e.g., 2% to 16%) and higher slowdowns (e.g., 1% to 6%). Other workloads with >99% BICache hit rates can have negligible slowdowns.
[0096] Figures 14-15 An example breakdown of scenarios with loads with BICache misses is shown. In particular, Figure 14 An example non-limiting chart 1400 depicting loads per 1000 instructions with BICache misses is shown; Figure 15 An example non-limiting chart 1500 depicting percentage of loads with BICache misses is shown in accordance with one or more embodiments described herein. To understand slowdowns in workloads like xalancbmk, gcc, and parest, the scenarios that cause BICache misses for them are evaluated, since there is no slowdown if the bound check has a BICache hit. Generally, the evaluation determines that over 98% of BICache misses are caused by bound checks on load operations, while only 2% of misses occur on stores.
[0097] Graphs 1400 and 1500 show a breakdown of BiCache misses for load operations based on where the load gets serviced from, in absolute numbers and in percentages, respectively. As shown in graphs 1400 and 1500, the xalanckbmk workload has the most BiCache misses (as it has the highest miss rate), and thus the highest slowdown. On the other hand, the gcc workload has a higher miss rate than the parest workload, but the gcc workload causes less slowdown. In general, the gcc workload causes less slowdown because it has less of a fraction of BiCache misses when the load is an Ll hit (which has more impact on performance for that load than BiCache misses when the load is an Ll miss). The lack of locality in BICache accesses on Ll-Cache hits can be a major driver of slowdown for the xalanckbmk and parest workloads. However, this can be addressed by making the BIEngry allocation algorithm locality sensitive, especially for sub-cache-line objects common in these benchmarks, to reduce the overhead for these workloads.
[0098] Figures 16-17 Example slowdowns associated with BICache size as compared to bound checks are shown. In particular, Figure 16 Example non-limiting graph 1600 is shown that depicts average slowdown associated with bound checks as BICache size varies; Figure 17 Example non-limiting graph 1700 is shown that depicts BiCache miss rate as BICache size varies, in accordance with one or more embodiments described herein. While the example evaluation of bound check overhead described above utilizes a default BICache size of 8KB, graphs 1600 and 1700 depict evaluations of other BICache sizes. Specifically, graphs 1600 and 1700 show slowdowns associated with bound checks and BiCache miss rate as BICache size varies from 1KB to 64KB. Graphs 1600 and 1700 show that as BICache size increases, slowdown can decrease from 7% (1KB) to 3% (4KB) to 1% (8KB). With further increases in BICache size, the decrease in slowdown can be negligible. This is because beyond 8KB, the average BiCache miss rate typically does not decrease much, as the miss rate for most workloads can be less than 1%.
[0099] Figures 18-19 Example memory overhead associated with implementing embodiments of the disclosed bound check framework is shown. In particular, Figure 18 Example non-limiting graph 1800 is shown that depicts memory bandwidth overhead associated with bound checks; Figure 19An example non-limiting graph 1900 depicting memory overhead associated with a B I Table is shown in accordance with one or more embodiments described herein. Graph 1800 shows that, on average, bound checking can increase application memory bandwidth consumption by approximately 29%. However, application memory bandwidth consumption can vary depending on the BICache design. For example, by additionally caching BI Entries in a shared last-level cache, the bandwidth requirement can be reduced. Fortunately, DDR4 DRAM can satisfy the additional bandwidth requirement without causing a slowdown. In terms of memory consumption, a B I Table can consume up to 256 MB when configured with 16 bytes per entry for 16 million entries. In that configuration, a B I Table can consume an average of 39% additional memory. In an embodiment, a memory-optimized B I Table design (e.g., B I Table-MemOpt) with 8 million entries and 12-byte entries (storing 48-bit base addresses and bounds) can consume approximately 17% additional memory. These overheads can be much lower than shadow memory-based solutions (e.g., the disjoint bound group 130 discussed above with respect to FIG. 1 1) because the memory required for a B I Table can grow with the number of mallocs, not with the amount of program memory usage. Figure 1
[0100] The following disclosure describes other hardware-based solutions for spatial and temporal safety and contrasts the disclosed hardware-based bound checking framework with them. One distinguishing aspect of the disclosed bound checking framework compared to other bound checking solutions is that the disclosed bound checking framework facilitates the propagation and lookup of bound information at a very low cost.
[0101] As discussed above with respect to Figure 1 One technique in the disjoint bound group 130 accesses bound metadata from a shadow memory for bound checking, but it only provides spatial safety. Another technique in the disjoint bound group 130 extends that design to provide temporal safety at a modest cost (e.g., 24% slowdown on average) by associating pointers with unique identifiers that can be revoked (also stored in the shadow memory). This shadow memory access at bound check time has limited temporal locality because different shadow memory locations are accessed for different words loaded / stored to a single object. In one or more embodiments of the disclosed bound checking framework, an index bit in the pointer can be used to access the B I Table, which facilitates ensuring that all loads / stores to a single object can use the same B I Table entry. In turn, this facilitates being able to implement a low-cost bound check (e.g., 1% slowdown) that has over 98% hit rate in the BICache.
[0102] Another technique in disjoint bound group 130 provides spatial and temporal safety, associating a pointer with a capability stored in a separate capability table indexed using a Capability-ID (Capability-ID) to obtain bounds at bound checks. However, deriving a Capability-ID from a pointer value can be expensive for pointers that overflow to memory, requiring a second expensive lookup of a 5-level pointer-alias table. Although this technique proposes a speculative pointer tracking mechanism in hardware to cheaply propagate Capability-IDs to derived pointers, and caches capabilities and identifiers to limit average slowdown to 15%, the expensive table lookup can result in up to 40% high slowdown in the worst case. Moreover, carrying Capability-IDs over pointer arithmetic requires a speculative pointer tracking mechanism. In contrast, embodiments of the disclosed bound checking framework utilize a BTAble that can be looked up using an index embedded in unused bits of a pointer and can be automatically carried to derived pointers without additional cost, limiting worst-case slowdown to about 7%.
[0103] Other techniques in disjoint bound group 130 can provide spatial safety and temporal safety, but incur high overhead (e.g., 50-60% on average) because their bound checks require additional explicit instructions and involve expensive table lookups, as the bound table is organized as a two-level trie structure. In contrast, embodiments of the disclosed bound checking framework can implement bound checks that require at most a single table lookup, which can have high temporal locality and can be transparently inserted into hardware during load / store execution.
[0104] Techniques in adjacent bound group 110 can provide memory safety at the cost of changing binary layout, which affects compatibility with existing library code. Techniques in inline bound group 120 can avoid compatibility issues by reusing unused pointer bits for bound metadata, but at the cost of not providing temporal safety. Embodiments of the disclosed bound checking framework can maintain compatibility with legacy shared libraries and can even provide memory safety (both temporal and spatial) for pointers passed to existing shared libraries, while ensuring negligible slowdown.
[0105] Tripwire-based probabilistic techniques can provide low-cost detection of memory errors (e.g., 2%-18% slowdown) by inserting magic-values (i.e., tripwires) at object or sub-object granularity and checking them in hardware to detect out-of-bound accesses that activate such tripwires. However, such techniques cannot detect larger out-of-bound accesses that access memory beyond the tripwires. Embodiments of the disclosed bound checking framework can provide precise detection of all out-of-bound accesses with equal or better performance.
[0106] Memory tag based probabilistic techniques assign labels or "colors" to object-pointers, maintain these labels for both separately, and check the label of a pointer and the label of the accessed memory on pointer dereference for a match. While such techniques can have negligible slowdown (e.g., < 5% slowdown), they can only probabilistically detect errors as they use 4-bit labels (stored in the top bits of the pointer) that are reused for different objects, resulting in error false-negatives. Embodiments of the disclosed bound checking framework can also repurpose the pointer bits, but instead use them to store an index into actual bound information. In this way, embodiments of the disclosed bound checking framework can provide precise enforcement (high coverage) of object bounds with comparable slowdown.
[0107] Figures 20A-20G FIG. 1 illustrates an example non-limiting computing device 100, in accordance with one or more embodiments described herein. As shown, the computing device 100 includes a processor 102, a memory 104, and a bound checking library (BC_Library) 106. The processor 102 is configured to execute instructions and manipulate data stored in the memory 104. The memory 104 can include one or more types of storage media, such as random access memory (RAM), read only memory (ROM), flash memory, etc. The BC_Library 106 is configured to provide bound checking functionality for the computing device 100. In one or more embodiments, the BC_Library 106 is configured to provide a BITable for use in bound checking functionality. Figure 20A As shown, the operational flow 2000 includes a state 2002 in which an application or user program enters a runtime. From state 2002, the operational flow 2000 moves to a state 2004, as shown. Figure 20B In state 2004, the application generates a BITable initialization call that includes two arguments. The first argument of the BITable initialization call includes a mask value (e.g., 0xff00) that defines which unused bits in a pointer are to be used to store index information for corresponding BIEntries in the BITable. The second argument of the BITable initialization call includes a size value (e.g., 128) that defines the number of BIEntries to be allocated for the BITable at initialization. From state 2004, the operational flow 2000 moves to a state 2006, as shown. Figure 20C
[0108] In state 2006, the application issues the BITable initialization call to the bound checking library (BC_Library). From state 2006, the operational flow 2000 moves to a state 2008, as shown. Figure 20D In state 2008, a creation routine of the BC_Library creates the BITable in memory by allocating a memory region to the BITable based on the size value included in the BITable initialization call. From state 2008, the operational flow 2000 moves to a state 2010, as shown. Figure 20E In state 2010, an initialization routine of the BC_Library initializes the BITable by filling the BIEntries of the BITable with initial values. From state 2010, the operational flow 2000 moves to a state 2012, as shown.Figure 20F State 2012.
[0109] In State 2012, the special register routine of BC_Library fills a plurality of special hardware registers with values corresponding to BITable. As Figure 20F shown, the plurality of special hardware registers includes a bound table register (BTR), a bound mask register (BMR), and a bound table size register (BTSR). The BTR stores a base address of BITable in the allocated memory region. The BMR stores a mask value from the BITable initialization call issued by the application to BC_Library in State 2006. The BTSR stores a size value from the BITable initialization call issued by the application to BC_Library in State 2006, the size value defining a number of BIEntries comprising BITable. Operation flow 2000 moves from State 2012 to Figure 20G State 2014, shown. In State 2014, the handler routine of BC_Library sets a bt_handler that can be used to operate on BITable. In embodiments, the bt_handler is a global variable. In embodiments, the bt_handler includes a plurality of fields that store data related to: a base address of BITable, a size value of the BITable initialization call, a mask value of the BITable initialization call, or a combination thereof.
[0110] Figures 21A-21E An example non-limiting operation flow 2100 for processing a memory allocation function according to one or more embodiments described herein is shown. As Figure 21A shown, operation flow 2100 includes State 2102, in which an application generates a memory allocation call for requesting an allocation of a memory region. The memory allocation call includes an argument that includes a length value defining a size of the requested allocation of a memory region. Operation flow 2100 moves from State 2102 to Figure 21B State 2104, shown. In State 2104, the application issues the memory allocation call to a memory allocation function of a heap library (Heap_Library). As Figure 21BThe memory allocation function is shown generating a BIEntry create call that includes two arguments for creating an entry in the BITable (p = createBI(p, len)). In addition, the memory allocation function processes the original memory allocation call and allocates the requested memory region (p = origin_malloc(len)). The two arguments for BIEntry creation include a first argument that includes a pointer value defining the base address of the newly allocated memory region and a second argument that includes a length value defining the size of the allocated memory region. The operational flow 2100 moves from state 2104 to state 2106. Figure 21C The state 2106 is shown.
[0111] In state 2106, the memory allocation function of the HEAP_Library issues a BIEntry create call to the BIEntry create function of the BC_Library. The operational flow 2100 moves from state 2106 to state 2108. Figure 21D The state 2108 is shown. In state 2108, the BIEntry create function looks for a free BIEntry within the BITable to store the bound metadata associated with the allocated memory region. The operational flow 2100 moves from state 2108 to state 2110. Figure 21E The state 2110 is shown. In state 2110, the BIEntry create function fills the free BIEntry with a pointer value defining the base address of the allocated memory region and a length value defining the size of the allocated memory region. The BIEntry create function further embeds the index value (idx) of the free BIEntry into the pointer value to create a new pointer value that is returned to the memory allocation function.
[0112] Figures 22A-22K An example non-limiting operational flow 2200 for processing a load instruction according to one or more embodiments described herein is shown. As Figure 22A The operational flow 2200 includes state 2202 where an application can execute a load instruction from an address Ra, as shown. The operational flow 2200 moves from state 2202 to state 2204. Figure 22B The state 2204 is shown in FIG. 22B. In state 2204, a bound protection unit (BPU) can extract an address value and a mask value from the Ra register and the BMR. The operational flow 2200 moves from state 2204 to state 2206. Figure 22C The state 2206 is shown. In state 2206, the BPU can extract a memory address and an index value of a heap object associated with the load instruction from the address value and the mask value. The operational flow 2200 moves from state 2206 to state 2208. Figure 22Dthe state 2208. In the state 2208, the memory address and the mask value derived from Ra can be used by the load instruction to load bytes from the heap object. The operational flow 2200 moves from the state 2208 to Figure 22E the state 2210.
[0113] In the state 2210, the BPU can use the BTR containing the base address of the BITable associated with the application program and the index derived from Ra and BMR to determine the address of the BIEntry corresponding to the address Ra. The operational flow 2200 moves from the state 2210 to Figure 22F the state 2212. In the state 2212, the BPU uses the address of the BIEntry determined in the state 2210 to obtain the appropriate BIEntry for the load instruction. The operational flow 2200 moves from the state 2212 to Figure 22G the state 2214. In the state 2214, the BPU can compare the index value with the size value of the BITable retrieved from the BTSR to evaluate whether the index value is valid. The operational flow 2200 moves from the state 2214 to Figure 22H the state 2216.
[0114] In the state 2216, if the evaluation of the state 2214 determines that the index value is not valid, the BPU can generate an exception value and store the exception value in a bound status register (BSR). Alternatively, if the evaluation of the state 2214 determines that the index value is valid, the BPU can issue a BI load instruction to the bound cache including the BIEntry address. The operational flow 2200 moves from the state 2216 to Figure 22I the state 2218. In the state 2218, if the bound cache includes the bound metadata, the BPU can obtain the bound metadata corresponding to the heap object from the bound cache in response to the BI load instruction. Alternatively, if the bound cache does not include the bound metadata, the BPU can obtain the bound metadata corresponding to the heap object from the BITable in the memory in response to the BI load instruction. The operational flow 2200 moves from the state 2218 to Figure 22J the state 2220.
[0115] In the state 2220, the BPU can compare the bound metadata with the memory address of the heap object extracted in the state 2206 to evaluate whether the memory address to be loaded is valid. The operational flow 2200 moves from the state 2220 to Figure 22KThe state shown is 2222. In state 2222, if the evaluation of state 2220 determines that the memory address is invalid, the BPU can generate an exception and store it in the BSR. Alternatively, if the evaluation of state 2220 determines that the memory address of the heap object is valid, the BPU can allow the load instructions executed by the application to continue.
[0116] Figure 23 An example non-limiting pointer 2300 according to one or more embodiments described herein is shown. In some instances, as a result of array indexing or pointer arithmetic, arithmetic can "overflow" to unused bits (or index bits) of the pointer and "corrupt" those unused bits (or index bits) that are used as an index to the BITable. For out-of-bounds references that are not detected in this case, the corrupted index value would need to reference a valid BIEntry in the BITable, and the pointer value bits (or address bits) of the pointer would need to correspond to a valid address within the bounds of the BIEntry. While the likelihood of this occurring may be low, the pointer can be modified to reduce the likelihood of this occurring or to avoid it altogether. To this end, pointer 2300 includes guard bits 2310 (e.g., bits 41 and 40) that facilitate a guard band between index bits 2320 (e.g., bits 42 to 63) and address bits 2330 (e.g., bits 0 to 39). When a "moderately sized" offset is added to or subtracted from the address, protection bit 2310 can protect index bit 2320, as shown below. Figures 24-25 To be discussed in more detail.
[0117] Figure 24 An example non-limiting pointer 2400 is shown according to one or more embodiments described herein. Figure 24 As shown, pointer 2400 includes index bit 2420, address bit 2430, and protection bit 2440 inserted between index bit 2420 and address bit 2430. Figure 24 In the middle, the protection bit includes the binary value "10" read from left to right. Add a moderately sized offset (e.g., <2) to pointer 2400. 40 This can result in a carry that flips the lower bit of guard bit 2440 (e.g., bit 40) from binary value "0" to binary value "1", but it will not overflow into index bit 2420 and corrupt that index bit. Furthermore, subtracting a moderate offset from pointer 2400 can result in a borrow that flips bit 41 of guard bit 2440 from binary value "1" to binary value "0", but it will not overflow into index bit 2420 and corrupt that index bit.
[0118] For example, such as Figure 25As shown, a negative value of binary value "1" can be added to the pointer value 2400 (or binary value "1" can be subtracted from the pointer value 2400). Adding a negative value of binary value "1" in the high bit (e.g., bit 41) of the guard bit 2440 can cause a carry, which effectively zeros the binary value "1" to the left of bit 41 in the 64-bit representation of -1. In this way, the bits to the left of bit 41 in the sum will equal those bits in the original address represented by the pointer 2400. The above-discussed index bit corruption mitigation techniques facilitate application or user programs using >1 terabyte (TB) of address space and tracking bound information for >4 million arrays. The techniques do so while preventing out-of-bounds array references and eliminating or mitigating "index corruption" in pointer arithmetic associated with modest-sized offsets (e.g., <2 40 ). Figure 24 Figures 23-25 The above-discussed index bit corruption mitigation techniques facilitate application or user programs using >1 terabyte (TB) of address space and tracking bound information for >4 million arrays. The techniques do so while preventing out-of-bounds array references and eliminating or mitigating "index corruption" in pointer arithmetic associated with modest-sized offsets (e.g., <2 40 ).
[0119] Figure 26 A flow diagram illustrating an example non-limiting computer-implemented method 2600 that facilitates hardware-based memory error mitigation for heap objects in accordance with one or more embodiments described herein is shown. Repetitive description of like elements employed in other embodiments described herein is omitted for sake of brevity.
[0120] At 2602, the computer-implemented method 2600 can include allocating an entry in a table to store bound information using a processor (e.g., with the entry component 240) when an object is allocated in memory. At 2604, the computer-implemented method 2600 can include reusing unused bits of an object address to store an index to a table entry using a processor (e.g., with the reuse component 250).
[0121] In embodiments, the computer-implemented method 2600 can further include performing a bound check in hardware for load and store instructions by using the index bits in an address to access the bound information using a processor (e.g., with the check component 260). In embodiments, the computer-implemented method 2600 can further include automatically propagating the index when a subsequent object address is derived via an assignment statement or pointer arithmetic using a processor (e.g., with the propagation component 270). In embodiments, the computer-implemented method 2600 can further include checking array bounds using a processor. In embodiments, the computer-implemented method can further include determining whether an array reference is in bounds or out-of-bounds using a processor. In embodiments, the computer-implemented method 2600 can further include mitigating the occurrence of out-of-bounds array references using a processor.
[0122] In embodiments, the computer-implemented method 2600 can further include employing, using the processor, unused bits in the object address to check a range of memory addresses that can be accessed. In embodiments, the computer-implemented method 2600 can further include propagating, using the processor, extra information in the unused bits when the object address is copied in an assignment statement. In embodiments, the computer-implemented method 2600 can further include propagating, using the processor, extra information in the unused bits when the object address is passed as an argument in a function call. In embodiments, the computer-implemented method 2600 can further include propagating, using the processor, extra information in the unused bits when the object address is used in a computation of an address.
[0123] Although the foregoing discussion has focused on preventing erroneous memory references to heap objects, the mechanisms discussed can also be applied to other types of objects, including global objects and objects allocated on the stack. Global objects can be protected by allocating a BIEntry in the BITable at program startup for each global object in the program. Stack objects can also be protected. One way to do this involves an additional pre-processing step that pre-processes the source language files (e.g., C or C++ files) that comprise the program. Pre-processing of the source language files can involve static analysis that determines, for each function in the file, whether the function can directly or indirectly recursively call itself. If the function does not recursively call itself, the pre-processor can edit the function to convert the declarations of the automatic objects in the function to static objects. Then, at program startup, BIEntries can be allocated for these static objects in a manner similar to the allocation of BIEntries for global objects as described above. Objects in functions that can be recursively called can be handled differently. In this case, another processing step can edit the prolog and epilog of the function to include code that allocates and deallocates a BIEntry for each object in the function. Alternatively, all recursive and non-recursive functions can be handled in the same manner by editing the prolog and epilog of each function to include code that allocates and deallocates the appropriate BIEntry.
[0124] When a pointer is defined, the use of uninitialized pointers can also be prevented by assigning a NULL value (i.e., 0) to the pointer. This will protect the program from defects in which "garbage" in an uninitialized pointer is used to read or write memory.
[0125] It is worth mentioning that a program can be built to include or not include the protection mechanisms that have been described. With the appropriate "make" tags, a program can be built without the protection mechanisms (if desired) and without any performance penalty.
[0126] To provide context for the various aspects of the disclosed subject matter,Figure 27 The following discussion is intended to provide a brief description of a suitable environment in which various aspects of the disclosed subject matter can be implemented. It is not intended to be used as an exhaustive description of all possible environments in which the disclosed subject matter can be implemented. Figure 27 A suitable operating environment 2700 for implementing various aspects of the present disclosure is also shown. The computer 2712 can also include a processing unit 2714, a system memory 2716, and a system bus 2718. The system bus 2718 couples system components including, but not limited to, the system memory 2716 to the processing unit 2714. The processing unit 2714 can be any of various available processors. Dual microprocessors and other multiprocessor architectures also can be employed as the processing unit 2714. The system bus 2718 can be any of several types of bus structures including a memory bus or memory controller, a peripheral bus or external bus, and / or a local bus using any of a variety of bus architectures including, but not limited to, Industry Standard Architecture (ISA), Micro Channel Architecture (MSA), Extended ISA (EISA), Intelligent Drive Electronics (IDE), VESA Local Bus (VLB), Peripheral Component Interconnect (PCI), Card Bus, Universal Serial Bus (USB), Advanced Graphics Port (AGP), Firewire (IEEE 1094), and Small Computer Systems Interface (SCSI). The system memory 2716 can also include volatile memory 2720 and nonvolatile memory 2722. The basic input / output system (BIOS), containing the basic routines to transfer information between elements within the computer 2712, such as during start-up, is stored in nonvolatile memory 2722. By way of illustration, and not limitation, nonvolatile memory 2722 can include read only memory (ROM), programmable ROM (PROM), electrically programmable ROM (EPROM), electrically erasable programmable ROM (EEPROM), flash memory, or nonvolatile random access memory (RAM) (e.g., ferroelectric RAM (FeRAM)). Volatile memory 2720 can also include random access memory (RAM), which acts as external cache memory. By way of illustration and not limitation, RAM is available in many forms such as static RAM (SRAM), dynamic RAM (DRAM), synchronous DRAM (SDRAM), double data rate SDRAM (DDR SDRAM), enhanced SDRAM (ESDRAM), Synchlink DRAM (SLDRAM), direct Rambus DRAM (DRDRAM), and
[0127] The computer 2712 can also include removable / non-removable, volatile / non-volatile computer storage media. FIG. 27 illustrates, for example a disk storage 2724. Disk storage 2724 can also include, but is not limited to, devices like a magnetic disk drive, floppy disk drive, tape drive, Jaz drive, Zip drive, LS-100 drive, flash memory card, or memory stick. Furthermore, disk storage 2724 can include storage media separately or in combination with other storage media including, but not limited to, an optical disk drive such as a compact disk ROM device (CD-ROM), CD recordable drive (CD-R drive), CD-RW drive, a Blu-ray device, a DVD optical drive, relayed-writable (DVD-RW), digital video Figure 27A disk storage 2724 is also shown. The disk storage 2724 can also include, without limitation, devices such as a magnetic disk drive, a soft disk drive, a tape drive, a Jaz drive, a Zip drive, an LS-100 drive, a flash memory card, or a Figure 27 Software is also depicted as being used as an intermediary between the user and the basic computer resources described in the suitable operating environment 2700. Such software can also include, for example, an operating system 2728. The operating system 2728, which can be stored on disk storage 2724, acts to control and allocate resources of the computer 2712. System applications 2730 take advantage of the management of the resources by the operating system 2728 through program modules 2732 and program data 2734, e.g., stored either in the system memory 2716 or the disk storage 2724. It is to be appreciated that this disclosure can be implemented with various operating systems or combinations of operating systems. A user enters commands or information into the computer 2712 through input device(s) 2736. Input devices 2736 include, but are not limited to, a pointing device such as a mouse, trackball, stylus, touch pad, keyboard, microphone, joystick, game pad, satellite dish, scanner, TV tuner card, digital camera, digital video camera, web camera, and the like. These and other input devices connect to the processing unit 2714 through the system bus 2718 via interface port(s) 2738. Interface port(s) 2738 include, for example, a serial port, a parallel port, a game port, and a universal serial bus (USB). Output device(s) 2740 use some of the same type of ports as input device(s) 2736. Thus, for example, a USB port can be used to provide input to computer 2712, and to output information from computer 2712 to an output device 2740. Output adapter 2742 is provided to illustrate that there are some output devices 2740 like monitors, speakers, and printers, among other output devices 2740, that require special adapters. The output adapters 2742 include, by way of illustration and not limitation, video and sound cards that provide a means of connection between the output device 2740 and the system bus 2718. It can be noted that other devices and / or systems of devices provide both input and output capabilities such as remote computer(s) 2744.
[0128] The computer 2712 can operate in a networked environment using logical connections to one or more remote computers, such as a remote computer(s) 2744. The remote computer(s) 2744 can be a computer, a server, a router, a network PC, a workstation, a microprocessor-based appliance, a peer device, or other common network node, and typically includes many of the elements described relative to the computer 2712, although, for purposes of brevity, not all of them are
[0129] The present application can be a system, a method, and / or a computer program product at any possible technical detail of integration. The computer program product can include a computer readable storage medium (or media) having computer readable program instructions thereon for causing a processor to carry out aspects of the present application. The computer readable storage medium can be a tangible device that can retain and store instructions for use by an instruction execution device. The computer readable storage medium can be, for example, but is not limited to, an electronic storage device, a magnetic storage device, an optical storage device, an electromagnetic storage device, a semiconductor storage device, or any suitable combination of the foregoing. A non-exhaustive list of more specific examples of the computer readable storage medium can also include the following: a portable computer diskette, a hard disk, a random access memory (RAM), a read-only memory (ROM), an erasable programmable read-only memory (EPROM or Flash memory), a static random access memory (SRAM), a portable compact disc read-only memory (CD-ROM), a digital versatile disk (DVD), a memory stick, a floppy disk, a mechanically encoded device such as punch-cards or raised structures in a groove having instructions recorded thereon, and any suitable combination of the foregoing. A computer readable storage medium, as used herein, is not to be construed as being transitory signals per se, such as radio waves or other freely propagating electromagnetic waves, electromagnetic waves propagating through a waveguide or other transmission media (e.g., light pulses passing through a fiber-optic cable), or electrical signals transmitted through a wire.
[0130] The computer readable program instructions described herein can be downloaded to respective computing / processing devices from a computer readable storage medium or to external computers or external storage devices from a network, including the Internet, a local area network, a wide area network and / or a wireless network. The network can comprise copper transmission cables, optical transmission fibers, wireless transmission, routers, firewalls, switches, gateway computers and / or edge servers. A network adapter card or network interface in each computing / processing device receives computer readable program instructions from the network and forwards the computer readable program instructions to storage media within the respective computing / processing device for execution by a processor. The computer readable program instructions for carrying out operations of the present application can be assembler instructions, instruction-set-architecture (ISA) instructions, machine instructions, machine dependent instructions, microcode, firmware instructions, state-setting data, configuration data for integrated circuitry, or either source code or object code written in any combination of one or more programming languages, including an object oriented programming language such as Smalltalk, C++ or the like, and a procedural programming language such as the "C" programming language or similar programming languages. The computer readable program instructions can execute entirely on the user's computer, partly on the user's computer, as a stand-alone software package, partly on the user's computer and partly on a remote computer or entirely on the remote computer or server. In the latter scenario, the remote computer can be connected to the user's computer through any type of network, including a local area network (LAN) or a wide area network (WAN), or the connection can be made to an external computer (for example, through the Internet using an Internet Service Provider). In some embodiments, electronic circuitry including, for example, programmable logic circuitry, field-programmable gate arrays (FPGA), or programmable logic arrays (PLA) can execute the computer readable program instructions by utilizing state information of the computer readable program instructions to personalize the electronic circuitry, in order to perform aspects of the present application.
[0131] The computer readable program instructions can also be loaded onto a computer, other programmable data processing apparatus, or other device to cause a series of operational steps to be performed on the computer, other programmable apparatus or other device to produce a computer implemented process, such that the instructions which execute on the computer, other programmable apparatus, or other device implement the functions / acts specified in the flowchart and / or block diagram block or blocks.
[0132] The flow diagrams and block diagrams in the drawings are illustrative of the possible architectures, functional operations and acts enabled by the various embodiments of the present application. In this regard, each block in the flow diagrams and / or block diagrams can represent a module, segment, or portion of instructions, which includes one or more executable instructions for implementing the specified logical function(s). In some alternative implementations, the functions noted in the blocks can occur out of the order noted in the figures. For example, two blocks shown in succession may, in fact, be executed substantially concurrently, or the blocks can sometimes be executed in the reverse order, depending upon the functionality involved. It will also be noted that each block of the block diagrams and / or flowchart illustrations, and combinations thereof, can be implemented by a dedicated hardware-based system that performs the specified functions or acts, or combinations of special-purpose hardware and computer instructions.
[0133] While the subject matter has been described above in the general context of computer-executable instructions of a computer program product that runs on one and / or more computers, those skilled in the art will recognize that the disclosure also can be implemented in combination with other program modules. Generally, program modules include routines, programs, components, data structures, etc. that perform particular tasks and / or implement particular abstract data types. Moreover, those skilled in the art will appreciate that the inventive computer-implemented methods can be practiced with other computer system configurations, including single-processor or multiprocessor computer systems, minicomputers, mainframe computers, as well as computers, hand-held computing devices (e.g., PDA, phone), microprocessor-based or programmable consumer or industrial electronics, and the like. The illustrated aspects can also be practiced in distributed computing environments where tasks are performed by remote processing devices that are linked through a communications network. However, if not all aspects are implemented in a distributed computing environment, some aspects can be practiced on stand-alone computers. In a distributed computing environment, program modules can be located in both local and remote memory storage devices. For example, in one or more embodiments, computer-executable components can be executed from memory that can include or consist of one or more distributed memory units. As used herein, the terms “memory” and “memory unit” are interchangeable. Moreover, one or more embodiments described herein can execute code of computer-executable components in a distributed manner, e.g., multiple processors combine or work in concert to execute code from one or more distributed memory units. As used herein, the term “memory” can encompass a single memory or memory unit at one location or multiple memories or memory units at one or more locations.
[0134] As used in this application, the terms “component,” “system,” “platform,” “interface,” and the like can refer to and / or can include a computer-related entity or an entity that is related to an operational machine with one or more specific functionalities. The entities disclosed herein can be either hardware, a combination of hardware and software, software, or software in execution. For example, a component can be, but is not limited to being, a process running on a processor, a processor, an object, an executable, a thread of execution, a program, and / or a computer. By way of illustration, both an application running on a server and the server can be a component. One or more components can reside within a process and / or thread of execution and a component can be localized, co-resident, and / or distributed amongst one computer and / or across multiple computers. In another example, a component can be a virtual machine executing in a cloud computing system.
[0135] Also, the term “or” is intended to mean an inclusive “or” rather than an exclusive “or.” That is, unless specified otherwise, or clear from context, “X employs A or B” is intended to mean any of the natural inclusive permutations. That is, if X employs A; X employs B; or X employs both A and B, then “X employs A or B” is satisfied under any of the foregoing instances. Moreover, articles “a” and “an” as used in the subject specification and annexed drawings should generally be construed to mean “one or more” unless specified otherwise or clear from context to be directed to a singular form. As used herein, the term “example” and / or “exemplary” are utilized to mean serving as an example, instance, or illustration. For the avoidance of doubt, the subject matter disclosed herein is not limited by such examples. In addition, any aspect or design described herein as “example” and / or “exemplary” is not necessarily to be construed as preferred or advantageous over other aspects or designs, nor is it meant to exclude equivalents of an example structure and / or technology known to those of ordinary skill in the art.
[0136] As employed in this specification, the term "processor" can refer to substantially any computing processing unit or device comprising single-core processors; single-processors with software multithread execution capability; multi- core processors; multi-core processors with software multithread execution capability; multi-core processors with hardware multithread technology; parallel platforms; and parallel platforms with distributed shared memory. Additionally, a processor can refer to an integrated circuit, an application specific integrated circuit (ASIC), a digital signal processor (DSP), a field programmable gate array (FPGA), a programmable logic controller (PLC), a complex programmable logic device (CPLD), a discrete gate or transistor logic, discrete hardware components, or any combination thereof designed to perform the functions described herein. Further, a processor can employ nano- scale architectures such as, but not limited to, molecular and quantum-dot based transistors, switches and gates, in order to optimize space usage or enhance performance of user equipment. A processor can also be implemented as a combination of computing processing units. In this disclosure, terms such as "store," "storage," "data store," data storage," "database," and substantially any other information storage component relevant to operation and functionality of a component are utilized to refer to "memory components," entities embodied in a "memory," or components comprising a memory. It is to be appreciated that memory and / or memory components described herein can be volatile memory or nonvolatile memory, or can include both volatile and nonvolatile memory. By way of illustration, and not limitation, nonvolatile memory can include read only memory (ROM), programmable ROM (PROM), electrically programmable ROM (EPROM), electrically erasable ROM (EEPROM), flash memory, or nonvolatile random access memory (RAM) (e.g., ferroelectric RAM (FeRAM)). Volatile memory can include, for example, RAM that can be utilized as external cache memory. By way of illustration and not limitation, RAM can be available in many forms such as synchronous RAM (SRAM), dynamic RAM (DRAM), synchronous DRAM (SDRAM), double data rate SDRAM (DDR SDRAM), enhanced SDRAM (ESDRAM), Synchlink DRAM (SLDRAM), direct Rambus RAM (DRRAM), and Rambus dynamic RAM (RDRAM).
[0137] The above description includes only examples of systems and computer-implemented methods. Of course, it is not possible to describe every conceivable combination of components or computer-implemented methods for describing the disclosure, but one of ordinary skill in the art can recognize that many further combinations and permutations of the disclosure are possible. Moreover, as used in the specific embodiments, claims, appendices, and drawings, the terms "comprise," "have," "possess," and the like are to be construed as being inclusive and not exclusive.
[0138] The description of the various embodiments has been presented for purposes of illustration, but is not intended to be exhaustive or limited to the embodiments disclosed. Many modifications and variations will be apparent to those of ordinary skill in the art without departing from the scope and spirit of the described embodiments. The terminology used herein was chosen to best explain the principles of the embodiments, the practical application or technical improvement over technologies found in the marketplace, or to enable others skilled in the art to understand the embodiments disclosed herein.
Claims
1. A computer system comprising: a processor that executes the following computer-executable components stored in a computer storage device: an entry component that generates an entry in a table, wherein the entry includes bound information for an object allocated in memory of the storage device; a reuse component that reuses unused bits of an object pointer that specifies an address of an object and stores an index into the entry in the table to the unused bits; and an inspection component that intercepts an instruction that contains the object pointer and performs a bound check in hardware on load and store instructions by extracting the index from the unused bits in the object pointer to access the bound information and comparing to the address.
2. The system of claim 1, further comprising: a propagation component that automatically propagates the index when a subsequent address is derived via an assignment statement or pointer arithmetic.
3. The system of claim 1, wherein, The inspection component checks array bounds.
4. The system of claim 1, wherein, The inspection component determines whether an array reference is in bounds or out of bounds and mitigates occurrences of out of bounds array references.
5. The system of claim 1, wherein, The reuse component tracks a range of memory addresses that can be accessed using the unused bits in the object pointer.
6. The system of claim 2, wherein, The propagation component propagates additional information in the unused bits when the object pointer is copied in an assignment statement.
7. The system of claim 2, wherein, The propagation component propagates additional information in the unused bits when the object pointer is passed as an argument in a function call.
8. The system of claim 2, wherein, The propagation component propagates additional information in the unused bits when the object pointer is used to compute another address.
9. The system of claim 1, wherein, A guard bit is between the index bits stored by the unused bits and the address bits specified by the object pointer.
10. The system of claim 1, wherein, The entry component manages the bound information stored in the table via modifications to a memory allocation function or deallocation library function.
11. The system of claim 1, wherein, A subset of the bound information is stored in an overflow table when a number of active objects, or a number of index bits required to support the number of active objects, exceeds a number of index bits that have been allocated.
12. The system of claim 11, wherein, The inspection component performs a bound check in hardware on load and store instructions by using the address to access the bound information within the subset of the bound information when the address contains index bits that include a value that indicates the overflow table.
13. A computer-implemented method comprising: generating, using a processor, an entry in a table to store bound information for an allocated object in memory of a storage device when the object is allocated in the memory; reusing, using the processor, unused bits of an object pointer that specifies an address of an object and storing an index into the entry in the table to the unused bits; and intercepting, using the processor, an instruction that contains the object pointer and performing a bound check in hardware on load and store instructions by extracting the index from the unused bits in the object pointer to access the bound information and comparing to the address.
14. The method of claim 13, further comprising: automatically propagating, using the processor, the index when a subsequent object address is derived via an assignment statement or pointer arithmetic.
15. The method of claim 13, further comprising: checking, using the processor, array bounds.
16. The method of claim 13, further comprising: determining, using the processor, whether an array reference is in bounds or out of bounds.
17. The method of claim 16, further comprising: mitigating, using the processor, occurrences of out of bounds array references.
18. The method of claim 13, further comprising: using the processor to track a range of memory addresses that can be accessed using the unused bits in the object pointer.
19. The method of claim 13, further comprising: using the processor to propagate additional information in the unused bits when the object pointer is copied in an assignment statement.
20. The method of claim 13, further comprising: using the processor to propagate additional information in the unused bits when the object pointer is passed as an argument in a function call.
21. The method of claim 13, further comprising: using the processor to propagate additional information in the unused bits when the object pointer is used to compute another address.
22. A computer program product comprising computer program instructions executable by a processor to cause the processor to perform the method of any one of claims 13-21.
Citation Information
Patent Citations
A photovoltaic module level monitoring system
EP3584946A1
File Aggregation in a Switched File System
US20090077097A1
Unbounded transactional memory system and method
US20110167222A1
Hard Object: Lightweight Hardware Enforcement of Encapsulation, Unforgeability, and Transactionality
US20140283040A1