Practical Byte-Granular Memory Blacklisting using Califorms
Hiroshi Sasaki

Miguel A. Arroyo

M. Tarek Ibn Ziad

Columbia University
sasaki@cs.columbia.edu

Columbia University
miguel@cs.columbia.edu

Columbia University
mtarek@cs.columbia.edu

Koustubha Bhat†

Kanad Sinha

Simha Sethumadhavan

Vrije Universiteit Amsterdamk.bhat@vu.nl

Columbia University
kanad@cs.columbia.edu

Columbia University
simha@cs.columbia.edu

ABSTRACT
Recent rapid strides in memory safety tools and hardware have improved software quality and security. While coarse-grained memory
safety has improved, achieving memory safety at the granularity
of individual objects remains a challenge due to high performance
overheads usually between ∼1.7x−2.2x. In this paper, we present a
novel idea called Califorms, and associated program observations, toobtain a low overhead security solution for practical, byte-granularmemory safety.
The idea we build on is called memory blacklisting, which prohibits a program from accessing certain memory regions based onprogram semantics. State of the art hardware-supported memory
blacklisting, while much faster than software blacklisting, creates
memory fragmentation (on the order of few bytes) for each use of
the blacklisted location. We observe that metadata used for blacklisting can be stored in dead spaces in a program’s data memory
and that this metadata can be integrated into the microarchitecture
by changing the cache line format. Using these observations, a Califorms based system proposed in this paper reduces the performance
overheads of memory safety to ∼1.02x−1.16x while providing bytegranular protection and maintaining very low hardware overheads.
Moreover, the fundamental idea of storing metadata in empty spaces
and changing cache line formats can be used for other security andperformance applications.

CCS CONCEPTS• Security and privacy → Security in hardware; • Computer
systems organization → Architectures.

KEYWORDS
memory safety, memory blacklisting, caches
ACM Reference Format:
Hiroshi Sasaki, Miguel A. Arroyo, M. Tarek Ibn Ziad, Koustubha Bhat† ,Kanad Sinha, and Simha Sethumadhavan. 2019. Practical Byte-Granular† Part of this work was carried out while the author was a visiting student at Columbia

University.
Permission to make digital or hard copies of all or part of this work for personal orclassroom use is granted without fee provided that copies are not made or distributedfor profit or commercial advantage and that copies bear this notice and the full citationon the first page. Copyrights for components of this work owned by others than ACM
must be honored. Abstracting with credit is permitted. To copy otherwise, or republish,
to post on servers or to redistribute to lists, requires prior specific permission and/or afee. Request permissions from permissions@acm.org.
MICRO-52, October 12–16, 2019, Columbus, OH, USA© 2019 Association for Computing Machinery.
ACM ISBN 978-1-4503-6938-1/19/10. . . $15.00
https://doi.org/10.1145/3352460.3358299

Memory Blacklisting using Califorms. In The 52nd Annual IEEE/ACM International Symposium on Microarchitecture (MICRO-52), October 12–16,
2019, Columbus, OH, USA. ACM, New York, NY, USA, 14 pages. https://doi.org/10.1145/3352460.3358299

1

INTRODUCTION

Historically, program memory safety violations have provided asignificant opportunity for exploitation by attackers: for instance,
Microsoft recently revealed that the root cause of more than half ofall exploits are software memory safety violations [30]. To address
this threat, software checking tools such as AddressSanitizer [25]and commercial hardware support for memory safety such as Oracle’s ADI [21] and Intel’s MPX [20] have enabled programmers todetect and fix memory safety violations before deploying software.
Current software and hardware-supported solutions excel atproviding coarse-grained, inter-object memory safety which involves detecting memory access beyond arrays and heap allocatedregions (malloc’d struct and class instances). However, they are notsuitable for fine-grained memory safety (i.e., intra-object memory
safety—detecting overflows within objects, such as fields withina struct, or members within a class) due to the high performance
overheads and/or need for making intrusive changes to the sourcecode [29]. Some real-world scenarios where intra-object memory safety problems manifest are type confusion vulnerabilities(e.g., CVE–2017–5115 [2]) and uninitialized data leaks throughpadding bytes (e.g., CVE–2014–1444 [1]), both recognized as highimpact security classes [13, 16].
For instance, a recent work that aims to provide intra-object
overflow protection functionality incurs a 2.2x performance overhead [10]. These overheads are problematic because they not only
reduce the number of pre-deployment tests that can be performed,
but also impede post-deployment continuous monitoring, which
researchers have pointed out is necessary for detecting benign andmalicious memory safety violations [26]. Thus, a low overhead
memory safety solution that can enable continuous monitoring andprovide complete program safety has been elusive.
The source of overheads stem from how current designs store
and use metadata necessary for enforcing memory safety. In IntelMPX [20], Hardbound [8], CHERI [31, 32], and PUMP [9], the metadata is stored for each pointer; each data or code memory accessthrough a pointer performs checks using the metadata. Since C/C++
memory accesses tend to be highly pointer based, the performanceand energy overheads of accessing metadata can be significant insuch systems. Furthermore, the management of metadata, especially if it is stored in a disjoint manner from the pointer, can also
create significant engineering complexity in terms of performanceMICRO-52, October 12–16, 2019, Columbus, OH, USA

H. Sasaki, M. Arroyo, M. Tarek Ibn Ziad, K. Bhat, K. Sinha, and S. Sethumadhavan

L2 CacheDead Byte

L1D Cache

When dead bytes are present,
cache lines are califormed

Buﬀer_BColor
B TagsTripwire

Begin
Buﬀer

✘
Natural
0xF

0x0

Califorms
0x0

0xD

Header

0xF 0x0 0x0 0xD

NaturalNatural0x0 0xD 0x1 0x5 0xE 0xA 0x5 0xE

0x0 0xD 0x1 0x5 0xE 0xA 0x5 0xE

When dead bytes are not present,
cache lines are preserved

Figure 1: Califorms offers memory safety by detecting accesses to dead bytes in memory. Dead bytes are not stored beyond the L1 data cache and identified using a special header
in the L2 cache (and beyond) resulting in very low overhead.
The conversion between these formats happens when lines
are filled or spilled between the L1 and L2 caches. The absence of dead bytes results in the cache lines stored in thesame natural format across the memory system.

and usability. This was evidenced by the fact that compilers like
LLVM and GCC dropped support for Intel MPX in their mainline
after an initial push to integrate it into the toolchain [20].
Our approach for reducing overheads is two-fold. First, insteadof checking access bounds for each pointer access, we blacklist
all memory locations that should never be accessed. This reduces
the additional work for memory safety such as comparing bounds.
Second, we propose a novel metadata storage scheme for storing
blacklisted information. We observe that by using dead memory
spaces in the program, we can store metadata needed for memory safety for free for nearly half of the program objects. These
dead spaces can occur for several reasons including language alignment requirements. When we cannot find naturally occurring deadspaces, we manually insert them. The overhead due to this deadspace is smaller than traditional methods for storing metadata because of how we represent the metadata: our metadata is smaller(one byte) as opposed to multiple bytes with traditional whitelistingor blacklisting memory safety techniques.
A natural question is how the dead (more commonly referred
to as padding) bytes can be distinguished from normal bytes inmemory. A straightforward scheme results in one bit of additional
storage per byte to identify if a byte is a dead byte; this scheme
results in a space overhead of 12.5%. We reduce this overhead toone bit per 64B cache line (0.2% overhead) without any loss of
precision by only reformatting how data is stored in cache lines.
Our technique, Califorms, uses one bit of additional storage to
identify if the cache line associated with the memory contains any
dead bytes. For califormed cache lines, i.e., lines which containdead bytes, the actual data is stored following the “header”, whichindicates the location of dead bytes, as shown in Figure 1.
With this support, it is easy to describe how a Califorms based
system for memory safety works. Dead bytes, either naturally harvested or manually inserted, are used to indicate memory regionsthat should never be accessed by a program (i.e., blacklisting). If an
attacker accesses these regions, we detect this rogue access without
any additional metadata accesses as our metadata resides inline.

Buﬀer_A

✘
End

✔

✔

Pointer
Begin
End

A

Buﬀer

✘
✔

Pointer A

Tripwire
Pointer(a) Disjoint metadata (b) Cojoined metadata (c) Inlined metadata
whitelisting.
whitelisting.
blacklisting.

Figure 2: Three main classes of hardware solutions for memory safety.
In theory, perfect blacklisting is a strictly weaker form of security than perfect whitelisting, but blacklisting is a more practicalalternative because of its ease of deployment and low overheads.
Informally, whitelisting techniques are applied partially to reduce
overheads and maintain backward compatibility which reduces
their security, while blacklisting techniques can be applied more
broadly and thus offer more coverage due to their low overheads.
Additionally, blacklisting techniques complement defenses in existing systems better since they do not require intrusive changes.
Our experimental results on the SPEC CPU2006 benchmark suiteindicate that the overheads of Califorms are quite low: software
overheads range from 2 to 14% slowdown (or alternatively, 1.02x
to 1.16x performance overhead) depending on the amount andlocation of padding bytes used. Varying the number of padding
bytes provides functionality for the user/customer to tune the security according to their performance requirements. Hardware
induced overheads are also negligible, on average less than 1%. Allof the software transformations are performed using the LLVM
compiler framework using a front-end source-to-source transformation. These overheads are substantially lower compared to thestate-of-the-art software or hardware supported schemes (viz., 2.2x
performance and 1.1x memory overheads for EffectiveSan [10], and1.7x performance and 2.1x memory overheads for Intel MPX [20]).

2

BACKGROUND

Hardware support for memory safety can be broadly categorized
into the following three classes as presented in Figure 2.
Disjoint Metadata Whitelisting. This class of techniques, also
called base and bounds, attaches bounds metadata with every
pointer, bounding the region of memory they can legitimately
dereference (see Figure 2(a)). Hardbound [8], proposed in 2008,
provides spatial memory safety using this mechanism. IntelMPX [20], productized in 2016, is similar and introduces an explicit
architectural interface (registers and instructions) for managing
bounds information. Temporal memory safety was introduced tothis scheme by storing an additional “version” information alongwith the pointer metadata and verifying that no stale versions are
ever retrieved [18, 19]. BOGO [33] adds temporal memory safety to
MPX by invalidating all pointers to freed regions in MPX’s lookup
table. Introduced about 35 years ago in commercial chips likeIntel 432 and IBM System/38, CHERI [32] revived capability basedPractical Byte-Granular Memory Blacklisting using Califorms

architectures with similar bounds-checking guarantees, in addition
to having other metadata fields (e.g., permissions).1 PUMP [9],on the other hand, is a general-purpose framework for metadata
propagation, and can be used for propagating pointer bounds.
One advantage of per pointer metadata stored separately fromthe pointer in a shadow memory region is that it allows compatibility with codes that use legacy pointer layouts. Typically, metadatastorage overhead scales according to the number of pointers inprinciple but implementations generally reserve a fixed chunk ofmemory for easy lookup. Owing to this disjoint nature, metadata access requires additional memory operations, which some proposals
seek to minimize with caching and other optimizations. Regardless, disjoint metadata introduces atomicity concerns potentiallyresulting in false positives and negatives or complicating coherence
designs at the least (e.g., MPX is not thread-safe). Explicit specification of bounds per pointer also allows bounds-narrowing inprinciple, wherein pointer bounds can be tailored to protect individual elements in a composite memory object. However, commercial
compilers do not support this feature for MPX due to the complexityof compiler analyses required. Furthermore, compatibility issues
with untreated modules (e.g., unprotected libraries) also introduces
real-world deployability concerns for these techniques. For instance
MPX drops its bounds when protected pointers are modified byunprotected modules, while CHERI does not support it at all. MPX
additionally makes bounds checking explicit, thus introducing amarginal computational overhead to bounds management as well.
Cojoined Metadata Whitelisting. Originally introduced in the
IBM System/370 mainframes, this mechanism assigns a “color” tomemory chunks when they are allocated, and the same color to thepointer used to access that region. The runtime check for accessvalidity simply consists of comparing the colors of the pointer andaccessed memory (see Figure 2(b)).
This technique is currently commercially deployed by Oracle
as ADI [21],2 which uses higher order bits in pointers to store thecolor. In ADI, color information associated with memory is stored
in dedicated per line metadata bits while in cache and in extra ECC
bits while in memory [26]. The use of ECC bits creates a restriction
on the number of colors, however, if the colors can fit into ECC,
metadata storage does not occupy any additional memory in the
program’s address space.3 Additionally, since metadata bits are
acquired along with concomitant data, extra memory operations
are obviated. For the same reason, it is also compatible with unprotected modules since the checks are implicit as well. Temporal
safety is achieved by assigning a different color when memory
regions are reused. However, intra-object protection or boundsnarrowing is not supported as there is no means for “overlapping”
colors. Furthermore, protection is also dependent on the number of
metadata bits employed, since it determines the number of colors
that can be assigned. So, while color reuse allows ADI to scale andlimit metadata storage overhead, it can also be exploited by this1 A recent version of CHERI [31], however, manages to compress metadata to 128 bits

and changes pointer layout to store it with the pointer value (i.e., implementing baseand bounds as cojoined metadata whitelisting), accordingly introducing instructions
to manipulate them specifically.
2 ARM has a similar upcoming Memory Tagging feature [3], whose implementation
details are unclear, as of this work.
3 However, when a memory is swapped color bits are copied into memory by the OS.

MICRO-52, October 12–16, 2019, Columbus, OH, USA

vector. Another disadvantage of this technique, specifically due toinlining metadata in pointers, is that it only supports 64-bit architectures. Narrower pointers would not have enough spare bits toaccommodate color information.
Inlined Metadata Blacklisting. Another line of work, also referred to as tripwires, aims to detect overflows by simply blacklisting a patch of memory on either side of a buffer, and flagging
accesses to this patch (see Figure 2(c)). This is very similar to contemporary canary design [6], but there are a few critical differences.
First, canaries only detect overwrites, not overreads. Second, hardware tripwires trigger instantaneously, whereas canaries need tobe periodically checked for integrity, providing a period of attack
to time of use window. Finally, unlike hardware tripwires, canaryvalues can be leaked or tampered, and thus mimicked.
SafeMem [23] implements tripwires by repurposing ECC bits inmemory to mark memory regions invalid, thus trading off reliability
for security. On processors supporting speculative execution, however, it might be possible to speculatively fetch blacklisted lines into
the cache without triggering a faulty memory exception. Unlessthese lines are flushed immediately after, SafeMem’s blacklisting
feature can be trivially bypassed. Alternatively, REST [28] achieves
the same by storing a predetermined large random number, in theform of a 8–64B token, in the memory to be blacklisted. Violations
are detected by comparing cache lines with the token when they arefetched. REST provides temporal memory safety by quarantining
freed memory, and not reusing them for subsequent allocations.
Compatibility with unprotected modules is easily achieved as well,since tokens are part of the program’s address space and all accessare implicitly checked. However, intra-object safety is not supported
by REST owing to fragmentation overhead such heavy usage of
tokens would entail.
Since Califorms operates on the principle of detecting memory
accesses to dead bytes, which are in turn stored along with program
data, it belongs to the inlined metadata class of defenses. However,
it is different from other works in the class in one key aspect—granularity. While both REST and SafeMem naturally blacklist at
the cache line granularity, Califorms can do so at the byte granularity. It is this property that enables us to provide intra-object safetywith negligible performance and memory overheads, unlike previous work in the area. For inter-object spatial safety and temporal
safety, we employ the same design principles as REST. Hence, oursafety guarantees are a strict superset of those provided by previous
schemes in this class (spatial memory safety by blacklisting andtemporal memory safety by quarantining).

3

MOTIVATION

One of the key ways in which we mitigate the overheads for finegrained memory safety is by opportunistically harvesting padding
bytes in programs to store metadata. So how often do these occur
in programs? Before we answer the question let us concretely understand padding bytes with an example. Consider the struct A
defined in Listing 1(a). Let us say the compiler inserts a three-byte
padding in between char c and int i as in Listing 1(b) because of
the C language requirement that integers should be padded to theirnatural size (which we assume to be four bytes here). These typesof paddings are not limited to C/C++ but also required by many

MICRO-52, October 12–16, 2019, Columbus, OH, USA
struct A {char c;int i;
char buf[64];void (*fp)();}H. Sasaki, M. Arroyo, M. Tarek Ibn Ziad, K. Bhat, K. Sinha, and S. Sethumadhavan

struct A_opportunistic {char c;/* compiler inserts padding* bytes for alignment */char padding_bytes[3];int i;
char buf[64];void (*fp)();}(a) Original.

struct A_full {/* we protect every field with* random security bytes */char security_bytes[2];char c;char security_bytes[1];int i;
char security_bytes[3];char buf[64];char security_bytes[2];void (*fp)();char security_bytes[1];}(b) Opportunistic.

struct A_intelligent {char c;int i;/* we protect boundaries* of arrays and pointers with* random security bytes */char security_bytes[3];char buf[64];char security_bytes[2];void (*fp)();char security_bytes[3];}(d) Intelligent.

(c) Full.

0.6
0.4
0.2
0.0

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

Struct density(a) SPEC CPU2006 C and C++
benchmarks.

1B

0.8

0.4
0.2
0.0

2B

3B

4B

5B

6B

7B

8%

0.6

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

Struct density(b) V8 JavaScript engine.

Figure 3: Struct density histogram of SPEC CPU2006 benchmarks and the V8 JavaScript engine. More than 40% of thestructs have at least one padding byte.
other languages and their runtime implementations. To obtain aquantitative estimate on the amount of paddings, we developed acompiler pass to statically collect the padding size information. Figure 3 presents the histogram of struct densities for SPEC CPU2006
C and C++ benchmarks and the V8 JavaScript engine. Struct density
is defined as the sum of the size of each field divided by the total
size of the struct including the padding bytes (i.e., the smaller orsparse the struct density the more padding bytes the struct has).
The results reveal that 45.7% and 41.0% of structs within SPEC andV8, respectively, have at least one byte of padding. This is encouraging since even without introducing additional padding bytes (nomemory overhead), we can offer protection for certain compounddata types restricting the remaining attack surface.
Naturally, one might inquire about the safety for the rest of
the program. To offer protection for all defined compound datatypes, we can insert random sized padding bytes, also referred toas security bytes, between every field of a struct or member of aclass as in Listing 1(c) (full strategy). Random sized security bytes
are chosen to provide a probabilistic defense as fixed sized security
bytes can be jumped over by an attacker once she identifies theactual size (and the exact memory layout). By carefully choosing theminimum and maximum of random sizes, we can keep the average
size of security bytes small (few bytes). Intuitively, the higher theunpredictability (or randomness) within the memory layout, thehigher the security level we can offer.
While the full strategy provides the widest coverage, not all of the
security bytes provide the same security utility. For example, basic
data types such as char and int cannot be easily overflowed pasttheir bounds. The idea behind the intelligent insertion strategy is to

Slowdown

0.8

Fraction of structs

Fraction of structs

Listing 1: (a) Original source code and examples of three security bytes harvesting strategies: (b) opportunistic uses the existing
padding bytes as security bytes, (c) full protect every field within the struct with security bytes, and (d) intelligent surrounds
arrays and pointers with security bytes.

6%
4%
2%
0%

Figure 4: Average performance overhead with additional
paddings (one byte to seven bytes) inserted for every fieldwithin structs (and classes) of SPEC CPU2006 C and C++
benchmarks.
prioritize insertion of security bytes into security-critical locations
as shown in Listing 1(d). We choose data types which are most prone
to abuse by an attacker via overflow type accesses: (1) arrays and (2)data and function pointers. In Listing 1(d), the array buf[64] andthe function pointer fp are protected with random sized security
bytes. While it is possible to utilize padding bytes present between
other data types without incurring memory overheads, doing sowould come at an additional performance overhead.
In comparison to opportunistic harvesting, the other more secure
strategies (full and intelligent) come at an additional performance
overhead. We analyze the performance trend in order to decide how
many security bytes can be reasonably inserted. For this purpose
we developed an LLVM pass which pads every field of a structand member of a class with fixed size paddings. We measure
the performance of SPEC CPU2006 benchmarks by varying thepadding size from one byte to seven bytes (since eight bytes is thefinest granularity that state-of-the-art technique can offer [28]). The
detailed evaluation environment and methodology are describedlater in Section 10.
Figure 4 demonstrates the average slowdown when inserting
additional bytes for harvesting. As expected, we can see the performance overheads grow as we increase the padding size, mainly due
to ineffective cache usage. On average the slowdown is 3.0% for
one byte and 7.6% for seven bytes of padding. The figure presents
the ideal (lower bound) performance overhead when fully inserting
security bytes into compound data types; the hardware and software modifications we introduce add additional overheads on topof these numbers. We strive to provide a mechanism that allows
the user to tune the security level at the cost of performance andthus explore several security byte insertion strategies to reduce theperformance overhead in the paper.

Practical Byte-Granular Memory Blacklisting using Califorms

THREAT MODEL

5FULL SYSTEM OVERVIEWThe Califorms framework consists of multiple components we discuss in the following sections:
Architecture Support. A new instruction called BLOC, mnemonicfor Blacklist LOCations, that blacklists memory locations at byte
granularity and raises a privileged exception upon misuse of blacklisted locations (Section 6).
Microarchitecture Design. New cache line formats, or Califorms,
that enable low cost access to the metadata—we propose different
Califorms for L1 cache vs. L2 cache and beyond (Section 7).
Software Design. Compiler, memory allocator and operating system extensions which insert the security bytes at compile time andmanages them via the BLOC instruction at runtime (Section 8).
At compile time, each compound data type (struct or class) is
examined and security bytes are added according to a user defined
insertion policy viz. opportunistic, full or intelligent, by a sourceto-source translation pass. At execution time when compound data
type instances are dynamically created in the heap, we use a newversion of malloc that issues BLOC instructions to arrange the security bytes after the space is allocated. When the BLOC instruction
is executed, the cache line format is transformed at the L1 cachecontroller (assuming a cache miss) and is inserted into the L1 data
cache. Upon an L1 eviction, the L1 cache controller transforms thecache line to meet the Califorms of the L2 cache.
While we add additional metadata storage to the caches, we
refrain from doing so for main memory and persistent storage tokeep the changes local within the CPU core. When a califormed
cache line is evicted from the last-level cache to main memory,
we keep the cache line califormed and store the additional one
metadata bit into spare ECC bits similar to Oracle’s ADI [21, 26].4
When a page is swapped out from main memory, the page fault
handler stores the metadata for all the cache lines within the page
into a reserved address space managed by the operating system;
the metadata is reclaimed upon swap in. Therefore, our design
keeps the cache line format califormed throughout the memory
hierarchy. A califormed cache line is un-califormed only when the
4 ADI stores four bits of metadata per cache line for allocation granularity enforcement
while Califorms stores one bit for sub-allocation granularity enforcement.

Table 1: BLOC instruction K-map. X represents “Don’t Care”.
R2, R3
Initial4

We assume a threat model comparable to that used in contemporary related works [28, 31, 32]. We assume the victim program tohave one or more vulnerabilities that an attacker can exploit togain arbitrary read and write capabilities in the memory; our goal
is to prevent both spatial and temporal memory violations. Furthermore, we assume that the adversary has access to the sourcecode of the program, therefore she is able to glean all source-level
information. However, she does not have access to the host binary(e.g., server-side applications). Finally, we assume that all hardware
is trusted—it does not contain and/or is not subject to bugs arisingfrom exploits such as physical or glitching attacks. Due to its recent
rise in relevance however, we maintain side-channel attacks in ourdesign of Califorms within the purview of our threats. Specifically,
we accommodate attack vectors seeking to leak the location andvalue of security bytes.

MICRO-52, October 12–16, 2019, Columbus, OH, USA

X, AllowSet, Allow

Set, Allow

Regular Byte

Regular Byte

Exception

Security Byte

Security Byte

Security Byte

Regular Byte

Exceptioncorresponding bytes cross the boundary where the califormed datacannot be understood by the other end, such as writing to I/O(e.g., pipe, filesystem or network socket). Finally, when an object is
freed, the freed bytes are filled with security bytes and quarantinedfor offering temporal memory safety. At runtime, when a rogue loador store accesses a security byte the hardware returns a privileged,precise security exception to the next privilege level which can takeany appropriate action including terminating the program.

6 ARCHITECTURE SUPPORT
6.1 BLOC Instruction
The format of the instruction is “BLOC R1, R2, R3”. The value inregister R1 points to the starting (64B cache line aligned) addressin the virtual address space, denoting the start of the 64B chunkwhich fits in a single cache line. Table 1 represents a K-map for the
BLOC instruction. The value in register R2 indicates the attributesof said region represented in a bit vector format (1 to set and 0
to unset the security byte). The value in register R3 is a mask to
the corresponding 64B region, where 1 allows and 0 disallows
changing the state of the corresponding byte. The mask is used
to perform partial updates of metadata within a cache line. We
throw a privileged exception when the BLOC instruction tries to set
a security byte to an existing security byte, or unset a security byte
from a normal byte.
The BLOC instruction is treated similarly to a store instructionin the processor pipeline since it modifies the architectural state ofdata bytes in a cache line. It first fetches the corresponding cacheline into the L1 data cache upon an L1 miss (assuming a write
allocate cache policy). Next, it manipulates the bits in the metadatastorage to appropriately set or unset the security bytes.

6.2

Privileged Exceptions

When the hardware detects an access violation (i.e., access to asecurity byte), it throws a privileged exception once the instruction
becomes non-speculative. There are some library functions which
violate the aforementioned operations on security bytes such as
memcpy so we need a way to suppress the exceptions. In orderto whitelist such functions, we manipulate the exception mask
registers and let the exception handler decide whether to suppress
the exception or not. Although privileged exception handling ismore expensive than handling user-level exceptions (because it
requires a context switch to the kernel), we stick with the former tolimit the attack surface. We rely on the fact that the exception itself
is a rare event and would have negligible effect on performance.

7

MICROARCHITECTURE DESIGN

The microarchitectural support for our technique aims to keep
the common case fast: L1 cache uses the straightforward scheme

MICRO-52, October 12–16, 2019, Columbus, OH, USA

H. Sasaki, M. Arroyo, M. Tarek Ibn Ziad, K. Bhat, K. Sinha, and S. Sethumadhavan

Add’l storage

Cache line (data)

8B

64B

1bit
[0]

Add’l
storage

1B
[1]

[63]

[0]

4B

[63]

[0]

[1]

[2]

[3]

[4]

[5]

[62] [63]

[1]

[2]

[3]

1
[0]

Line califormed?

Security byte?

Aligner

Tag
Array

=

Hit/Miss# of security
bytes

00: 1
01: 2
10: 3
11: 4+

2bit

6bit

00

Addr0

[1]

[2]

[3]

01

Addr0

Addr1

[2]

[3]

10

Addr0

Addr1

Addr2

11

Addr0

Addr1

Addr2

[3]
Addr3

SentinelFigure 7: Califorms-sentinel that stores a bit vector in security byte locations. HW overhead of 1-bit per 64B cache line.
Data

Way Mux

Exception?

Address
Decoder

Data
Array

Address
DecoderTag etc.

Index

Oﬀset

Metadata
Array

Califorms
Checker

Figure 5: Califorms-bitvector: L1 Califorms implementation
using a bit vector that indicates whether each byte is a security byte. HW overhead of 8B per 64B cache line.

Figure 6: Pipeline diagram for the L1 cache hit operation.
The shaded blocks correspond to Califorms components.
of having one bit of additional storage per byte. All califormed
cache lines are converted to the straightforward scheme at theL1 data cache controller so that typical loads and stores which
hit in the L1 cache do not have to perform address calculations
to figure out the location of original data (which is required for
Califorms of L2 cache and beyond). This design decision guarantees
that the common case latencies will not be affected due to security
functionality. Beyond the L1, the data is stored in the optimized
califormed format, i.e., one bit of additional storage for the entire
cache line. The transformation happens when the data is filled inor spilled from the L1 data cache (between the L1 and L2), and adds
minimal latency to the L1 miss latency.

7.1

64B

1bit
[1]

1

Address calc

Cache line (data)

L1 Cache: Bit Vector Approach

To satisfy the L1 design goal we consider a naive (but low latency)
approach which uses a bit vector to identify which bytes are security bytes in a cache line. Each bit of the bit vector corresponds toeach byte of the cache line and represents its state (normal byteor security byte). Figure 5 presents a schematic view of this implementation califorms-bitvector. The bit vector requires a 64-bit (8B)
bit vector per 64B cache line which adds 12.5% storage overhead
for the L1 data cache (comparable to ECC overhead for reliability).
Figure 6 shows the L1 data cache hit path modifications for
Califorms. If a load accesses a security byte (which is determinedby reading the bit vector) an exception is recorded to be processed
when the load is ready to be committed. Meanwhile, the load returns
a pre-determined value for the security byte (in our design thevalue zero which is the value that the memory region is initialized
to upon deallocation). Returning this fixed value is meant to bea countermeasure against speculative side-channel attacks that
seek to identify security byte locations (discussed in greater detailin Section 9). On store accesses to security bytes, we report an
exception when the store commits.

7.2

L2 Cache and Beyond: Sentinel Approach

For L2 and beyond, we take a different approach that allows us
to recognize whether each byte is a security byte with fewer bits, as
using the L1 metadata format throughout the system will increase
the cache area overhead by 12.5%, which may not be acceptable.
We propose califorms-sentinel, which has a 1-bit or 0.2% metadata
overhead per 64B cache line. For main memory, we store the additional bit per cache line size in the DRAM ECC spare bits, thus
completely removing any cycle time impact on DRAM access or
modifications to the DIMM architecture.
The key insight that enables the savings is the following observation: the number of bits required to address all the bytes in a cacheline, which is six bits for a 64 byte cache line, is less than a single byte.
For example, let us assume that there is (at least) one security byte
in a 64B cache line. Considering a byte granular protection there areat most 63 unique values (bytes) that non-security bytes can have.
Therefore, we are guaranteed to find a six bit pattern that is notpresent in any of the normal bytes’, for instance least significant,six bits. We use this pattern as a sentinel value to represent the
security bytes in the cache line. Now if we store this six bit (sentinelvalue) as additional metadata, the storage overhead will be sevenbits (six bits plus one bit to specify if the cache line is califormed)
per cache line. In this paper we further propose a new cache line
format which stores the sentinel value within a security byte to
reduce the metadata overhead down to one bit per cache line.
As presented in Figure 7, califorms-sentinel stores the metadata
into the first four bytes (at most) of the 64B cache line. Two bitsof the first (0th) byte are used to specify the number of security
bytes within the cache line: 00, 01, 10 and 11 represent one, two,
three, and four or more security bytes, respectively. The sentinel
is used only when we have more than four security bytes. If there
is only one security byte in the cache line, we use the remaining
six bits of the 0th byte to specify the location of the security byte,
and the original value of the 0th byte is stored in the security byte.
Similarly when there is two or three security bytes in the cache line,

Practical Byte-Granular Memory Blacklisting using Califorms

1

Data of 1st 4 Bytes

[0]

6bit

Decoder6 x 64

2bit
[1]

6bit

[63]

5

8

64

Decoder6 x 64

Decoder6 x 64

L1 Cache Line Data

9

13

14

15

[0]
Mask

[1]

Find
index
of 1stbit of 1st Sec. Byte
value 1

[0]
[1]

64

6bit

3

MICRO-52, October 12–16, 2019, Columbus, OH, USA

Find
index
of 1stbit ofvalue 0L2 Califorms
Metadata

6Mask

2nd Sec. Byte
6

Find
index
of 1stbit ofvalue 1[0]Mask

3rd Sec. Byte
6

Find
index
of 1stbit ofvalue 1

4th Sec. Byte

7

[1]

6

Cross Bar &Combinational
Logic

[63]

L1 Califorms Metadata[63]
1: used0: unused

6

Find
index
of 1stbit ofvalue 111

[63]

Sentinel Value

12

L2 Cache Line Data

Figure 8: Logic diagram for Califorms conversion from the L1 cache (califorms-bitvector) to L2 cache (califorms-sentinel).
The shaded blocks are constructed using 64 shift blocks followed by a single comparator. The circled numbers refer to thecorresponding steps in Algorithm 1.

1: Read the Califorms metadata for the evicted line and OR them
2: if result is 0 then3:
Evict the line as is and set Califorms bit to zero
4: else5:
Set Califorms bit to one
6:
if num security bytes (N) < 4 then7:
Get locations of first N security bytes
8:Store data of first N bytes in locations obtained in 7
9:Fill the first N bytes based on Figure 7
10:
else
11:
Get locations of first four security bytes
12:
Scan least 6-bit of every byte to determine sentinel
13:
Store data of first four bytes in locations obtained in 11
14:
Fill the first four bytes based on Figure 7
15:
Use the sentinel to mark the remaining security bytes
16:
end
17: end

Algorithm 1: Califorms conversion from the L1 cache(califorms-bitvector) to L2 cache (califorms-sentinel).
we use the bits of the second and third bytes to locate them. The
key observation is that, we gain two bits per security byte since weonly need six bits to specify a location in the cache line. Therefore
when we have four security bytes, we can locate four addresses andhave six bits remaining in the first four bytes. This remaining six
bits can be used to store a sentinel value, which allows us to haveany number of additional security bytes.
Although the sentinel value depends on the actual values within
the 64B cache line, it works naturally with a write-allocate L1
cache (which is the most commonly used cache allocation policy
in modern microprocessors). The cache line format is transformed
upon L1 cache eviction and insertion (califorms-bitvector to/from
califorms-sentinel), while the sentinel value only needs to be foundupon L1 cache eviction (L1 miss). Also, it is important to note thatcaliforms-sentinel supports critical-word first delivery since thesecurity byte locations can be quickly retrieved by scanning only
the first 4B of the first 16B flit.

7.3

L1 to/from L2 Califorms Conversion

Figure 8 and Algorithm 1 show the logic diagram and the high-levelprocess of the spill (L1 to L2 conversion) module, respectively. The
circled numbers in the figure refer to the corresponding steps in
the algorithm. There are four components presented in the figure.
From the left, the first block details the process of determining thesentinel value (line 12). We scan the least 6-bits of every byte, decodethem, and OR the output to construct a used-values vector. The usedvalues vector is then processed by a “find-index” block to get thesentinel value. The find-index block takes a 64-bit input vector

L2 Califorms Metadata

F
2bit

[0]

6bit
Addr0
6bit
Addr1

[3]

L2[Addr1]

0

Zeros

1

[3]

0

Zeros

1

En3

L2 Cache Line Data

[2]

L1Meta[3]

[63]

6bit

[1]

L1Meta[2]L2[Addr2]

Decoder6 x 646bit
Sentinel[0][4]

Decoder6 x 64

G[63]

1

L1Meta[1]

[2]

En3
6bit
Addr3

0

Zeros

[1]

En2
6bit
Addr2

L2[Addr0][0]

Decoder6 x 64[2]

9

L1Meta[0]Califormed?

En0

Decoder6 x 64En1[1]

8

Sentinel?

L2[Addr3]

0

Zeros

1

L1 Califorms
Metadata

5

6

7

Blocks F (if 2-bit matches 00, 01, 10 or 11)
and G (if 6-bit matches the sentinel) areconstructed using logic comparators[3]

L1Meta[63]L2[63]

0

Zeros

1

[63]

L1 Cache Line Data

Figure 9: Logic diagram of Califorms conversion from the L2
cache (califorms-sentinel) to L1 cache (califorms-bitvector).
The shaded block F and G consist of four and 60 comparators,
respectively. The circled numbers refer to the corresponding
steps in Algorithm 2.

1: Read the Califorms bit for the inserted line
2: if result is 0 then3:
Set the Califorms metadata bit vector to [0]4: else5:
Check the least significant 2-bit of byte 0
6:
Set the metadata of byte[Addr[0-3]] to one based on 5
7:
Set the metadata of byte[Addr[byte==sentinel]] to one
8:
Set the data of byte[0-3] to byte[Addr[0-3]]
9:
Set the new locations of byte[Addr[0-3]] to zero
10: end

Algorithm 2: Califorms conversion from the L2 cache(califorms-sentinel) to L1 cache (califorms-bitvector).
and searches for the index of the first zero value. It is constructedusing 64 shift blocks followed by a single comparator. In the second
block, L1 cache (califorms-bitvector) metadata for the evicted line
is ORed to construct the L2 cache (califorms-sentinel) metadata. The
third block shows the logic for getting the locations of the first
four security bytes (lines 7 and 11). It consists of four successive
combinational find-index blocks (each detecting one security byte)
in our evaluated design. This logic can be easily pipelined into four

MICRO-52, October 12–16, 2019, Columbus, OH, USAstages if needed, to completely hide the latency of the spill process
in the pipeline. Finally in the last block, we form the L2 cache line
based on Figure 7.
Figure 9 shows the logic diagram for the fill (L2 to L1 conversion)
module, as summarized in Algorithm 2. The shaded blocks F and
G are constructed using logic comparators. The one bit metadata of
L2 Califorms is used to control the value of the L1 cache (califormsbitvector) metadata. The first two bits of the L2 cache line are used
as inputs for the comparators (block F) to detect how many security
bytes the cache line contain. Block F outputs four signals (En0 toEn3) which enable the four decoders. Only if those two bits are 11,
the sentinel value is read from the fourth byte and fed, with theleast 6-bits of each byte, to 60 comparators simultaneously to set
the rest of the L1 metadata bits. Such parallelization reduces thelatency impact of the fill process.

7.4

Load/Store Queue Modifications

Since the BLOC instruction updates the architectural state, it is functionally a store instruction and handled as such in the pipeline.
However, there is a key difference: unlike a store instruction, theBLOC instruction should not forward the value to a younger load instruction whose address matches within the load/store queue (LSQ)
but instead return the value zero. This functionality is required
to provide tamper-resistance against side-channel attacks. Additionally, upon an address match, both load and store instructions
subsequent to an in flight BLOC instruction are marked for Califorms
exception; exception is thrown when the instruction is committed
to avoid any false positives due to misspeculation.
In order to detect an address match in the LSQ with a BLOC
instruction, first a cache line address should be matched with all
the younger instructions. Subsequently upon a match, the value
stored in the LSQ for the BLOC instruction which contains the mask
value (to set/unset security bytes) is used to confirm the final match.
To facilitate a match with a BLOC instruction, each LSQ entry should
be associated with a bit to indicate whether the entry contains a
BLOC instruction. Detecting a complete match may take multiple
cycles, however, a legitimate load/store instruction should never
be forwarded a value from a BLOC instruction, and thus the storeto-load forwarding from a BLOC instruction is not on the critical
path of the program (i.e., its latency should not affect performance),
and we do not evaluate its effect in our evaluation. Alternately, if
LSQ modifications are to be avoided, the BLOC instructions can besurrounded by memory serializing instructions (i.e., ensure that
BLOC instructions are the only in flight memory instructions).

8

SOFTWARE DESIGNWe describe the memory allocator, compiler and the operating
system changes to support Califorms in the following.

8.1

Dynamic Memory Management

We can consider two approaches to applying security bytes: (1)Dirty-before-use. Unallocated memory has no security bytes. We
set security bytes upon allocation and unset them upon deallocation;or (2) Clean-before-use. Unallocated memory remains filled withsecurity bytes all the time. We clear the security bytes (in legitimate
data locations) upon allocation and set them upon deallocation.

H. Sasaki, M. Arroyo, M. Tarek Ibn Ziad, K. Bhat, K. Sinha, and S. Sethumadhavan

Ensuring temporal memory safety in the heap remains a nontrivial problem [30]. We therefore choose to follow a clean-beforeuse approach in the heap, so that deallocated memory regions remain protected by security bytes.5 In order to provide temporal
memory safety (to mitigate use-after-free exploits), we do not reallocate recently freed regions until the heap is sufficiently consumed(quarantining). Additionally, both ends of the heap allocated regions
are protected by security bytes in order to provide inter-object memory safety. Compared to the heap, the security benefits are limited
for the stack since temporal attacks on the stack (e.g., use-afterreturn attacks) are much rarer. Hence, we apply the dirty-before-use
scheme on the stack.

8.2

Compiler Support

Our compiler-based instrumentation infers where to place security
bytes within target objects, based on their type layout information.
The compiler pass supports three insertion policies: the first opportunistic policy supports security bytes insertion into existing
padding bytes within the objects, and the other two support modifying object layouts to introduce randomly sized security byte spansthat follow the full or intelligent strategies described in Section 3.
The first policy aims at retaining interoperability with external code
modules (e.g., shared libraries) by avoiding type layout modification. Where this is not a concern, the latter two policies help offer
stronger security coverage—exhibiting a tradeoff between security
and performance.

8.3

Operating System Support

We need the following support in the operating system:
Privileged Exceptions. As the Califorms exception is privileged,
the operating system needs to properly handle it as with otherprivileged exceptions (e.g., page faults). We also assume the faulting
address is passed in an existing register so that it can be used
for reporting/investigation purposes. Additionally, for the sake ofusability and backwards compatibility, we have to accommodate
copying operations similar in nature to memcpy. For example, asimple struct to struct assignment could trigger this behavior,thus leading to a potential breakdown of software with Califorms
support. Hence, in order to maintain usability, we allow whitelisting
functionality to suppress the exceptions. This can either be donewith a privileged store (requiring a syscall) or an unprivileged store.
Both options represent different design points in the performancesecurity tradeoff spectrum.
Page Swaps. As we have discussed in Section 5, data with security
bytes is stored in main memory in a califormed format. When apage with califormed data is swapped out from main memory, thepage fault handler needs to store the metadata for the entire page
into a reserved address space managed by the operating system;
the metadata is reclaimed upon swap in. The kernel has enoughaddress space in practice (kernel’s virtual address space is 128TB
for a 64-bit Linux with 48-bit virtual address space) to store the
5 It is natural to use a variant of BLOC instruction which bypasses (does not store into)

the L1 data cache, just like the non-temporal (or streaming) load/store instructions(e.g., MOVNTI, MOVNTQ, etc) when deallocating a memory region; deallocated region is
not meant to be used by the program and thus polluting the L1 data cache with thosememory is harmful and should be avoided. However, we do not evaluate the use ofsuch instructions in this paper.

Practical Byte-Granular Memory Blacklisting using Califorms

metadata for all the processes on the system since the size of themetadata is minimal (8B for a 4KB page or 0.2%).

9 SECURITY DISCUSSION
9.1 Hardware Attacks and Mitigations
Metadata Tampering Attacks. A key feature of Califorms is theabsence of metadata that is accessible by the program via regular load-stores. This makes our technique immune to attacks that
explicitly aim to leak or tamper metadata to bypass the defense.
This, in turn, implies a smaller attack surface as far as software
maintenance/isolation of metadata is concerned.
Bit-Granular Attacks. Califorms’s capability of fine-grained
memory protection is the key enabler for intra-object overflow
detection. However, our byte granular mechanism is not enoughfor protecting bit-fields without turning them into char bytes
functionally. This should not be a major detraction since security
bytes can still be added around composites of bit-fields.
Side-Channel Attacks. Our design takes multiple steps to be resilient to side-channel attacks. Firstly, we purposefully avoid having
our hardware modifications introduce timing variances to avoid
timing based side-channel attacks. Additionally, to avoid speculative execution side channels ala Spectre [15], our design returns
zero on a load to camouflage security byte with normal data, thus
preventing speculative disclosure of metadata. We augment this further by requiring that deallocated objects (heap or stack) be zeroedout in software [17]. This is to reduce the chances of the following
attack scenario: consider a case if the attacker somehow knows thatthe padding locations should contain a non-zero value (for instance,
because she knows the object allocated at the same location prior
to the current object had non-zero values). However, while speculatively disclosing memory contents of the object, she discovers thatthe padding location contains a zero instead. As such, she can inferthat the padding there contains a security byte. If deallocations
were accompanied with zeroing, however, this assumption can bemade with a lower likelihood. Hence, making Califorms return afixed value (zero), complemented by software actively zeroing out
unused locations, reduces the attacker’s probability of speculatively
predicting security byte locations, as well as leaking its exact value.

9.2

MICRO-52, October 12–16, 2019, Columbus, OH, USA(e.g., passing a pointer to an object that shall remain opaque within
the external module), our hardware-based implicit checks havethe benefit of persistent tampering protection, even across binary
module boundaries.
Whitelisting Attacks. Our concession of allowing whitelisting ofcertain functions was necessary to make Califorms more usable incommon environments without requiring significant source modifications. However, this also creates a vulnerability window wherein
an adversary can piggy back on these functions in the source tobypass our protection. To confine this vector, we keep the numberof whitelisted functions as minimal as possible.
Derandomization Attacks. Since Califorms can be bypassed if
an attacker can guess the security bytes location, it is crucial that it
be placed unpredictably. For the attacker to carry out a guessing
attack, the virtual address of the target object has to be leaked, inorder to overwrite a certain number of bytes within that object.
To know the address of the object of interest, she typically has toscan the process’s memory: the probability of scanning without
touching any of the security bytes is (1−P/N )O where O is numberof allocated objects, N is the size of each object, and P is number of
security bytes within that object. With 10% padding (P/N = 0.1),
when O reaches 250, the attack success goes to 10−20 . If the attacker
can somehow reduce O to 1, which represents the ideal case forthe attacker, the probability of guessing the element of interest is
1/7n (since we insert 1–7 wide security bytes), compounding as thenumber of padding spans to be guessed (= n) increases.
The randomness is, however, introduced statically akin torandstruct plugin introduced in recent Linux kernels which
randomizes structure layout of those which are specified (it does
not offer detection of rogue accesses unlike Califorms do) [5, 12].
The static nature of the technique may make it prone to brute
force attacks like BROP [4] which repeatedly crashes the program
until the correct configuration is guessed. This could be prevented
by having multiple binaries of the same program with different
padding sizes or simply by better logging, when possible. Anothermitigating factor is that BROP attacks require specific type ofprogram semantics, namely, automatic restart-after-crash with thesame memory layout. Applications with these semantics can be
modified to spawn with a different padding layout in our case andyet satisfy application level requirements.

Software Attacks and Mitigations

Coverage-Based Attacks. For emitting BLOC instructions to workon the padding bytes (in an object), we need to know the precise
type information of the allocated object. This is not always possible
in C-style programs where void* allocations may be used. In thesecases, the compiler may not be able to infer the correct type, inwhich case intra-object support may be skipped for such allocations.
Similarly, our metadata insertion policies (viz., intelligent and full)
require changes to the type layouts. This means that interactions
with external modules that have not been compiled with Califorms
support may need (de)serialization to remain compatible. For an
attacker, such points in execution may appear lucrative because of
inserted security bytes getting stripped away in those short periods.
We note however that the opportunistic policy can still remainin place to offer some protection. On the other hand, for thoseinteractions that remain oblivious to type layout modifications

10 PERFORMANCE EVALUATION
10.1 Hardware Overheads
Cache Access Latency Impact of Califorms. Califorms adds
additional state and operations to the L1 data cache and the interface
between the L1 and L2 caches. The goal of this section is to evaluate
the access latency impact of the additional state and operations
described in Section 7. Qualitatively, the metadata area overheadof L1 Califorms is 12.5%, and the access latency should not be
impacted as the metadata lookup can happen in parallel with theL1 data and tag accesses; the L1 to/from L2 Califorms conversion
should also be simple enough so that its latency can be completely
hidden. However, the metadata area overhead can increase the L1
access latency and the conversions might add little latency. Without
loss of generality, we measure the access latency impact of adding

MICRO-52, October 12–16, 2019, Columbus, OH, USA

H. Sasaki, M. Arroyo, M. Tarek Ibn Ziad, K. Bhat, K. Sinha, and S. Sethumadhavan

Table 2: Area, delay and power overheads of Califorms(GE represents gate equivalent). L1 Califorms (califormsbitvector) adds negligible delay and power overheads to theL1 cache access.

Table 3: Hardware configuration of the simulated system.

6 For some benchmark-input pairs we saw discrepancies in the number of instructions

measured by PinPoints vs. ZSim and thus the appropriate SimPoint regions might not
be simulated. Those inputs are: foreman_ref_encoder_main for h264ref and pds-50
for soplex. Also, due to time constraints, we could not complete executing SimPointfor h264ref with sss_encoder_main input and excluded it from the evaluation.

1.5%
1%

AMean

sphinx3

xalancbmk

sjeng

soplexpovrayperlbench

namd

omnetpp

mcf

0%

milc

0.5%

lbm

califorms-bitvector on a 32KB direct mapped L1 cache in the context
of a typical energy optimized tag and data, formatting L1 pipeline
with multicycle fill/spill handling. For the implementation we use
the 65nm TSMC core library, and generate the SRAM arrays with
the ARM Artisan memory compiler.
Table 2 summarizes the results for the L1 Califorms (califormsbitvector). As expected, the overheads associated with the califormsbitvector are minor in terms of delay (1.85%) and power consumption (2.12%). We found the SRAM area to be the dominant component in the total cache area (around 98%) where the overhead is
18.69% (higher than 12.5%).
The results of fill/spill modules are reported separately in thebottom half of Table 2. The latency impact of the fill operation iswithin the access period of the L1 design. Thus, the transformation
can be folded completely within the pipeline stages that are responsible for bringing cache lines from L2 to L1. The timing delay ofthe less performance sensitive spill operation is larger than thatof the fill operation (5.5ns vs. 1.4ns) as we use pure combinational
logic to construct the califorms-sentinel format in one cycle, as
shown in Figure 8. This cycle period can be reduced by dividing
the operations of Algorithm 1 into two or more pipeline stages.
For instance, getting the locations of the first four security bytes(lines 7 and 11) consists of four successive combinational blocks(each detecting one security byte) in our evaluated design. This
logic can be easily pipelined into four stages. Therefore we believethat the latency of both the fill and spill operations can be minimal(or completely hidden) in the pipeline.
Performance with Additional Cache Access Latency. Our
VLSI implementation results imply that there will be no additional
L2/L3 latency imposed by implementing Califorms. However, thismight not be the case depending on several implementation details(e.g., target clock frequency) so we pessimistically assume that theL2/L3 access latency incurs additional one cycle latency overhead.
In order to evaluate the performance of the additional latency posedby Califorms, we perform detailed microarchitectural simulations.
We run SPEC CPU2006 benchmarks with ZSim [24] processor
simulator for evaluation. All the benchmarks are compiled with
Clang version 6.0.0 with “-O3 -fno-strict-aliasing” flags. We
use the ref input sets and representative simulation regions are
selected with PinPoints [22]. We do not warmup the simulator
upon executing each SimPoint region, but instead use a relatively
large interval length of 500M instructions to avoid any warmup
issues. MaxK used in SimPoint region selection is set to 30.6 Table 3

libquantum

0.18
0.52

hmmer

1.43
5.50

h264ref

8,957.16
34,561.80

gcc

Fill Module
Spill Modulex86-64 Intel Westmere-like OoO core at 2.27GHz
32KB, 4-way, 3-cycle latency
32KB, 8-way, 4-cycle latency
256KB, 8-way, 7-cycle latency
2MB, 16-way, 27-cycle latency
8GB, DDR3-1333

gobmk[+2.12%] 16.17

dealIIPower (mW )[+1.85%] 1.65

astar

Delay (ns)[+18.69%] 412,263.87

bzip2

Area (GE)L1 Overheads

Slowdown

L1 Califorms

Core
L1 inst. cache
L1 data cache
L2 cacheL3 cache
DRAM

Figure 10: Slowdown with additional one-cycle access latency for both L2 and L3 caches.
shows the parameters of the processor, an Intel Westmere-like outof-order core which has been validated against a real system whose
performance and microarchitectural events to be commonly within
10% [24]. We evaluate the performance when both L2 and L3 caches
incur additional latency of one cycle.
As shown in Figure 10 slowdowns range from 0.24% (hmmer) to
1.37% (xalancbmk). The average performance slowdown is 0.83%
which is well in the range of error when executed on real systems.

10.2

Software Performance Overheads

Our evaluations so far revealed that the hardware modifications
required to implement Califorms add little or no performance overhead. Here, we evaluate the overheads incurred by the software
based changes required to enable inter-/intra-object and temporal
memory safety with Califorms: the effect of underutilized memory
structures (e.g., caches) due to additional security bytes, the additional work necessary to issue BLOC instructions (and the overheadof executing the instructions themselves), and the quarantining tosupport temporal memory safety.
Evaluation Setup. We run the experiments on an Intel Skylakebased Xeon Gold 6126 processor running at 2.6GHz with RHEL
Linux 7.5 (kernel 3.10). We omit dealII and omnetpp due to librarycompatibility issues in our evaluation environment, and gcc since
it fails when executed with the memory allocator with inter-object
spatial and temporal memory safety support. The remaining 16
SPEC CPU2006 C/C++ benchmarks are compiled with our modified
Clang version 6.0.0 with “-O3 -fno-strict-aliasing” flags. We
use the ref inputs and run to completion. We run each benchmarkinput pair five times and use the shortest execution time as its
performance. For benchmarks with multiple ref inputs, the sum of
the execution time of all the inputs are used as their execution times.
We use the arithmetic mean to represent the average slowdown.7
We estimate the performance impact of executing a BLOC instruction by emulating it with a dummy store instruction that writes
some value to the corresponding cache line’s padding byte. Since
7 The use of arithmetic mean of the speedup (execution time of the original system

divided by that of the system with additional latency) means that we are interested ina condition where the workloads are not fixed and all types of workloads are equallyprobable on the target system [11, 14].

Practical Byte-Granular Memory Blacklisting using Califorms

MICRO-52, October 12–16, 2019, Columbus, OH, USA
1-3B

1-5B

1-7B

Slowdown

Opportunistic BLOC

1-3B BLOC

1-5B BLOC

1-7B BLOC

85.2%

50%

85.2%

40%

85.2%

30%

80.3%

20%
10%
0%
-10%

astar

bzip2

gobmk

h264ref

hmmer

lbm

libquantum

mcf

milc

namd

perlbench

povraysjeng

soplexsphinx3

xalancbmk

AMean

Figure 11: Slowdown of the opportunistic policy, and full insertion policy with random sized security bytes (with and without
BLOC instructions). The average slowdowns of opportunistic and full insertion policies are 6.2% and 14.2%, respectively.
1-3B

1-5B

1-7B

1-3B BLOC

1-5B BLOC

1-7B BLOC

Slowdown

20%
15%
10%
5%
0%
-5%

astar

bzip2

gobmk

h264ref

hmmer

lbm

libquantum

mcf

milc

namd

perlbench

povraysjeng

soplexsphinx3

xalancbmk

AMean

Figure 12: Slowdown of the intelligent insert policy with random sized security bytes (with and without BLOC instructions).
The average slowdown is 2.0%.

a single BLOC instruction is able to caliform the entire cache line,
issuing one dummy store instruction per to-be-califormed cacheline suffices. In order to issue the dummy stores, we implement a
LLVM pass to instrument the code to hook into memory allocations
and deallocations. We then retrieve the type information to locate
the padding bytes, calculate the number of dummy stores and theaddress they access, and finally emit them. Therefore, all the software overheads we need to pay to enable Califorms are accounted
for in our evaluation.
For the random sized security bytes, we evaluate three variants:
we fix the minimum size to one byte while varying the maximum
size to three, five and seven bytes (i.e., on average the amount of
security bytes inserted are two, three and four bytes, respectively).
In addition, in order to account for the randomness introduced by
the compiler, we generate three different versions of binaries forthe same setup (e.g., three versions of astar with random sized
paddings of minimum one byte and maximum three bytes). The
error bars in the figure represent the minimum and the maximum
execution times among 15 executions (three binaries × five runs)
and the average of the execution times is represented as the bar.
Performance of the Opportunistic and Full Insertion Policies with BLOC Instructions. Figure 11 presents the slowdown incurred by three set of strategies: full insertion policy (with random
sized security bytes) without BLOC instructions, the opportunistic
policy with BLOC instructions, and the full insertion policy with
BLOC instructions. Since the first strategy does not execute BLOC
instructions it does not offer any security coverage, but is shown
as a reference to showcase the performance breakdown of the third
strategy (cache underutilization vs. executing BLOC instructions).
First, we focus on the three variants of the first strategy, which
are shown in the three left most bars. We can see that different sizesof (random sized) security bytes does not make a large difference interms of performance. The average slowdown of the three variants

are 5.5%, 5.6% and 6.5%, respectively. This can be backed up by
our results shown in Figure 4, where the average slowdowns ofadditional padding of two, three and four bytes ranges from 5.4%
to 6.2%. Therefore in order to achieve higher security coverage
without losing performance, using a random sized bytes of, minimum of one byte and maximum of seven bytes, is promising. When
we focus on individual benchmarks, we can see that a few benchmarks including h264ref, mcf, milc and omnetpp incur noticeable
slowdowns (ranging from 15.4% to 24.3%).
Next, we examine the opportunistic policy with BLOC instructions, which is shown in the middle (fourth) bar. Since this strategy does not add any additional security bytes, the overheads are
purely due to the work required to setup and execute BLOC instructions. The average slowdown of this policy is 7.9%. There
are benchmarks which encounter a slowdown of more than 10%,
namely gobmk, h264ref and perlbench. The overheads are due
to frequent allocations and deallocations made during program
execution, where we have to calculate and execute BLOC instructions upon every event (since every compound data type requires
security bytes management). For instance perlbench is notorious
for being malloc-intensive, and reported as such elsewhere [25].
Lastly the third policy, the full insertion policy with BLOC instructions, offers the highest security coverage in Califorms based
system with the highest average slowdown of 14.0% (with the random sized security bytes of maximum seven bytes). Nearly half
(seven out of 16) the benchmarks encounter a slowdown of morethan 10%, which might not be suitable for performance-criticalenvironments, and thus the user might want to consider the use of
the following intelligent insertion policy.
Performance of the Intelligent Insertion Policy with BLOC
Instructions. Figure 12 shows the slowdowns of the intelligent
insertion policy with random sized security bytes (with and without
BLOC instructions, in the same spirit as Figure 11). First we focus

MICRO-52, October 12–16, 2019, Columbus, OH, USA

H. Sasaki, M. Arroyo, M. Tarek Ibn Ziad, K. Bhat, K. Sinha, and S. Sethumadhavan

Table 4: Security comparison against prior hardware techniques. ∗ Achieved with bounds narrowing. † Although the
hardware supports bounds narrowing, CHERI foregoes it
since doing so compromises capability logic [7].‡ Execution
compatible, but protection dropped when external modules
modify pointer. § Limited to 13 tags. ¶ Allocator should randomize allocation predictability.
ProposalProtection
Granularity

IntraObject

BinaryComposability

Temporal
SafetyHardbound [8]Watchdog [18]WatchdogLite [19]Intel MPX [20]BOGO [33]
PUMP [9]CHERI [32]CHERI concentrate [31]SPARC ADI [21]SafeMem [23]
REST [28]

Byte
Byte
Byte
Byte
Byte
Word
Byte
Byte
Cache line
Cache line
8–64B

✓∗
✓∗
✓∗
✓∗
✓∗
✗
✗†
✗†
✗
✗
✗

✗
✗
✗
✗‡
✗‡
✓
✗
✗
✓
✓
✓

✗
✓
✓
✗
✓
✓
✗
✗
✓§
✗
✓¶

Califorms

Byte

✓

✓

✓¶

on the strategy without executing BLOC instructions (the threebars on the left). The performance trend is similar such that thethree variants with different random sizes have little performancedifference, where the average slowdown is 0.2% with the random
sized security bytes of maximum seven bytes. We can see that noneof the programs incurs a slowdown of greater than 5%. Finally with
BLOC instructions (three bars on the right), gobmk and perlbench
have slowdowns of greater than 5% (16.1% for gobmk and 7.2% for
perlbench). The average slowdown is 1.5%, where considering its
security coverage and performance overheads the intelligent policy
might be the most practical option for many environments.

11

COMPARISON WITH PRIOR WORK

Tables 4, 5, and 6 summarize the security, performance, and implementation characteristics of the hardware based memory safety
techniques discussed in Section 2, respectively. Califorms has theadvantage of requiring simpler hardware modifications and being
faster than disjoint metadata based whitelisting systems. The hardware savings mainly stem from the fact that our metadata resides
with program data; it does not require explicit propagation while
additionally obviating all lookup logic. This significantly reduces
our design’s implementation costs. Califorms also has lower performance and energy overheads since it neither requires multiple
memory accesses, nor does it incur any significant checking costs.
However, Califorms can be bypassed if accesses to security bytes
can be avoided. This safety-vs.-complexity tradeoff is critical to
deployability and we argue that our design point is more practical. This is because designers have to contend with integratingthese features to already complicated processor designs, without
introducing additional bugs while also keeping the functionality oflegacy software intact. This is a hard balance to strike [20].
On the other hand, ideal cojoined metadata mechanisms would
have comparable slowdowns and similar compiler requirements.
However, practical implementations like ADI exhibits some crucial
differences from the ideal.

• It is limited to 64-bit architectures, which excludes a large portion of embedded and IoT processors that operate on 32-bit or
narrower platforms.
• It has finite number of colors since available tag bits are limited—
ADI supports 13 colors with 4 tag bits. This is important because
reusing colors proportionally reduces the safety guarantees ofthese systems in the event of a collision.
• It operates at the coarse granularity of cache line width, andhence, is not practically applicable for intra-object safety.
On the contrary, Califorms is agnostic of architecture width andis better suited for deployment over a more diverse device environment. In terms of safety, collision is not an issue for our design.
Hence, unlike cojoined metadata systems, our security does notscale inversely with the number of allocations in the program. Finally, our fine-grained protection makes us suitable for intra-object
memory safety which is a non-trivial threat in modern security [16].

12

CONCLUSION

Califorms is a hardware primitive which allows blacklisting a memory location at byte granularity with low area and performance
overhead. A key observation behind Califorms is that a blacklisted
region need not store its metadata separately but can rather store
them within itself; we utilize byte-granular existing or added space
between object elements to blacklist a region. This in-place compact data structure avoids additional operations for fetching themetadata making it very performant in comparison. Further, bychanging how data is stored within a cache line we reduce the hardware area overheads substantially. Subsequently, if the processor
accesses a blacklisted byte or a security byte, due to programming
errors or malicious attempts, it reports a privileged exception.
To provide memory safety, we use Califorms to insert security
bytes between and within data structures (e.g., between fields of astruct) upon memory allocation and clear them on deallocation.
Notably, by doing so, Califorms can even detect intra-object overflows in a practical manner, thus addressing one of the prominent
open problems in area of memory safety and security.

ACKNOWLEDGMENTS
This work was partially supported by ONR N00014–16–1–2263,
ONR N00014–17–1–2788, ONR N00014–15–1–2173, DARPA
HR0011–18–C–0017, and a gift from Bloomberg. The authors
thank Prof. Mingoo Seok for access to SRAM timing measurement
tools. Any opinions, findings, conclusions and recommendations
expressed in this material are those of the authors and do notnecessarily reflect the views of the US government or commercial
entities. Simha Sethumadhavan has a significant financial interestin Chip Scan Inc.

Practical Byte-Granular Memory Blacklisting using Califorms

MICRO-52, October 12–16, 2019, Columbus, OH, USA

Table 5: Performance comparison against previous hardware techniques.
Proposal

Metadata
Overhead

MemoryOverhead

Performance
Overhead

Hardbound [8]

0–2 words per ptr,
4b per word

Watchdog [18]∝ # of ptrs and prog memory footprint∼∝ # of ptr derefs∼

1–2 mem ref for bounds (may be cached),
check µ ops.

4 words per ptr∝ # of ptrs and allocations∼∝ # of ptr derefs∼

1–3 mem ref for bounds (may be cached),
check µ ops.

WatchdogLite [19]4 words per ptr∝ # of ptrs and allocations∼∝ # of ptr ops∼

1–3 mem ref for bounds (may be cached),
check & propagate insns.

Intel MPX [20]

2 words per ptr∝ # of ptrs∼

∝ # of ptr derefs∼

2+ mem ref for bounds (may be cached),
check & propagate insns.

BOGO [33]

2 words per ptr∝ # of ptrs∼

∝ # of ptr derefs∼

MPX ops + ptr miss exception handling,
page permission mods.

PUMP [9]64b per cache line

∝ Prog memory footprint∼∝ # of ptr ops∼

1 mem ref for tags, may be cached,fetch and chk rules; propagate tags.

CHERI [32]256b per ptr∝ # of ptrs and physical mem∼∝ # of ptr ops∼

1+ mem ref for capability (may be cached),
capability management insns.

CHERI concentrate [31]Ptr size is 2x∝ # of ptrs∼

∝ # of ptr ops∼

Wide ptr load (may be cached),
capability management insns.

∝ Prog memory footprint∼∝ Blacklisted memory∼∝ # of tag (un)set ops∼∝ # of ECC (un)set ops∼∝ Blacklisted memory∼∝ Blacklisted memory∼∝ # of arm/disarm insns∼∝ # of BLOC insns.
∼

SPARC ADI [21]4b per cache line

SafeMem [23]2x blacklisted memory

REST [28]

8–64B token

Califorms

Byte granular security byte

Main
Operations(Un)set tag.
Syscall to scramble ECC, copy data content.
Execute arm/disarm insns.
Execute BLOC insns.

Table 6: Implementation complexity comparison against previous hardware techniques.
ProposalCore

Caches/TLB

MemorySoftwareHardbound [8]µ op injection & logic for ptr meta,
extend reg file and data path topropagate ptr meta

Tag cache and its TLB

N/ACompiler & allocator annotates ptr meta

Watchdog [18]µ op injection & logic for ptr meta,
extend reg file and data path topropagate ptr meta

Ptr lock cache

N/A

Compiler & allocator annotates ptr meta

WatchdogLite [19]

N/A

N/A

N/A

Compiler & allocator annotates ptrs,
compiler inserts meta propagation and check insns

Intel MPX [20]Unknown (closed platform [27], design likely similar to Hardbound)Compiler & allocator annotates ptrs,
compiler inserts meta propagation and check insns

BOGO [33]Unknown (closed platform [27], design likely similar to Hardbound)

MPX mods + kernel mods for bounds page
right management

PUMP [9]Extend all data units by tag width,modify pipeline stages for tag checks,
new miss handler

Rule cache

N/A

Compiler & allocator (un)sets memory, tag ptrs

CHERI [32]Capability reg file, coprocessor
integrated with pipeline

Capability caches

N/A

Compiler & allocator annotates ptrs,
compiler inserts meta propagation and check insns

CHERI concentrate [31]Modify pipeline to integrate ptr checks

N/A

N/A

Compiler & allocator annotates ptrs,
compiler inserts meta propagation and check insns

SPARC ADI [21]Unknown (closed platform)

Compiler & allocator (un)sets memory, tag ptrs

SafeMem [23]

N/A

N/A

Repurposes ECC bits

Original data copied to distinguish from hardware faults

REST [28]N/A

1–8b per L1D line,
1 comparator

N/A

Compiler & allocator (un)sets tags,
allocator randomizes allocation order/placement

Califorms

N/A

8b per L1D line,
1b per L2/L3 line

Use unused/spare ECC bit

Compiler & allocator mods to (un)set tags,
compiler inserts intra-object spacing

MICRO-52, October 12–16, 2019, Columbus, OH, USA

REFERENCES[1] 2014. CVE–2014–1444. https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE2014-1444. [Online; accessed 30-Aug-2019].
[2] 2017. CVE–2017–5115. https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE2017-5115. [Online; accessed 30-Aug-2019].
[3] ARM. 2018. ARM A64 instruction set architecture for ARMv8-A architecture
profile. https://static.docs.arm.com/ddi0596/a/DDI_0596_ARM_a64_instruction_
set_architecture.pdf.
[4] Andrea Bittau, Adam Belay, Ali Mashtizadeh, David Mazi e res, and Dan Boneh.
2014. Hacking blind. In IEEE S&P ’14: Proceedings of the 35th IEEE Symposium on
Security and Privacy.
[5] Kees Cook. 2017. Introduce struct layout randomization plugin. https://lkml.org/lkml/2017/5/26/558.
[6] Crispin Cowan, Calton Pu, Dave Maier, Heather Hintony, Jonathan Walpole,
Peat Bakke, Steve Beattie, Aaron Grier, Perry Wagle, and Qian Zhang. 1998.
StackGuard: automatic adaptive detection and prevention of buffer-overflow
attacks. In USENIX Security ’98: Proceedings of the 7th USENIX Security Symposium.
[7] Brooks Davis, Khilan Gudka, Alexandre Joannou, Ben Laurie, A Theodore Markettos, J Edward Maste, Alfredo Mazzinghi, Edward Tomasz Napierala, Robert M
Norton, Michael Roe, Peter Sewell, Robert N M Watson, Stacey Son, Jonathan
Woodruff, Alexander Richardson, Peter G Neumann, Simon W Moore, John Baldwin, David Chisnall, James Clarke, and Nathaniel Wesley Filardo. 2019. CheriABI:
enforcing valid pointer provenance and minimizing pointer privilege in the POSIX
C run-time environment. In ASPLOS ’19: Proceedings of the 24th International
Conference on Architectural Support for Programming Languages and Operating
Systems.
[8] Joe Devietti, Colin Blundell, Milo M K Martin, and Steve Zdancewic. 2008. HardBound: architectural support for spatial safety of the C programming language.
In ASPLOS XIII: Proceedings of the 13th International Conference on Architectural
Support for Programming Languages and Operating Systems.
[9] Udit Dhawan, Catalin Hritcu, Raphael Rubin, Nikos Vasilakis, Silviu Chiricescu,
Jonathan M Smith, Thomas F Knight, Jr, Benjamin C Pierce, and Andre DeHon.
2015. Architectural support for software-defined metadata processing. In ASPLOS ’15: Proceedings of the 20th International Conference on Architectural Support
for Programming Languages and Operating Systems.
[10] Gregory J Duck and Roland H C Yap. 2018. EffectiveSan: type and memory error
detection using dynamically typed C/C++. In PLDI ’18: Proceedings of the 39th
ACM SIGPLAN Conference on Programming Language Design and Implementation.
[11] Lieven Eeckhout. 2010. Computer architecture performance evaluation methods(1st ed.).
[12] Nur Hussein. 2017. Randomizing structure layout. https://lwn.net/Articles/722293/.
[13] Yuseok Jeon, Priyam Biswas, Scott Carr, Byoungyoung Lee, and Mathias Payer.
2017. HexType: efficient detection of type confusion errors for C++. In CCS ’17:
Proceedings of the 24th ACM SIGSAC Conference on Computer and Communications
Security.
[14] Lizy Kurian John. 2004. More on finding a single number to indicate overall
performance of a benchmark suite. ACM SIGARCH Computer Architecture News32, 1 (March 2004), 3–8.
[15] Paul Kocher, Daniel Genkin, Daniel Gruss, Werner Haas, Mike Hamburg, Moritz
Lipp, Stefan Mangard, Thomas Prescher, Michael Schwarz, and Yuval Yarom. 2019.
Spectre attacks: exploiting speculative execution. In IEEE S&P ’19: Proceedings ofthe 40th IEEE Symposium on Security and Privacy.
[16] Kangjie Lu, Chengyu Song, Taesoo Kim, and Wenke Lee. 2016. UniSan: proactive
kernel memory initialization to eliminate data leakages. In CCS ’16: Proceedingsof the 23rd ACM SIGSAC Conference on Computer and Communications Security.

H. Sasaki, M. Arroyo, M. Tarek Ibn Ziad, K. Bhat, K. Sinha, and S. Sethumadhavan[17] Alyssa Milburn, Herbert Bos, and Cristiano Giuffrida. 2017. SafeInit: comprehensive and practical mitigation of uninitialized read vulnerabilities. In NDSS ’17:
Proceedings of the 2017 Network and Distributed System Security Symposium.
[18] Santosh Nagarakatte, Milo M K Martin, and Steve Zdancewic. 2012. Watchdog:
hardware for safe and secure manual memory management and full memory
safety. In ISCA ’12: Proceedings of the 39th International Symposium on Computer
Architecture.
[19] Santosh Nagarakatte, Milo M K Martin, and Steve Zdancewic. 2014. WatchdogLite: hardware-accelerated compiler-based pointer checking. In CGO ’14:
Proceedings of the 12th IEEE/ACM International Symposium on Code Generation
and Optimization.
[20] Oleksii Oleksenko, Dmitrii Kuvaiskii, Pramod Bhatotia, Pascal Felber, and Christof
Fetzer. 2018. Intel MPX explained: a cross-layer analysis of the Intel MPX system
stack. Proceedings of the ACM on Measurement and Analysis of Computing Systems
2, 2 (June 2018), 28:1–28:30.
[21] Oracle. 2015. Hardware-assisted checking using Silicon Secured Memory (SSM).
https://docs.oracle.com/cd/E37069_01/html/E37085/gphwb.html.
[22] Harish Patil, Robert Cohn, Mark Charney, Rajiv Kapoor, Andrew Sun, and Anand
Karunanidhi. 2004. Pinpointing representative portions of large Intel® Itanium®
programs with dynamic instrumentation. MICRO-37: Proceedings of the 37th
IEEE/ACM International Symposium on Microarchitecture.
[23] Feng Qin, Shan Lu, and Yuanyuan Zhou. 2005. SafeMem: exploiting ECC-memoryfor detecting memory leaks and memory corruption during production runs. In
HPCA ’05: Proceedings of the IEEE 11th International Symposium on High Performance Computer Architecture.
[24] Daniel Sanchez and Christos Kozyrakis. 2013. ZSim: fast and accurate microarchitectural simulation of thousand-core systems. In ISCA ’13: Proceedings of the40th International Symposium on Computer Architecture.
[25] Konstantin Serebryany, Derek Bruening, Alexander Potapenko, and Dmitry
Vyukov. 2012. AddressSanitizer: a fast address sanity checker. In USENIX ATC ’12:
Proceedings of the 2012 USENIX Annual Technical Conference.
[26] Kostya Serebryany, Evgenii Stepanov, Aleksey Shlyapnikov, Vlad Tsyrklevich,and Dmitry Vyukov. 2018. Memory tagging and how it improves C/C++ memory
safety. arXiv.org (Feb. 2018). arXiv:cs.CR/1802.09517v1[27] Junjing Shi, Qin Long, Liming Gao, Michael A. Rothman, and Vincent J. Zimmer.
2018. Methods and apparatus to protect memory from buffer overflow and/or
underflow. International patent WO/2018/176339.
[28] Kanad Sinha and Simha Sethumadhavan. 2018. Practical memory safety with
REST. In ISCA ’18: Proceedings of the 45th International Symposium on Computer
Architecture.
[29] Dokyung Song, Julian Lettner, Prabhu Rajasekaran, Yeoul Na, Stijn Volckaert,
Per Larsen, and Michael Franz. 2019. SoK: sanitizing for security. In IEEE S&P ’19:
Proceedings of the 40th IEEE Symposium on Security and Privacy.
[30] David Weston and Matt Miller. 2016. Windows 10 mitigation improvements.
Black Hat USA.
[31] Jonathan Woodruff, Alexandre Joannou, Hongyan Xia, Anthony Fox, Robert
Norton, David Chisnall, Brooks Davis, Khilan Gudka, Nathaniel W Filardo, ,A Theodore Markettos, Michael Roe, Peter G Neumann, Robert Nicholas Maxwell
Watson, and Simon Moore. 2019. CHERI concentrate: practical compressedcapabilities. IEEE Trans. Comput. 68, 10 (Oct. 2019), 1455–1469.
[32] Jonathan Woodruff, Robert N M Watson, David Chisnall, Simon W Moore,
Jonathan Anderson, Brooks Davis, Ben Laurie, Peter G Neumann, Robert Norton,and Michael Roe. 2014. The CHERI capability model: revisiting RISC in an age ofrisk. In ISCA ’14: Proceedings of the 41st International Symposium on Computer
Architecture.
[33] Tong Zhang, Dongyoon Lee, and Changhee Jung. 2019. BOGO: buy spatial memory safety, get temporal memory safety (almost) free. In ASPLOS ’19: Proceedingsof the 24th International Conference on Architectural Support for Programming
Languages and Operating Systems.