Clean Application Compartmentalization with SOAAP

Khilan Gudka Robert N.M. Watson Jonathan Anderson University of Cambridge University of Cambridge Memorial University Cambridge, UK Cambridge, UK St. Johns, NL, Canada [email protected] [email protected] [email protected] David Chisnall Brooks Davis Ben Laurie University of Cambridge SRI International Google UK Ltd. Cambridge, UK Menlo Park, CA, USA London, UK [email protected] [email protected] [email protected] Ilias Marinos Peter G. Neumann Alex Richardson University of Cambridge SRI International University of Cambridge Cambridge, UK Menlo Park, CA, USA Cambridge, UK [email protected] [email protected] [email protected]

ABSTRACT ploitation of vulnerabilities. It seeks to employ the prin- Application compartmentalization, a vulnerability mitiga- ciple of least privilege by granting each compartment only tion technique employed in programs such as OpenSSH and the rights that it requires to operate [37]. It is used in the Chromium web browser, decomposes software into iso- software ranging from OpenSSH [35] to the Chromium web lated components to limit privileges leaked or otherwise browser [36] to limit rights available to an attacker follow- available to attackers. However, compartmentalizing appli- ing a successful exploit. Recently disclosed vulnerabilities cations – and maintaining that compartmentalization – is such as [29], Shellshock [31], and a symlink at- hindered by ad hoc methodologies and significantly increased tack vulnerability in Wget [30], illustrate the importance of programming effort. In practice, programmers stumble protecting software not just from known exploit techniques through (rather than overtly reason about) compartmental- (e.g., stack canaries mitigating buffer overflows), but also ization spaces of possible decompositions, unknowingly trad- from unknown future classes of vulnerabilities. ing off correctness, security, complexity, and performance. Application compartmentalization proves surprisingly We present a new conceptual framework embodied in an subtle: contrary to the implied suggestion of simplistic de- LLVM-based tool: the Security-Oriented Analysis of Appli- scriptions (“Application X has been privilege separated”), cation Programs (SOAAP) that allows programmers to rea- there are many possible compartmentalizations of most pro- son about compartmentalization using source-code annota- grams within a compartmentalization space that reflects dif- tions (compartmentalization hypotheses). We demonstrate ferent tradeoffs among correctness, security, complexity, and considerable benefit when creating new compartmentaliza- performance. Selecting a suitable point in this space is tions for complex applications, and analyze existing com- challenging, as implementing compartmentalization requires partmentalized applications to discover design faults and considerable effort and can disrupt code structure. This maintenance issues arising from application evolution. choice is crucial, as it can be difficult to change strategy after implementation: the non-trivial code changes made to application structure are often specific to the selected com- Categories and Subject Descriptors partmentalization. Design choices and tradeoffs are infre- D.4.6 [Operating Systems]: Security and Protection quently revisited – even as understanding of program secu- rity grows due to discovered vulnerabilities, or as program Keywords functionality evolves beyond its compartmentalization. Reasoning about compartmentalization tradeoffs is diffi- Security, Compartmentalization, Vulnerability Mitigation cult for many reasons. Information about past vulnerabil- ities – often a good predictor of future vulnerabilities – is 1. INTRODUCTION not easily accessible. Call graphs of compartmentalized ap- Application compartmentalization decomposes software plications are extremely complex, and simple control-flow into isolated but collaborating components to mitigate ex- analysis cannot follow manually encoded cross-domain ac- tions – typically via Inter-Process Communication (IPC) – Permission to make digital or hard copies of all or part of this work for personal or found in real-world applications. Even where call graphs classroom use is granted without fee provided that copies are not made or distributed can be extracted, control flow is only a starting point: in for profit or commercial advantage and that copies bear this notice and the full citation on the first page. Copyrights for components of this work owned by others than the the compartmentalization adversary model, naively written author(s) must be honored. Abstracting with credit is permitted. To copy otherwise, or code may be vulnerable, but it is exposure to malicious data republish, to post on servers or to redistribute to lists, requires prior specific permission that causes exploits – requiring reasoning about a combi- and/or a fee. Request permissions from [email protected]. nation of vulnerabilities, information flow from dangerous CCS’15 October 12–16, 2015, Denver, Colorado, USA. sources, and uncompartmentalized code. Application fail- Copyright is held by the owner/author(s). Publication rights licensed to ACM. ures due to compartmentalization are frequently mysterious: ACM 978-1-4503-3832-5/15/10$15.00 DOI: http://dx.doi.org/10.1145/2810103.2813611. the libraries they link against are often designed without the expectation of sandboxing, and failures may not be detected 2. CONCEPTUAL FRAMEWORK by testing. Finally, performance characteristics are critical, Application compartmentalization rests on the principle of with compartmentalization boundaries often selected that least privilege: compromised components yield fewer rights are not based on ideal security boundaries, but rather on ac- to attackers, and offer fewer opportunities to compromise the ceptable performance (e.g., in Capsicum where gzip rather rest of the system. Karger first proposed using access con- than zlib is sandboxed [41]). Even then, performance im- trol for vulnerability mitigation while working on capability pacts are difficult to predict. systems [18], and took as his threat model the trojan horse: Application developers would ideally be able to explore subverted software working on behalf of the adversary. Con- how new or changing compartmentalization would affect fac- temporary compartmentalization for vulnerability mitiga- tors such as security and performance without paying the full tion, sometimes referred to as privilege separation, saw its cost of implementation, letting them more easily identify a foundations in work by Provos et al. [35] and Kilpatrick [19], preferred spot in the compartmentalization space. For ex- and has been applied to complex, security-relevant programs ample, partitioning decompression from decryption can pre- such as OpenSSH and the Chromium web browser, both of vent decompression-related vulnerabilities from leaking key- which hold substantial effective privilege and perform com- ing material – but at great costs to both code complexity plex processing of untrustworthy, network-originated data. and run-time performance. The overhead of this compart- Compartmentalization adopts a de facto, and quite strong, mentalization may be too high for production use, requiring threat model in which attackers gain total control of com- another approach, such as having per-client compartments. promised compartments as a result of poorly crafted C code This exploration is comparable to the use of performance- (or other program weaknesses) being being exposed to ma- profiling tools to identify the hot spots in an application licious input. For example, buffer-overflow attacks triggered that would benefit most from optimization. Similarly, se- by network input might allow malicious code to be executed, curity profiling tools could enable the developer to deter- or program control flow to be fully subverted by the at- mine whether a particular compartmentalization was “worth tacker. We generalize this model, adding software supply- it”, namely that it would give sufficient security gains while chain vulnerabilities involving explicitly trojaned software not exceeding tolerable performance overheads. Such an ap- without the need for malicious input – e.g., back doors be- proach would also allow continuous automatic reevaluation ing inserted following compromise of a software vendor’s as application source code evolves, ensuring that, for exam- source-code repository. Weaker attacks, which fall short of ple, refactorings do not accidentally move vulnerable code arbitrary code execution, are also important: the OpenSSL to a more privileged context. To this end, this paper: Heartbleed vulnerability allows read access to victim mem- • Describes a conceptual framework for compartmental- ory, which might reveal keys allowing further access, but ization grounded in isolation and controlled communi- does not immediately allow arbitrary manipulation. cation. Possible program compartmentalizations, each Compartmentalization rests on three underpinnings: a with differing design tradeoffs in terms of complexity, strong Trusted Computing Base (TCB) able to protect its performance, security, and functionality, exist within own integrity [2]; compartment isolation (implemented by compartmentalization spaces. We also describe a set of the TCB), which provides strong prevention of interference compartmentalization design patterns reflecting com- between isolated program instances [10]; and controlled com- mon approaches to compartmentalization. munication, which allows safe communication between com- partments – subject to suitable policies. Applications may, • Presents the Security-Oriented Analysis of Application themselves, construct application-specific TCBs on top of Programs (SOAAP), an LLVM-based tool for evaluat- the compartmentalization substrate – for example, compo- ing proposed (or extant) compartmentalizations based nents that run with ambient authority, or that store sensitive on annotated compartmentalization hypotheses, which keying material, etc. – but for our purposes, TCB refers to document programmer expectations and designs for mechanisms underlying compartmentalization itself. compartmentalization and security. Source-code anno- tations represent sandboxing strategies, cross-domain 2.1 Isolation communication, past vulnerabilities, sensitive or risky Mechanisms for isolation vary, but will often be an data, and security goals. SOAAP scales to multi- operating-system (OS) process model based on a hardware million-LoC applications, providing efficient control- Memory Management Unit (MMU). The conventional OS flow and information-flow analysis of whole programs. process model limits the scope of accidental damage from • Demonstrates the effectiveness of our approach buggy programs, and also provides modest (often discre- through analysis of existing real-world compartmen- tionary) isolation between users to limit the damage mali- talizations – including OpenSSH and the Chromium cious user can cause to other users. To construct stronger web browser – and discover bugs that were introduced isolation, other access control mechanisms are used to nar- by developing these without the aid of a SOAAP-like row down access to system resources. For example, across tool. We also show the use of SOAAP in adding new various systems, OpenSSH uses mechanisms such as chroot, compartmentalization to two existing applications: Linux seccomp, SELinux [24], Mac OS X [40], and Cap- FreeBSD’s fetch and the Okular document viewer sicum [41] to restrict the OS facilities available to its com- from KDE. SOAAP has identified various weaknesses, partments. The literature sometimes refers to a constrained including untrustworthy code unexpectedly executed process as a sandbox, but we prefer the term compartment as outside of sandboxes, and provides a new methodol- ‘sandbox’ is often taken to refer to the near total isolation of ogy for evaluating software compartmentalization. a whole application (or component) rather than being part of a more nuanced decomposition in which processes may be delegated more subsets of (perhaps quite powerful) rights. Pattern Description Sandboxing Compartments handling untrustworthy data or executing untrustworthy code are delegated minimal rights – e.g., for web-page rendering [18, 12, 27, 39, 36]. Assured pipelines A series of linked compartments perform staged processing of data while limiting the access of (and exposure of) compartments in the chain – e.g., when processing protocol stages between two firewall interfaces [7]. Horizontal compartmentalization Compartments contain multiple instances of the same code operating on different data instances – e.g., one sandbox for each image processed [42]. Vertical compartmentalization Compartments encapsulate different layers when performing a task – e.g., isolating web-page download from rendering [42]. Temporal compartmentalization Reuse of compartments over time is avoided to prevent loss of confidentiality for prior tasks, and loss of integrity or availability for later tasks [42]. Work-bounded compartmentalization Compartments are permitted to perform bounded work, limiting potential denial- of-service impact (e.g., following a control-flow exploit) [42]. Library compartmentalization Compartmentalization occurs entirely ‘behind’ an existing API, allowing a library to isolate its processing while leaving programming and binary interfaces unper- turbed – e.g., placing compartmentalization in zlib rather than in gzip [41, 42].

Table 1: Common compartmentalization design patterns found across a broad range of compartmentalized systems.

Not all compartmentalization substrates are created sources outside the compartmentalized application (e.g., an equal. seccomp and Capsicum are both available to unprivi- open file descriptor), rights that represent the ability to com- leged processes, and intended to support extremely limited municate within the compartmentalized application (e.g., a access for isolated processes. In contrast, chroot depends local domain socket allowing message passing with another on OS privilege to use (requiring, for example, Chromium compartment), and data itself (which may flow via either to have a setuid helper), but constrains only unprivileged of these mechanisms). The initial and ongoing configura- processes. Further, chroot limits access only for the filesys- tions of these rights and data are critical to reasoning about tem namespace (unless extended via a mechanism such as the security state of an application (and to the protective FreeBSD jails [17]), leaving (on many systems) interfaces properties of compartmentalization) as any communication for several forms of IPC, and also administrative interfaces, right not delegated to a compartment is an attack surface available to notionally isolated processes. Differing delega- avoided, in terms of potential exploits to gain privilege, and tion mechanisms used to assign rights to compartments can also opportunities for denials of service. Data itself presents also prove challenging for programmers: whereas Capsicum a number of problems from the perspective of confidentiality allows system calls to be refined on a per-file-descriptor ba- and integrity. When a compartment has been compromised, sis, but a fixed set of permitted system calls, seccomp pro- it may have current access to confidential data, either in its vides a configurable filter on system calls, but not the abil- memory space or via rights it holds, as well as residual data ity to refine rights on particular file descriptors. These and from earlier execution. Likewise, a compromised compart- other differences (e.g., with respect to SELinux and Mac ment affects the integrity of future computations performed OS X) present a substantial challenge to the authors of in the compartment, which in turn impacts the confidential- portable applications, who must implement compartmental- ity and integrity of data that may later be received. ization over different substrates, and hence may experience variable expressiveness and mitigation properties. 2.3 Compartmentalization patterns Compartmentalization is a general technique that config- 2.2 Controlled communication ures a network of communication and delegated rights be- Controlled communication allows compartments to com- tween “cuts” in an application. Many compartmentalized municate both with the OS and one another. This commu- applications turn out to implement similar portable patterns. nication takes the form of a call gate: a call between com- The sandboxing pattern, for example, delegates as few rights partments that provides mediated access to a well-defined as possible to compartments processing high-risk data – e.g., set of entry points in a piece of code running with different a web-browser renderer that is able to send data to the dis- privileges. This allows subsets of global system rights to be play and receive limited input. By delegating only limited delegated to compartments, providing access to data or stor- rights to the sandbox – e.g., a connected socket and output age required for computation (e.g., a web-browser cache), or file rather than global access to the filesystem – vulnerabil- the ability to connect sockets to remote systems. Also im- ities in the sandboxed code, such as bugs in TLS process- portant are intra-application rights; for example, different ing, can be mitigated. Table 1 illustrates a set of common compartments within applications might have different ex- patterns [42]. We expect many further design patterns will posure to malicious data, with those protecting access to emerge as compartmentalization sees further deployment. critical information (e.g., user payment details or private keys) providing only narrowly constrained interfaces to com- 2.4 Compartmentalization spaces partments at greater risk (e.g., those rendering web pages). Compartmentalization spaces, illustrated in Figure 1, are A key concern in compartmentalized systems is the ex- a key concept: applications may be partitioned in many dif- plicit or implied delegation of data rights, which may be con- ferent ways, requiring compartments to have more or fewer sidered in three classes: OS rights that represent access to re- rights, and distributing both code of varying risk, as well Code-centered compartmentalization

1. fetch 2. fetch 3. fetch 4. fetch main loop main loop main loop main loop

ftp http ftp http ftp http ftp http auth http get FTP FTP HTTP FTP HTTP auth HTTP GET sandbox sandbox sandbox sandbox sandbox sandbox network tls tls sandbox HTTPS sandbox tls TLS tls sandbox 5. fetch TLS main loop sandbox

http ftp

tls Data-centered compartmentalization URL-specific sandbox URL-specific sandbox Object-oriented URL-specific sandbox compartmentalization

Figure 1: fetch and libfetch can be compartmentalized along different dimensions, offering different tradeoffs. as access to data of varying degrees of risk and sensitivity, further points become more accessible – e.g., further sub- around the compartment graph. The figure illustrates two division of existing compartments, or those that introduce possible dimensions of further refined compartmentalization greater data-centered granularity – but most will now re- for FreeBSD’s fetch/libfetch, a command-line HTTP/FTP quire greater application refactoring. file retrieval tool and supporting library: data-centered com- partmentalization, in which different instances of data, pro- 3. THE SOAAP ANALYSIS TOOL cessed by the same code, will be isolated from another; Application compartmentalization is a powerful vulner- and code-centered compartmentalization, in which different ability mitigation technique, but it can require substantial code components are isolated from one another. Combined, program refactoring and careful reasoning about interactions these may be viewed as object-oriented compartmentaliza- with the underlying isolation and communication substrates. tion, which provides a more granular decomposition. For To help developers explore the implications of current or fetch, data-centered compartmentalization might process planned compartmentalization more easily, we have devel- the contents of different sites, or even different URLs, in oped Security-Oriented Analysis of Application Programs their own sandbox, preventing cross-contamination with re- (SOAAP), a tool implemented using LLVM [21]. Figure 2 spect to confidentiality, integrity, and availability. Code- illustrates the SOAAP workflow. SOAAP accepts, as in- centered compartmentalization also offers benefits: by iso- put, C/++ source code annotated with compartmentaliza- lating different phases of TLS, vulnerabilities granting ac- tion hypotheses. The annotations may originate with the cess to a TLS session key need not, for example, provide the code author or, commonly, a third party retrofitting code attacker access to a client-side certificate. with compartmentalization after vulnerabilities are discov- Different points in an application’s compartmentalization ered. They may include: space offer markedly different correctness, complexity, se- • Code that should run in a sandbox. This may be entire curity, and performance. Correctness is particularly im- functions or a portion of a function. pacted by distributed-system problems: data replicated be- tween compartments may fall out of sync, leading to bugs. • Global state that should be accessible to sandboxes Greater compartmentalization often implies greater com- together with the types of accesses allowed. plexity, due to the need to select suitable rights to delegate • File descriptors that sandboxes can access and what to each compartment, but also because compartments may operations are allowed on them. not naturally align with an application’s class structure. Se- • System calls that sandboxes can perform. curity is a key concern: vulnerabilities are mitigated only • Call gates available to sandboxes for performing priv- if rights assigned to compartments are limited. Predicting ileged operations. the location of future vulnerabilities is an art rather than • Information-flow restrictions – for example, that cer- a science, but notions of risky code (e.g., string parsing in tain data should not leak out of, or into, a sandbox. C), and also the history of past vulnerabilities in code, often • Information-flow relaxations for declassification and motivate software components in sandboxes. For example, explicitly-permitted flows, e.g., transmitting a pass- it is common to place compression and video CODECs in word hash for authentication. sandboxes. Finally, performance is also critical: selecting • Performance overhead goals. “unnatural” cuts within applications may lead to substan- • Past-vulnerability information. tial performance overheads resulting from frequent domain crossings or the need to copy (rather than delegate a right SOAAP also takes descriptions of sandboxing platforms to) data. The latter may be due to mismatches between API that capture the protection provided – e.g., which system design and rights delegated between compartments. calls are allowed within a sandbox, at what granularity file The effort required to compartmentalize a program means accesses can be restricted, and whether sandboxes are com- that adopting a particular point in the design space is a sub- pletely isolated from one another or inter-sandbox communi- stantial commitment. Once a point is implemented, some cation might be permitted. These descriptions allow trade- offs to be compared across different sandboxing technologies. SOAAP toolchain

static dynamic SOAAP inputs LLVM Callgraph Clang analysis Application and library Link-time annotation taint, vuln., callgraph SOAAP outputs App source code processing Perform. analysis author simulation Application Past change Compartmentalization vulnerability and hypotheses as source Informatio Security analysis hypothesis code annotations n fow developer refnement analysis Call graph recommendations analysis Sandbox Performance characterization analysis OS vendor

Figure 2: SOAAP engages the developer in an iterative cycle of hypothesis development and testing. SOAAP uses LLVM’s Clang front end to compile the an- int l_flag = 0;// list file contents notated program into LLVM’s intermediate representation int main(int argc, char** argv) { (IR). Source files are compiled to individual IR files before l_flag = read_arg("l"); being statically linked together into a single application IR char* in, out; file for analysis. SOAAP assumes a closed world, meaning while ((in = process_next_file())) { that all dependencies whose behavior should be analyzed out = in_to_out(in); must be statically linked with the main program’s IR. Most int ifd = open(in, O_RDONLY); of SOAAP’s analysis is static, to check whole-program be- int ofd = open(out, O_WRONLY); dec2(ifd, ofd); havior. We model the structure and behavior of the program } by building a compartmentalization control- and data-flow return 0; graph. This captures the distributed nature and different se- } curity domains that would be present in the proposed com- partmentalization. SOAAP performs dynamic analysis to void dec2(int ifd, int ofd) { evaluate performance prior to implementation by simulat- // decrypt input to tmp file char key[256]; ing sandbox management and cross-domain communication read_stdin("Password:", key); costs to measure execution overhead. If this overhead ex- //... ceeds annotated performance goals, a warning is given. Un- char* tmp = tmp_file(); like static analysis, the results of performance simulation will int tfd = open(tmp, O_RDWR); typically be sensitive to input parameters; representative re- //... sults require multiple runs with representative workloads. read(ifd, buffer, buffer_size); //... The SOAAP workflow engages the programmer in an it- if (l_flag) {// list contents erative dialog as the compartmentalization approach is re- //... fined: programmers may initially annotate sandbox bound- } else{ aries and then add or remove these and other annotations as // decompress tmp to output file they learn more about the compartmentalization. This cycle //... is comparable to the regular iteration of a developer correct- } } ing warnings through successive compiler passes. SOAAP can also be used in a continuous integration environment Listing 1: Example program that decrypts and decompresses to validate that changes in program structure and compart- files. Passing -l allows only listing the archive contents. mentalization do not introduce regressions over the longer- tion isolates the dec2() function, which would prevent an term application life cycle. SOAAP may not identify all attacker from gaining access to the global filesystem names- possible shortcomings in a proposed approach, and it can- pace. We annotate a persistent sandbox, i.e., a reusable not make design decisions, but it can help developers express global sandbox, with the name dec2: compartmentalization choices and understand their impacts. __soaap_sandbox_persistent("dec2") 3.1 SOAAP workflow example void dec2(int ifd, int ofd) ; To demonstrate SOAAP’s workflow, we annotate and an- We also annotate that this sandboxed compartment will be alyze a simple program that decrypts and decompresses files created at the start of main(), which allows SOAAP to un- (see Listing 1). Passing -l lists only archive contents. derstand the implications of sandboxes created via fork(). 3.1.1 Specifying sandbox boundaries The subsequent sections present some of SOAAP’s output. Developers begin by annotating code that should run 3.1.2 Finding data dependencies within a sandboxed compartment, the kind of sandbox, and An initial run of SOAAP identifies that a global variable when it should be created. For our example, both decryp- is read by the dec2 sandbox: tion and decompression are known to be frequent sources of security vulnerabilities. One possible compartmentaliza- * Sandboxed method "dec2" * [dec2] read global variable "l_flag" * "open" but it is not allowed to, based * but has not been granted the right to * on the current sandboxing restrictions. + Line 70 of file dec2.c + Line 35 of file dec2.c The programmer must determine whether such accesses are * Sandbox "dec2" performs system call intended. If not, then the sandbox scope may need to be * "read" but is not allowed to for the reassessed or code refactored. In this case, the access is * given fd arg. intended, so we inform SOAAP through an annotation: + Line 45 of file dec2.c __soaap_var_read("dec2") The first warning is specific to the Capsicum model: open- int l_flag = 0; ing the temporary file will not work in a Capsicum sandbox. The second is more general, indicating that read() will fail Running SOAAP again now identifies a potential data- on the file descriptor passed into the sandbox as an integer, consistency bug that arises because l_flag is initialized to a because the parent and child process will have different file- command-line argument after the compartment is created: descriptor tables. We can declare that we will delegate the * Write to shared variable "l_flag" in read capability by annotating the input file descriptor with * method "main" may not be seen by the __soaap_fd_permit(read). * sandboxes: [dec2] + Line 4 of dec2.c 3.1.5 Past vulnerabilities and supply-chain attacks If the compartment were realized as a UNIX process, a bug The number of mitigated past vulnerabilities is a useful would result: fork() copies global variables from the parent measure for how effective a proposed compartmentalization to the child, and modifications to globals after the fork will might be. Annotating past vulnerabilities is not only worth- not be seen in the compartment. The developer must thus while documentation but SOAAP can use these annotations ensure, when implementing this compartmentalization, that to inform which are mitigated. SOAAP is able to enumer- the sandbox receives the correct value of l_flag. Otherwise, ate the rights an attacker would gain if another vulnerability the archive will be decompressed even when the user just were to be exploited there. We annotate a fictitious CVE in wants to list the contents! This error is similar in nature to the decryption portion of our example: that we discovered during the original Capsicum-based com- // decrypt input to tmp file partmentalization of gzip, in which gzip performed faster //... with sandboxing than without. This unlikely result was due __soaap_vuln_pt("CVE-XXXX-YYYY") to the compression level not being propagated to the sand- SOAAP is now able to report on the effects of compartmen- boxed child, leading to lower (hence faster) compression be- talization directly, showing the leaked rights: ing applied [41]. *** Sandboxed function "dec2" [dec2] 3.1.3 Finding information leaks *** has past-vulnerability annotations for The dec2 sandbox handles sensitive keying material. An *** [CVE-XXXX-YYYY]. Another vulnerability important security goal might be to ensure that it cannot *** here would not grant ambient authority *** to the attacker but would leak the leak out of the sandbox, which we can express as: *** following restricted rights: char key[256] __soaap_private; +++ Call [read] on file descriptor "ifd" +++ Call [write] on file descriptor "ofd" SOAAP informs us that our key could leak through several ... extern library functions whose behavior we know nothing Relevant vulnerabilities are not limited to just the applica- about. If we are certain these functions are safe, we can tion being annotated but also its dependencies, as exploiting annotate them as such. SOAAP also identifies that reuse of them would also give the attacker control of the application. the sandbox could leak an earlier key, as the key buffer is SOAAP allows hypothesizing the occurrence of vulnerabil- not scrubbed. One solution would be to zero out the buffer ities in specific libraries or a particular vendor’s code (so- before returning from the sandbox; another might be to use called supply-chain trojans): an ephemeral sandbox instead. The former prevents against accidental leakage, but could be bypassed by an attacker $ soaap --vulnerable-libs=libc ... able to compromise the sandbox. The latter approach pro- $ soaap --vulnerable-vendors=badvendor ... vides more security, but at the cost of having to create and SOAAP will again provide feedback on rights that might be destroy sandboxes more frequently. leaked by the application. We provide details about this in 3.1.4 Finding required privileges our technical report [13]. SOAAP uses platform descriptions to reason about sand- 3.2 SOAAP’s analysis box restrictions, allowing the programmer to understand what can be executed by each sandbox. For example, 3.2.1 Sandbox-platform descriptions sandboxes are allowed to perform any system call, chroot() An important SOAAP design goal is to aid in the de- whereas permits only , , seccomp read() write() sigreturn() velopment of portable compartmentalized applications. As and . Capsicum may require explicit capabilities on exit() discussed in Section 2, different OSes provide markedly dif- file descriptors to be able to perform operations on their ferent isolation primitives with different security proper- corresponding files. We tell SOAAP to model Capsicum be- ties that can impact the semantics of compartmentaliza- havior with our example, and it reports: tion. SOAAP’s platform descriptions identify the function- * Sandbox "dec2" performs system call ality and protection properties provided by platforms such as Capsicum and seccomp. The descriptions, implemented ported to Solaris, but is not guaranteed by most UNIX IPC as C++ classes passed to the SOAAP analysis, also include mechanisms; latency will increase considerably if other pro- performance and communication models. cesses are scheduled between IPC send and reply. The performance emulation in SOAAP is intended as a 3.2.2 Data-flow analysis prototyping tool, giving a rough overview of whether a par- SOAAP implements a data-flow framework that can per- ticular compartmentalization strategy will incur huge over- form both may and must as well as flow sensitive and flow- heads, rather than as a modeling tool to determine exactly insensitive analysis, depending upon the type of analysis and what the overheads will be on a specific system. precision required. It uses the control-flow and call graphs computed by LLVM. For information flow analyses, such as 4. EVALUATION for tracking sensitive data or file descriptors, SOAAP tracks The purpose of SOAAP is to allow developers to reason explicit flows along define-use chains. Analyses are sandbox about (and evaluate) current and potential future compart- sensitive, meaning that data-flow propagation within one mentalizations of software. We demonstrate three aspects of sandbox is distinct from that of another, even if they con- SOAAP: that a diverse array of practical compartmentaliza- tain overlapping code. This enables us to model the different tions (and compartmentalization technologies) map into the security domains of proposed compartmentalizations. SOAAP model; that a relatively sparse and maintainable One of the challenges in analyzing C/C++ programs is set of annotations produce immediately useful results when that function pointers and polymorphism mean that the a SOAAP analysis is applied; and that SOAAP performs targets of a function call can be unclear. For static anal- and scales sufficiently well so as to be a practical addition to ysis to be safe, it must approximate all possible behaviors of a contemporary software development environment, whether the program, which means knowing which functions will be as part of live builds or a continuous integration setup. We called. One approach is to assume that any plausible func- therefore consider a series of practical compartmentalization tion could be invoked (i.e., a function pointer could refer case studies that explore both fresh compartmentalizations to any function that has its address taken, or any instance (of fetch and KDE’s Okular), as well as existing compart- method in the case of C++ – both assuming type compat- mentalizations (of OpenSSH and Chromium). ibility). However, this can be overly conservative, and lead We ran our benchmarks on a server with a 4-core Intel to imprecise analysis results. Xeon E5-1620 3.6GHz CPU, 64GB of RAM, and a 500GB SOAAP infers function-pointer targets by tracking assign- SSD running FreeBSD/amd64 10.1-RELEASE-p5 [25]. We ments, and also allows the programmer to explicitly anno- disabled hyper-threading and used four cores (passing -j4 tate callees. For C++, it builds a static class hierarchy to make and ninja) when building. using static type information obtained from Clang’s AST and vtable metadata present in the LLVM IR. SOAAP then 4.1 Fetch: design-space exploration performs Class Hierarchy Analysis (CHA) [9] to calculate FreeBSD’s fetch application is an ideal candidate for the set of potential targets of a virtual method call, i.e., by compartmentalization. It performs risky operations such finding all method definitions in the class hierarchy rooted as URL/HTTP header parsing and implements TLS via at the receiver object’s static type. OpenSSL. It also runs with full user privileges, often the system superuser. Finally, fetch may hold sensitive data, 3.2.3 Performance simulation such as credentials for file servers and proxy servers. With SOAAP instruments an application at relevant points many potential vulnerabilities and mutually untrusting par- based on the hypothesis. For a persistent sandbox, we fork a ties, fetch encapsulates much of the design-space tradeoff of single process when the __soaap_create_persistent_sandbox monolithic applications such as mail readers, web browsers, annotation is reached. For ephemeral sandboxes, we fork and office suites. We use SOAAP to explore two points in the and terminate a process at the start and end of the entry design space space: compartmentalizing URL parsing and point function. There are other models that could be used, executing all network code in a single compartment. Using such as a zygote process, but we leave these for future work. SOAAP, we validated our hypotheses and simulated perfor- SOAAP emulates communication between compartments mance, then implemented the actual compartmentalizations by sending RPC messages (implemented as synchronous and compared their behavior with SOAAP’s predictions. messages sent via a UNIX pipe). Overhead is measured using clock_gettime. The performance simulation is an esti- 4.1.1 URL parsing mate: it will necessarily contain errors. URL parsing is a small fraction of fetch’s code, but it One source of error relates to overhead. SOAAP cur- is a well-known source of vulnerabilities (e.g., CVE-2010- rently models sandbox creation as a constant cost, but true 1663, CVE-2010-2179 and CVE-2012-0641). This makes it compartmentalization costs are non-linear in the number of an excellent target for incremental, greedy compartmental- sandboxes as contention triggers TLB and cache misses. ization. We expressed this hypothesis by annotating the A second source of error is the varying cost of IPC. function fetchParseURL() with __soaap_sandbox_persistent SOAAP simulates IPC cost by sending a simulated payload and the url struct’s password field with __soaap_classify. through a real IPC channel and measuring the round-trip An initial run of SOAAP warns us about global vari- time. This measures the cost of data transmission, but may able accesses. Checking and annotating these global vari- not accurately capture scheduler interaction. When a pro- ables as being accessible to the URL parser, SOAAP sug- cess sends a synchronous message to another, an ideal sched- gests we should propagate the value of the global variable uler would immediately switch to the receiving process and fetchLastErrCode back to the privileged parent, as well as then switch back on reply. This policy was explicit in the the value of fetchDebug to the sandbox. SOAAP also warns Spring [14] microkernel’s Doors mechanism, which was later about sharing sensitive state between sandbox invocations: * Variable "u" (fetch.c:345) contains 6 * sensitive information, but is not vanilla c-net c-parse s-net s-parse * erased before leaving the sandbox. * Reusing the sandbox could allow 4 * another request to access this data. This compartmentalization is fairly straightforward, as the sandbox does not require any rights to execute. We must Time (ms) 2 only ensure that state is propagated between the sandbox and privileged parent, and to scrub sensitive data before leaving the sandbox. An implementer would also have to add 0 cross-domain interactions, including marshalling the URL 16 64 256 1024 2048 string and unmarshalling the returned struct. File Size (KB) We simulate performance and compare it with actual com- Figure 3: Overhead of compartmentalization vs. file size. partmentalized performance in Section 4.1.3. We tested our compartmentalization by using the ktrace 4.1.2 Networking tool to check for benign attempts at violating the sandbox We also explored the threat model of a malicious server ex- policy. To our surprise, we saw violations that were not ploiting HTTP header parsing or OpenSSL to gain elevated detected by an early version of SOAAP: privileges. This can be mitigated by executing network code CALL open(0x801c29100,0,...) in a persistent sandbox. Again, we wish to ensure that sen- CAP restricted VFS lookup sitive data cannot leak out of the sandbox. RET open -1 errno 94 Not permitted in In addition to data dependencies, SOAAP warns us about capability mode system calls that are performed within the sandbox but These violations result from calls to getservbyname(), a func- which would not be allowed under Capsicum by default: tion that returns a service entry for a given name and pro- * Sandbox "net" performs system call tocol, and timegm(), a function that converts a time value to * "connect" but it is not allowed to based UTC. The implementation of these functions on FreeBSD * on current sandboxing restrictions read the network services file and UTC time file re- spectively on first call. This is a subtle failure, as any call Capsicum does not allow a sandbox to call , nor connect() before sandbox creation to functions that rely on network can it be delegated as a capability right. The programmer services or the time zone will cause libc to cache copies of must proxy such calls to the privileged parent or else recon- them, making subsequent calls safe even after sandbox entry. sider sandbox boundaries. If we rerun SOAAP specifying Other implementations of libc make timegm() safe to call chroot as the sandboxing technique, this warning is not pro- at any time. For example, Solaris libc implements locale duced. This reflects a tension between security and code support via shared libraries, with the default C locale and complexity: a less invasive change also gives less security. UTC time zone information compiled into libc by default. SOAAP also warns of potential private data leaks through To address this issue, we extended the platform description functions. The first of these leaks is unintentional and extern with information about sandbox-safe functions. the second is intentional: In Figure 3, compartmentalized versions have the prefix * Sandboxed method "fetchParseURL" c- and SOAAP simulations are prefixed with s-. The graph * executing in sandboxes: [net] may leak shows that SOAAP’s simulations are 0.4–0.6 ms less than * private data through the extern function the actual performance. This could be due to not simulating * " fprintf " the compartmentalized code in a separate process and thus incurring less context-switching overhead. One surprising * Sandboxed method "fetch_writev" result is that the c-net compartmentalization is faster than * executing in sandboxes: [net] may leak c-parse when downloading files of size 2048 KB, despite per- * private data through the extern function * "SSL_write" forming significantly more IPC. Using manual source code instrumentation as well as FreeBSD’s dtrace, we have been The first is an illustration of a common but infrequently- able to determine that this performance anomaly is disk- considered source of leaks [28]. The second warning can be IO–related and not associated with either the sandboxing silenced by annotating the intentional flow of data with a mechanism or the decomposition strategies implemented. declassify-data annotation (__soaap_declassify). SOAAP’s simulation, executed on the same system, repli- cated this anomaly. This unexpected outcome shows that 4.1.3 Evaluating performance simulation performance emulation, rather than static model-based pre- We evaluate SOAAP’s performance simulation by com- diction, is able to capture non-deterministic performance ef- paring it with actual compartmentalized performance. Fig- fects caused by hardware or the OS. ure 3 shows a graph with this comparison. We manually compartmentalized fetch according to our 4.2 Okular: complex compartmentalization hypotheses, using Capsicum as the sandboxing platform. The fetch case study demonstrated the SOAAP tool in We fork a persistent sandbox at the start of main() and use a simple application. We now investigate using SOAAP to UNIX IPC to send data between the privileged parent and add compartmentalization to something much larger: Oku- the sandboxes. For the net sandbox, we proxy the privi- lar, the document viewer of the KDE desktop environment. leged calls identified by SOAAP: connect(), fopen(), stat(), Okular is around 80KLOC (plus 4MLOC from external li- utimes(), mkstemps(), rename(), symlink() and unlink(). braries that were also analyzed). within the sandbox. These issues demonstrate that lazy ini- tialization is a real anti-pattern when compartmentalizing applications as it must be ensured that all the initialization code has run before the sandbox is entered. By moving libpoppler into a sandbox we have not only removed code with a history of vulnerabilities from the TCB but also reduced the total amount of code that runs at full privileges by over 180,000 lines – which is more than the whole Okular source tree with 80,000 lines. We have now submitted our changes, created with the benefit of SOAAP, to the upstream Okular project for re- view. The changes amount to fewer than 2,500 lines. Of these 2,500 lines, 1,800 are adding new classes required for proxying the calls to Okular::Generator functions to the sandbox running in a separate process. Almost all other changes are related to moving classes from .cpp files to .h files so that the serialization code can access the required fields. The only real changes to the existing source code Figure 4: Okular compartmentalization: grey code executes were 30 lines to enable loading of sandboxed renderers and with ambient authority; green code is sandboxed. 100 lines to the PDFGenerator class. Figure 4 provides a visu- Okular has a modular structure with rendering plugins alization of the implemented compartmentalization. Green (“renderers”) for each supported document format. We de- indicates code executing within a sandboxed compartment cided to use this plugin interface to draw the compart- and orange indicates ambient code. mentalization boundary, which allows us to support both Compared to the ad-hoc nature of the OpenSSH privilege sandboxed and unsandboxed plugins. Okular currently has separation which introduced changes across many files, the 16 different renderers and we do not wish to have to add use of object oriented interfaces makes it possible to have sandboxing support to all of them simultaneously. This almost all code related to compartmentalization in one lo- highlights one of the key requirements for a tool such as cation (in this case the proxy class that implements the re- SOAAP: aiding incremental compartmentalization. For this quired interface). This makes it much easier to reason about case study we focused on the commonly-used PDF renderer. the correctness of the compartmentalization than in a large This renderer is implemented using the libpoppler library, C program without a modular design. which has had 38 known vulnerabilities [34] in the last 10 years. Of these, 19 are code execution vulnerabilities. 4.3 OpenSSH: long-term maintenance In the case of , we were able to annotate a single fetch OpenSSH [35] has had privilege separation since 2002, function as the sandbox entry point. This was not possi- with gradual refinements over time, making it an excellent ble here because Okular dynamically loads renderer plugins case study for long-term compartmentalization maintenance at run time – which equates to creating a single C++ ob- using SOAAP. Of particular concern is the risk of silent se- ject that implements the interface. Our Okular::Generator curity regression: previously mitigated vulnerabilities might proposed sandbox scope would be to include every member become unmitigated, confidentiality goals might no longer function of that class and the base classes. As this was not be met, or performance overhead might become intolerable. easily expressible with the existing SOAAP annotations, we OpenSSH uses a two-stage sandboxing strategy: a com- introduced a new annotation __soaap_sandboxed_class(name) pletely unprivileged process prior to authentication called to annotate the PDFGenerator class. preauth followed by a process running with the rights of the One interesting issue found by SOAAP was that the KDE authenticated user, called postauth [35]. Table 5a shows translation system may lazily load a shared library when several releases of OpenSSH, from the latest version (6.8) translating messages into certain languages. The dlopen() back to the first privilege-separated version (3.2.2). For each call will fail when in the sandbox, however as the library version, we annotated the sandboxing boundaries, past vul- is not required for most languages, this error is unlikely to nerabilities, confidentiality requirements, cross-domain com- be observed when using dynamic analysis or testing. This munication, assertions of functions that should only run problem of lazy initialization was also encountered when privileged and those that should only run sandboxed. compartmentalizing (see Section 4.1.3) for the calls fetch We observed that OpenSSH’s compartmentalization has to and . getservbyname() timegm() not changed significantly over time, supporting our supposi- These findings, as well as the broken support in rhosts tion that such maintenance is difficult in practice. We also OpenSSH (see Section 4.3), show that static analysis with discovered functionality that had silently regressed due to SOAAP can find compartmentalization errors that other- compartmentalization. For example, by applying SOAAP wise might go unnoticed for years. However, being able to to OpenSSH v3.2.2 we discovered that the preauth sand- find compartmentalization bugs caused by lazy initialization box was performing multiple stat() calls on rhosts files in- can come at the cost of an increase in false positives. When side auth_rhosts2_raw(). As this sandbox runs in a chroot analyzing Okular, SOAAP showed 9 false positives due to environment, these accesses would always fail, breaking lazy initialization that performs I/O but which had already RhostsAuthentication when compartmentalization was en- been executed before entering the sandbox. There was also abled. This was never fixed, but rhosts-based authentication one such finding that was a legitimate issue. The PDF ren- was already a vestigial feature by the time OpenSSH came derer would lazily attempt to load a configuration file from into widespread use and it was removed in v3.7. Unmitigated vulnerabilities Syscall warnings Ver. Year LOC Functions Annotations Sandboxed Func warnings Privileged Func warnings P/S/P&S CDC Assert Vuln. All 60 3.2.2 2002 43.6K 197/454/84 80 64 23 192 3.5 2002 45.4K 200/454/83 88 67 34 211 40 3.7 2003 48.7K 212/463/90 113 73 34 247 20 5.3 2009 63.8K 367/667/182 117 75 58 287 Warnings 6.0 2012 73.9K 433/691/196 117 76 65 298 0 6.5 2014 82.6K 578/764/251 117 76 68 308 3.2.2 3.5 3.7 5.3 6.0 6.5 6.8 6.8 2015 96.7K 617/880/276 117 74 65 300 OpenSSH Version

(a) (b) Figure 5: (a) Table showing OpenSSH code changes between versions. P: privileged; S: sandboxed; CDC: cross-domain communication. (b) Graph showing the number and types of SOAAP warnings across OpenSSH versions.

We were able to carry our the initial annotations forward was spun off from the KHTML framework [1], and through with only trivial merge conflicts. However, shown in Ta- a dedicated fuzzing effort, Google security developers found ble 5a, SOAAP reports that the ratio between total code over one thousand security vulnerabilities in the FFmpeg and code executing in sandboxes has decreased from 69% media libraries in the span of a year [16]. Code that has to 59% — the TCB has been getting larger. One major previously suffered from multiple vulnerabilities often deals change is the use of multiple sandboxing platforms such as with the interpretation of complex data and is therefore an seccomp-bpf (added in 6.0) and Capsicum (added in 6.5). excellent candidate to be compartmentalized and isolated We also examined the change in SOAAP’s warnings across from privilege and ambient authority (see Section 2.3). OpenSSH versions, shown in Figure 5b. We looked at un- SOAAP facilitates reasoning about the exposure of mitigated vulnerabilities, system call warnings and functions risky code by allowing developers to annotate previously- that execute outside their intended domains. System call vulnerable code. We identified risky code in Chromium by warnings tell us which system calls are not permitted by a searching Chromium’s historical bug database for security given sandboxing platform. SOAAP correctly warned about vulnerabilities in extant code. Due to constant code churn, stat() calls, and these warnings disappeared when rhosts many historic vulnerabilities applied to code that no longer support was removed in 3.7. We also see the warnings drop exists. However, we did find 21 historic Chromium vulnera- when Capsicum support was added in 6.5. Along with the bilities that have been patched and made public but applied rise in privileged code, SOAAP shows us that there is a cor- to extant code in the WebKit rendering engine, Skia graphics responding rise in the number of unmitigated vulnerabilities. library, FFmpeg media transcoder, v8 JavaScript engine and SOAAP also gave insights into how the execution of code internal HTTP or URL handling code. From these vulner- annotated as being privileged or sandbox-only has changed ability descriptions, we annotated ten previously-vulnerable over time. Sandbox-only code (likely to be riskier) executes functions (__soaap_vuln_fn) and 18 locations within other almost only in sandboxes whereas privileged code is increas- functions that were previously vulnerable (__soaap_vuln_pt). ingly being executed in sandboxes. If the security policy These annotations are a machine-readable formalization of for the sandbox is not correctly defined, the sandbox could a common practice in the Chromium code base: referencing perform operations it is not supposed to. Conversely, if the bug IDs from comments in source code. We found 1,803 in- policy is correct then privileged operations will fail. stances of such references within C++ comments, some of which we were able to formalize with SOAAP annotations: 4.4 Chromium: analysis scalability __soaap_vuln_pt("Cr issue #425035"); We tested SOAAP’s scalability by applying it to the CHECK(HasBeenSetUp());// crbug.com/425035 Chromium web browser [36], a large, complex, compartmen- Annotating the locations of previous vulnerabilities allows talized application with a history of security vulnerabilities SOAAP to statically enumerate the call graphs of risky code. and a variety of vulnerability mitigation techniques. We Chromium is designed to execute risky code inside compart- used SOAAP’s risk annotation and data-flow analysis ca- ments, using platform-specific compartmentalization tech- pabilities to investigate the separation of “risky” code and nologies. To analyze the effectiveness of Chromium’s sand- data from each other. We were able to observe at least one boxing, we needed to expose the details of the compart- instance in which risky code could be exposed to risky data, mentalization scheme to SOAAP. We re-implemented the potentially leading to critical security vulnerabilities as have sandboxing model using Capsicum [41] and found it to been previously reported in released versions of Chromium. be an excellent fit for the compartmentalization models of both SOAAP and Chromium: the Linux compartmental- 4.4.1 Risky code ization requires 13,821 lines of code and Windows requires The Chromium web browser, which is the open source 28,239, but the Capsicum model requires only 406 lines of variant of Google Chrome, has complex security require- source code and two sets of SOAAP annotations. The first ments and incorporates code from many sources. In addi- was a pair of annotations (__soaap_sandboxed_region_start tion to core browser code written by Google and community and __soaap_sandboxed_region_end) within RendererMain to developers, Chromium incorporates code from vendors and expose the extent of the sandbox. The second was open-source libraries with varying security track records. a __soaap_limit_fd_syscall annotation to describe how For instance, the WebKit rendering framework has suffered Chromium limits a sandbox’s authority on particular file over 200 publicly-reported security vulnerabilities since it descriptors according to the Capsicum model. renderer

blink::InlineFlowBox::addToLine( [...]) blink::FrameSelection::setSelection( [...]) blink::RangeBoundaryPoint::toPosition( [...]) blink::dispatchEditableContentChangedEvents( [...]) [[Cr issue #51602]] [[Cr issue #51602]] [[Cr issue #51602]] [[Cr issue #237429]] <> <> <> <>

RenderBlockLineLayout.cpp:234 (libwebcore_rendering.a.bc) FrameSelection.cpp:1907 (libwebcore_remaining.a.bc) Range.h:112 (libwebcore_dom.a.bc) Editor.cpp:664 (libwebcore_remaining.a.bc)

blink::RenderScrollbarPart::computeScrollbarWidth( [...]) blink::RenderScrollbarPart::computeScrollbarHeight( [...]) blink::RenderBlockFlow::markAllDescendantsWithFloatsForLayout( [...]) blink::RenderBlockFlow::constructLine( [...]) blink::FrameSelection::selectWordAroundPosition( [...]) blink::Range::startPosition() [...]) blink::Editor::appliedEditing( [...]) [[Cr issue #49729]] [[Cr issue #49729]] [[Cr issue #244036]] <> <> <> <> <> <> <>

RenderScrollbarPart.cpp:104 (libwebcore_rendering.a.bc) RenderScrollbarPart.cpp:102 (libwebcore_rendering.a.bc) RenderBlockFlow.cpp:908 (libwebcore_rendering.a.bc) WebLocalFrameImpl.cpp:1178 (libblink_web.a.bc)

blink::FrameSelection::setSelection( [...]) blink::RenderScrollbarPart::layoutHorizontalPart( [...]) blink::RenderBlockFlow::rebuildFloatsFromIntruding( [...]) blink::RenderBlockFlow::layoutInlineChildren( [...]) blink::WebLocalFrameImpl::selectWordAroundPosition( [...]) blink::Editor::replaceSelectionWithText( [...]) blink::Editor::replaceSelectionWithFragment( [...]) [[Cr issue #51602]] <> <> <> <> <> <> <>

RenderScrollbarPart.cpp:91 (libwebcore_rendering.a.bc) LayoutSVGText.cpp:381 (libwebcore_svg.a.bc) LayoutSVGText.cpp:389 (libwebcore_svg.a.bc) ContextMenuClientImpl.cpp:146 (libblink_web.a.bc) ContextMenuClientImpl.cpp:136 (libblink_web.a.bc) Editor.cpp:168 (libwebcore_remaining.a.bc) Editor.cpp:166 (libwebcore_remaining.a.bc)

blink::FrameView::performPostLayoutTasks( [...]) blink::RenderScrollbarPart::layout( [...]) blink::LayoutSVGText::layout() blink::selectMisspelledWord(b [...]) blink::Editor::handleTextEvent( [...]) [[Cr issue #236245]] blink::InlineFlowBox::addToLine( [...]) blink::FrameSelection::setSelection( [...]) blink::RangeBoundaryPoint::toPosition( [...]) blink::dispatchEditableContentChangedEvents( [...]) <> <> <> <> [[Cr issue #51602]] [[Cr issue #51602]] [[Cr issue #51602]] [[Cr issue #237429]] <>

RenderBlockLineLayout.cpp:234 (libwebcore_rendering.a.bc) FrameSelection.cpp:1907 (libwebcore_remaining.a.bc) Range.h:112 (libwebcore_dom.a.bc) Editor.cpp:664 (libwebcore_remaining.a.bc) FrameView.cpp:857 (libwebcore_remaining.a.bc) FrameView.cpp:857 (libwebcore_remaining.a.bc) FrameView.cpp:812 (libwebcore_remaining.a.bc) EventHandler.cpp:3384 (libwebcore_remaining.a.bc)

blink::RenderText::deleteTextBoxes( [...]) blink::RenderBlockFlow::removeFloatingObjects( [...]) blink::InputType::stepUpFromRenderer( [...]) blink::FrameView::performLayout( [...]) blink::FrameView::performPreLayoutTasks( [...]) blink::ContextMenuController::handleContextMenuEvent( [...]) blink::EventHandler::defaultTextInputEventHandler( [...]) [[Cr issue #51602]] [[Cr issue #245727]] [[Cr issue #243991]] <> <> <> <> blink::RenderBlockFlow::markAllDescendantsWithFloatsForLayout( [...]) blink::RenderScrollbarPart::computeScrollbarHeight( [...]) blink::RenderScrollbarPart::computeScrollbarWidth( [...]) <> <> <> blink::RenderBlockFlow::constructLine( [...]) blink::FrameSelection::selectWordAroundPosition( [...]) blink::Range::startPosition() [...]) blink::Editor::appliedEditing( [...]) [[Cr issue #244036]] [[Cr issue #49729]] [[Cr issue #49729]]

RenderText.cpp:230 (libwebcore_rendering.a.bc) RenderInline.cpp:474 (libwebcore_rendering.a.bc) FrameView.cpp:1015 (libwebcore_remaining.a.bc) FrameView.cpp:923 (libwebcore_remaining.a.bc) TextFieldInputType.cpp:519 (libwebcore_html.a.bc) Node.cpp:2135 (libwebcore_dom.a.bc) Node.cpp:2139 (libwebcore_dom.a.bc) RenderBlockFlow.cpp:908 (libwebcore_rendering.a.bc) RenderScrollbarPart.cpp:102 (libwebcore_rendering.a.bc) RenderScrollbarPart.cpp:104 (libwebcore_rendering.a.bc) WebLocalFrameImpl.cpp:1178 (libblink_web.a.bc) blink::ResourceLoader::cancel( [...]) blink::Node::defaultEventHandler( [...]) blink::canHaveChildrenForEditing( [...]) blink::Resource::load(blink:: [...]) app_modal::AppModalDialog::CompleteDialog( [...]) SkMask::computeImageSize() co [...]) blink::RenderText::removeAndDestroyTextBoxes( [...]) blink::RenderInline::splitFlow( [...]) blink::FrameView::layout() blink::TextFieldInputType::spinButtonStepUp( [...]) [[Cr issue #244021]] [[Cr bug #60327]] [[Cr issue #51602]] [[Cr issue #244021]] [[Cr issue #137707]] [[Cr issue #10736]] <> <> <> <> blink::FrameSelection::setSelection( [...]) <> <> <> <> <> <> blink::RenderBlockFlow::rebuildFloatsFromIntruding( [...]) blink::RenderBlockFlow::layoutInlineChildren( [...]) blink::RenderScrollbarPart::layoutHorizontalPart( [...]) blink::WebLocalFrameImpl::selectWordAroundPosition( [...]) blink::Editor::replaceSelectionWithText( [...]) blink::Editor::replaceSelectionWithFragment( [...]) [[Cr issue #51602]]

DocumentLoader.cpp:723 (libwebcore_remaining.a.bc) Document.cpp:2537 (libwebcore_dom.a.bc) Document.cpp:2573 (libwebcore_dom.a.bc) markup.cpp:381 (libwebcore_remaining.a.bc) ResourceFetcher.cpp:804 (libwebcore_remaining.a.bc) javascript_app_modal_dialog.cc:111 (libapp_modal.a.bc) SkEmbossMaskFilter.cpp:98 (libskia_library.a.bc) LayoutSVGText.cpp:381 (libwebcore_svg.a.bc) LayoutSVGText.cpp:389 (libwebcore_svg.a.bc) RenderScrollbarPart.cpp:91 (libwebcore_rendering.a.bc) ContextMenuClientImpl.cpp:136 (libblink_web.a.bc) ContextMenuClientImpl.cpp:146 (libblink_web.a.bc) Editor.cpp:168 (libwebcore_remaining.a.bc) Editor.cpp:166 (libwebcore_remaining.a.bc) net::SniffForOfficeDocs(char [...]) blink::LayoutObject::destroy() blink::LayoutObject::setStyle( [...]) blink::DocumentLoader::cancelMainResourceLoad( [...]) blink::Document::implicitClose( [...]) blink::Document::setReadyState( [...]) blink::Document::dispatchBeforeUnloadEvent( [...]) blink::StyledMarkupAccumulator::traverseNodesForSerialization( [...]) blink::ResourceFetcher::requestResource( [...]) app_modal::JavaScriptAppModalDialog::OnCancel( [...]) SkEmbossMaskFilter::filterMask( [...]) [[Cr issue #239580]] <> <> <> <> <> <> <> <> <> <> blink::FrameView::performPostLayoutTasks( [...]) <> blink::LayoutSVGText::layout() blink::RenderScrollbarPart::layout( [...]) blink::selectMisspelledWord(b [...]) blink::Editor::handleTextEvent( [...]) [[Cr issue #236245]]

FrameView.cpp:2485 (libwebcore_remaining.a.bc) FrameView.cpp:2482 (libwebcore_remaining.a.bc) DocumentLoader.cpp:185 (libwebcore_remaining.a.bc) FrameLoader.cpp:494 (libwebcore_remaining.a.bc) FrameLoader.cpp:492 (libwebcore_remaining.a.bc) FrameLoader.cpp:1176 (libwebcore_remaining.a.bc) mime_sniffer.cc:945 (libnet.a.bc) FrameView.cpp:857 (libwebcore_remaining.a.bc) FrameView.cpp:857 (libwebcore_remaining.a.bc) FrameView.cpp:812 (libwebcore_remaining.a.bc) EventHandler.cpp:3384 (libwebcore_remaining.a.bc) blink::FrameView::updateScrollCorner( [...]) blink::DocumentLoader::stopLoading( [...]) blink::FrameLoader::checkCompleted( [...]) blink::FrameLoader::shouldClose( [...]) blink::FrameLoader::dispatchNavigationTransitionData( [...]) blink::DocumentLoader::startLoadingMainResource( [...]) CollectedCookiesViews::Observe( [...]) NTPLoginHandler::Observe(int, [...]) net::SniffMimeType(char const [...]) <> <> <> <> <> <> <> <> <> blink::RenderBlockFlow::removeFloatingObjects( [...]) blink::RenderText::deleteTextBoxes( [...]) blink::InputType::stepUpFromRenderer( [...]) blink::FrameView::performLayout( [...]) blink::FrameView::performPreLayoutTasks( [...]) blink::ContextMenuController::handleContextMenuEvent( [...]) blink::EventHandler::defaultTextInputEventHandler( [...]) [[Cr issue #245727]] [[Cr issue #51602]] [[Cr issue #243991]] FrameLoader.cpp:592 (libwebcore_remaining.a.bc) FrameLoader.cpp:617 (libwebcore_remaining.a.bc) FrameLoader.cpp:1240 (libwebcore_remaining.a.bc) FrameLoader.cpp:1236 (libwebcore_remaining.a.bc) FrameLoader.cpp:1276 (libwebcore_remaining.a.bc) notification_service_impl.cc:108 (libcontent_browser.a.bc) notification_service_impl.cc:108 (libcontent_browser.a.bc)

blink::FrameLoader::restoreScrollPositionAndViewState( [...]) blink::FrameLoader::loadInSameDocument( [...]) blink::FrameLoader::startLoad( [...]) content::NotificationServiceImpl::Notify( [...]) content::ChildProcessHostImpl::OnMessageReceived( [...]) RenderInline.cpp:474 (libwebcore_rendering.a.bc) RenderText.cpp:230 (libwebcore_rendering.a.bc) FrameView.cpp:1015 (libwebcore_remaining.a.bc) FrameView.cpp:923 (libwebcore_remaining.a.bc) TextFieldInputType.cpp:519 (libwebcore_html.a.bc) Node.cpp:2135 (libwebcore_dom.a.bc) Node.cpp:2139 (libwebcore_dom.a.bc) <> <> <> <> <>

blink::ResourceLoader::cancel( [...]) blink::Node::defaultEventHandler( [...]) blink::canHaveChildrenForEditing( [...]) blink::Resource::load(blink:: [...]) FrameLoader.cpp:1359 (libwebcore_remaining.a.bc) FrameLoader.cpp:1358 (libwebcore_remaining.a.bc) FrameLoader.cpp:1363 (libwebcore_remaining.a.bc) render_process_host_impl.cc:2067 (libcontent_browser.a.bc) render_process_host_impl.cc:2085 (libcontent_browser.a.bc) blink::RenderInline::splitFlow( [...]) blink::RenderText::removeAndDestroyTextBoxes( [...]) blink::FrameView::layout() blink::TextFieldInputType::spinButtonStepUp( [...]) [[Cr issue #244021]] [[Cr bug #60327]] [[Cr issue #51602]] [[Cr issue #244021]] blink::FrameLoader::loadHistoryItem( [...]) content::RenderProcessHostImpl::ProcessDied( [...]) <> <> DocumentLoader.cpp:723 (libwebcore_remaining.a.bc) Document.cpp:2537 (libwebcore_dom.a.bc) Document.cpp:2573 (libwebcore_dom.a.bc) markup.cpp:381 (libwebcore_remaining.a.bc) ResourceFetcher.cpp:804 (libwebcore_remaining.a.bc)

net::SniffForOfficeDocs(char [...]) v8::internal::HOptimizedGraphBuilder::BuildEmitInObjectProperties( [...]) app_modal::AppModalDialog::CompleteDialog( [...]) blink::LayoutObject::setStyle( [...]) blink::LayoutObject::destroy() blink::DocumentLoader::cancelMainResourceLoad( [...]) blink::Document::implicitClose( [...]) blink::Document::setReadyState( [...]) blink::Document::dispatchBeforeUnloadEvent( [...]) blink::StyledMarkupAccumulator::traverseNodesForSerialization( [...]) blink::ResourceFetcher::requestResource( [...]) [[Cr issue #239580]] [[Cr issue #240056]] [[Cr issue #137707]] v8::internal::HOptimizedGraphBuilder::BuildEmitInObjectProperties( [...]) content::RenderThreadImpl::Shutdown( [...]) content::PluginThread::Shutdown( [...]) [[Cr issue #240056]] <> <> <> FrameView.cpp:2482 (libwebcore_remaining.a.bc) FrameView.cpp:2485 (libwebcore_remaining.a.bc) DocumentLoader.cpp:185 (libwebcore_remaining.a.bc) FrameLoader.cpp:494 (libwebcore_remaining.a.bc) FrameLoader.cpp:492 (libwebcore_remaining.a.bc) FrameLoader.cpp:1176 (libwebcore_remaining.a.bc) mime_sniffer.cc:945 (libnet.a.bc) hydrogen.cc:11145 (libv8_base.a.bc) javascript_app_modal_dialog.cc:111 (libapp_modal.a.bc)

child_process.cc:67 (libcontent_child.a.bc) child_process.cc:67 (libcontent_child.a.bc) hydrogen.cc:11145 (libv8_base.a.bc)

blink::FrameView::updateScrollCorner( [...]) blink::DocumentLoader::stopLoading( [...]) blink::FrameLoader::checkCompleted( [...]) blink::FrameLoader::shouldClose( [...]) blink::FrameLoader::dispatchNavigationTransitionData( [...]) blink::DocumentLoader::startLoadingMainResource( [...]) net::SniffMimeType(char const [...]) v8::internal::HOptimizedGraphBuilder::BuildFastLiteral( [...]) app_modal::JavaScriptAppModalDialog::OnCancel( [...]) content::ChildProcess::~ChildProcess( [...]) v8::internal::HOptimizedGraphBuilder::BuildFastLiteral( [...]) <> <>

FrameLoader.cpp:592 (libwebcore_remaining.a.bc) FrameLoader.cpp:617 (libwebcore_remaining.a.bc) FrameLoader.cpp:1240 (libwebcore_remaining.a.bc) FrameLoader.cpp:1236 (libwebcore_remaining.a.bc) FrameLoader.cpp:1276 (libwebcore_remaining.a.bc)

blink::FrameLoader::restoreScrollPositionAndViewState( [...]) blink::FrameLoader::loadInSameDocument( [...]) blink::FrameLoader::startLoad( [...]) content::ChildProcessHostImpl::OnMessageReceived( [...]) IPC::ChannelProxy::Context::OnDispatchConnected( [...]) content::RenderFrameHostImpl::OnMessageReceived( [...]) content::RenderProcessImpl::~RenderProcessImpl( [...]) base::MessageLoop::Run() <> <>

FrameLoader.cpp:1359 (libwebcore_remaining.a.bc) FrameLoader.cpp:1358 (libwebcore_remaining.a.bc) FrameLoader.cpp:1363 (libwebcore_remaining.a.bc) ipc_channel_proxy.cc:282 (libipc.a.bc) ipc_channel_proxy.cc:270 (libipc.a.bc) ipc_channel_proxy.cc:282 (libipc.a.bc) renderer_main.cc:231 (libcontent_renderer.a.bc) renderer_main.cc:223 (libcontent_renderer.a.bc) blink::FrameLoader::loadHistoryItem( [...]) IPC::ChannelProxy::Context::OnDispatchMessage( [...])

SkMask::computeImageSize() co [...]) content::RendererMain(content [...]) content::RenderThreadImpl::Send( [...]) content::ChildThreadImpl::Send( [...]) [[Cr issue #10736]] <>

thread_safe_sender.cc:24 (libcontent_child.a.bc) thread_safe_sender.cc:24 (libcontent_child.a.bc) SkDraw.cpp:2260 (libskia_library.a.bc)

content::ThreadSafeSender::Send( [...]) SkDraw::DrawToMask(SkPath con [...])

content::DevToolsFrameTraceRecorderData::AppendAsTraceFormat( [...]) cc::TracedPicture::AppendAsTraceFormat( [...])

trace_event_impl.cc:785 (libbase.a.bc) trace_event_impl.cc:785 (libbase.a.bc)

base::trace_event::TraceEvent::AppendPrettyPrinted( [...])

main

Figure 6: Simplified SOAAP-generated call graphs of unmitigated (red) and mitigated (yellow) vulnerabilities in Chromium.

SkMask::computeImageSize() co [...]) 1.88 M such accesses, a number too large to manually sift for [[Cr issue #10736]] false positives. We are able to cope with this scale of problem SkDraw.cpp:2260 (libskia_library.a.bc) in two ways. First, our SOAAP graph manipulation tools SkDraw::DrawToMask(SkPath con [...]) are able to compute useful operations on combined call/data

cc::TracedPicture::AppendAsTraceFormat( [...]) flow graphs, such as intersections to a certain depth and leaf node filtering. For example, we can trace back a fixed trace_event_impl.cc:785 (libbase.a.bc) base::trace_event::TraceEvent::AppendPrettyPrinted( [...]) number of calls or data flows from a vulnerability or private data access to compute a set of ancestor nodes, then only include that node in the new intersection graph if it shares ChromeMain at least one ancestor with the ancestors of another graph. chrome_exe_main_aura.cc:17 (chrome.bc) main This allows us to reduce the graph of all private accesses to the graph of private accesses (risky data) that occur in some Figure 7: A simplified call graph produced by SOAAP that proximity to a previously-vulnerable function (risky code). demonstrates how a previously-vulnerable function can be The result of intersecting the vulnerability and private- called from main in an unsandboxed (i.e., privileged) context. access graphs is still too large for manual exploration. Such exploration was important when iteratively investigating lo- After annotating Chromium to describe both its risky cations for network data annotation (net::HttpStreamParser, code and its compartmentalization strategy, SOAAP was net::HttpNetworkTransaction, net::URLRequest, etc.). There- able to statically check which risky functions could be exe- fore, for initial data exploration, SOAAP is able to treat cuted outside of a sandbox. The results, shown in Figure 6, private accesses probabilistically. We found that randomly are surprising at first glance: almost all of the risky functions selecting 0.01% of private access allowed us to perform ex- are executed in both the privileged browser process and the ploratory data analysis and rapidly identify suspicious data least-privileged renderer process. For example, debug trac- flows. We then filtered large graphs by leaf nodes (vulner- ing in the privileged browser process can call a previously- abilities or private accesses) to produce the simple call and vulnerable image parsing function within Skia, as shown in data-flow graphs shown in Figures 8 and 10 (see Section A). Figure 7. However, this static call graph does not tell the Using SOAAP’s static call graphs of previously-vulnerable whole story of code and data risk. code, information flow propagation analysis, sandbox an- A reliance on static call graphs can lead to large num- notations, graph intersection and filtering, we were able bers of false-positive results. Figure 7 does show that the to identify network-tainted data (risky data) flowing to previously-vulnerable function SkMask::computeImageSize() previously-vulnerable functions (risky code). For example, might execute outside of the sandboxed renderer process, Figure 8 depicts a highly elided call and data flow graph that but if it only computes the sizes of browser chrome images shows resources loaded by URL and presented to MIME type distributed by Google, there is a much lower risk than if it detection code that has suffered security vulnerabilities in is exposed to content from arbitrary web pages. In order the past. This is precisely the type of interaction that appli- to better understand the real risk of running risky code, we cation authors might prefer to occur within a least-privileged added risky data annotations and combined the above static compartment; SOAAP makes it visible to the authors so call graphs with SOAAP’s information flow analysis. they can take appropriate mitigation steps. 4.4.2 Risky data After intersection and filtering SOAAP graphs, we still en- countered many false positives caused by Chromium’s var- In addition to annotating risky (previously-vulnerable) ied network use. For instance, Chromium’s HTTP and URL code, we also annotated risky data: data that is obtained handling code is used both to retrieve data from the network from the network and which may therefore be dictated by an and to manage transport between its privileged and unpriv- attacker. We annotated Chromium’s net::URLRequest::Read ileged components. We saw many data flows from, e.g., method, telling SOAAP to treat the read buffer as private to code in the to the renderer sandbox: net::HttpStreamParser remoting::protocol namespace, and then on to previously-vulnerable WebKit bool Read (__soaap_private("renderer") code. We view this as a false-positive result: it is part of a IOBuffer* buf, carefully-managed interaction between browser components int max_bytes, int* bytes_read); for the purpose of enabling compartmentalization. We then enabled SOAAP’s information flow tracking to Such false positives could be managed by introducing determine all of the locations where this network-originated more selective annotations, e.g., on content::ResourceLoader data was accessed outside of a sandbox. SOAAP detected net::SniffForOfficeDocs(char [...]) [[Cr issue #239580]]

mime_sniffer.cc:945 (libnet.a.bc)

net::SniffMimeType(char const [...]) ChromePluginServiceFilter::IsPluginAvailable( [...])

buffered_resource_handler.cc:289 (libcontent_browser.a.bc) plugin_service_impl.cc:536 (libcontent_browser.a.bc) plugin_service_impl.cc:536 (libcontent_browser.a.bc)

content::BufferedResourceHandler::DetermineMimeType( [...]) content::PluginServiceImpl::GetPluginInfo( [...])

buffered_resource_handler.cc:180 (libcontent_browser.a.bc) buffered_resource_handler.cc:484 (libcontent_browser.a.bc) buffered_resource_handler.cc:484 (libcontent_browser.a.bc)

content::BufferedResourceHandler::OnReadCompleted( [...]) content::BufferedResourceHandler::HasSupportingPlugin( [...]) resource_loader.cc:770 (libcontent_browser.a.bc)

buffered_resource_handler.cc:435 (libcontent_browser.a.bc) buffered_resource_handler.cc:349 (libcontent_browser.a.bc) buffered_resource_handler.cc:349 (libcontent_browser.a.bc) content::ResourceLoader::CompleteRead( [...])

content::BufferedResourceHandler::ReplayReadCompleted( [...]) content::BufferedResourceHandler::SelectNextHandler( [...]) resource_loader.cc:457 (libcontent_browser.a.bc) buffered_resource_handler.cc:252 (libcontent_browser.a.bc) buffered_resource_handler.cc:235 (libcontent_browser.a.bc) buffered_resource_handler.cc:235 (libcontent_browser.a.bc) content::ResourceLoader::OnReadCompleted( [...]) buffered_resource_handler.cc:184 (libcontent_browser.a.bc) content::BufferedResourceHandler::ProcessResponse( [...]) url_request.cc:1137 (libnet.a.bc) buffered_resource_handler.cc:145 (libcontent_browser.a.bc) net::URLRequest::NotifyReadCompleted( [...]) content::BufferedResourceHandler::OnResponseStarted( [...]) url_request_job.cc:561 (libnet.a.bc) throttling_resource_handler.cc:128 (libcontent_browser.a.bc) net::URLRequestJob::NotifyReadComplete( [...]) content::ThrottlingResourceHandler::OnResponseStarted( [...])

blob_url_request_job.cc:425 (libstorage.a.bc) throttling_resource_handler.cc:223 (libcontent_browser.a.bc)

storage::BlobURLRequestJob::DidReadFile( [...]) content::ThrottlingResourceHandler::ResumeResponse( [...])

blob_url_request_job.cc:401 (libstorage.a.bc) throttling_resource_handler.cc:167 (libcontent_browser.a.bc)

storage::BlobURLRequestJob::ReadFileItem( [...]) content::ThrottlingResourceHandler::Resume( [...])

blob_url_request_job.cc:345 (libstorage.a.bc) resource_scheduler.cc:202 (libcontent_browser.a.bc)

storage::BlobURLRequestJob::ReadItem( [...]) content::ResourceScheduler::ScheduledResourceRequest::Start( [...])

blob_url_request_job.cc:467 (libstorage.a.bc) resource_scheduler.cc:646 (libcontent_browser.a.bc)

storage::BlobURLRequestJob::ReadLoop( [...]) content::ResourceScheduler::Client::StartRequest( [...])

blob_url_request_job.cc:122 (libstorage.a.bc) resource_scheduler.cc:783 (libcontent_browser.a.bc)

storage::BlobURLRequestJob::ReadRawData( [...]) content::ResourceScheduler::Client::LoadAnyStartablePendingRequests( [...])

url_request_job.cc:854 (libnet.a.bc) resource_scheduler.cc:459 (libcontent_browser.a.bc)

net::URLRequestJob::ReadRawDataHelper( [...]) content::ResourceScheduler::Client::OnWillInsertBody( [...])

url_request_job.cc:112 (libnet.a.bc) resource_scheduler.cc:987 (libcontent_browser.a.bc)

net::URLRequestJob::Read(net: [...]) content::ResourceScheduler::OnWillInsertBody( [...])

resource_scheduler_filter.cc:62 (libcontent_browser.a.bc)

content::ResourceSchedulerFilter::OnMessageReceived( [...])

browser_message_filter.cc:89 (libcontent_browser.a.bc)

content::BrowserMessageFilter::Internal::DispatchMessage( [...])

browser_message_filter.cc:64 (libcontent_browser.a.bc) browser_message_filter.cc:64 (libcontent_browser.a.bc)

content::BrowserMessageFilter::Internal::OnMessageReceived( [...])

child_process_host_impl.cc:244 (libcontent_common.a.bc) child_process_host_impl.cc:244 (libcontent_common.a.bc)

content::ChildProcessHostImpl::OnMessageReceived( [...])

ipc_channel_proxy.cc:282 (libipc.a.bc) ipc_channel_proxy.cc:282 (libipc.a.bc)

IPC::ChannelProxy::Context::OnDispatchMessage( [...])

ipc_sync_channel.cc:126 (libipc.a.bc) ipc_sync_channel.cc:126 (libipc.a.bc)

IPC::SyncChannel::ReceivedSyncMsgQueue::DispatchMessages( [...])

ipc_sync_channel.cc:298 (libipc.a.bc) ipc_sync_channel.cc:298 (libipc.a.bc)

IPC::SyncChannel::SyncContext::DispatchMessages( [...])

ipc_sync_channel.cc:500 (libipc.a.bc) ipc_sync_channel.cc:500 (libipc.a.bc)

IPC::SyncChannel::WaitForReply( [...])

ipc_sync_channel.cc:493 (libipc.a.bc) ipc_sync_channel.cc:493 (libipc.a.bc)

IPC::SyncChannel::Send(IPC::M [...])

child_thread_impl.cc:452 (libcontent_child.a.bc)

content::ChildThreadImpl::Send( [...])

thread_safe_sender.cc:24 (libcontent_child.a.bc)

content::ThreadSafeSender::Send( [...])

child_discardable_shared_memory_manager.cc:187 (libcontent_child.a.bc)

content::ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory( [...])

child_discardable_shared_memory_manager.cc:97 (libcontent_child.a.bc)

content::ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory( [...])

discardable_memory_shmem.cc:34 (libbase.a.bc) discardable_memory_shmem.cc:34 (libbase.a.bc)

base::internal::DiscardableMemoryShmem::Lock( [...])

url_request.cc:735 (libnet.a.bc) SkDiscardableMemory_chrome.cc:10 (libskia_chrome.a.bc) SkDiscardableMemory_chrome.cc:10 (libskia_chrome.a.bc)

SkDiscardableMemoryChrome::lock( [...])

SkDiscardablePixelRef.cpp:41 (libskia_library.a.bc) SkDiscardablePixelRef.cpp:41 (libskia_library.a.bc)

SkDiscardablePixelRef::onNewLockPixels( [...])

SkPixelRef.cpp:157 (libskia_library.a.bc) SkPixelRef.cpp:157 (libskia_library.a.bc)

SkPixelRef::lockPixels(SkPixe [...])

SkPixelRef.cpp:170 (libskia_library.a.bc) SkPixelRef.cpp:170 (libskia_library.a.bc)

SkPixelRef::lockPixels()

SkBitmap.cpp:225 (libskia_library.a.bc) SkBitmap.cpp:225 (libskia_library.a.bc)

SkBitmap::lockPixels() const

SkBitmap.h:772 (libbrowser.a.bc) SkBitmap.h:772 (libbrowser.a.bc)

SkAutoLockPixels::SkAutoLockPixels( [...])

devtools_frame_trace_recorder.cc:81 (libcontent_browser.a.bc) devtools_frame_trace_recorder.cc:81 (libcontent_browser.a.bc)

content::DevToolsFrameTraceRecorderData::AppendAsTraceFormat( [...])

trace_event_impl.cc:785 (libbase.a.bc) trace_event_impl.cc:785 (libbase.a.bc)

net::SniffForOfficeDocs(charbase::trace_event::TraceEvent::AppendPrettyPrinted( [...]) [...]) [[Cr issue #239580]] previously_vulnerable [[CVE-1900-XXXXX]] trace_event_impl.cc:2084 (libbase.a.bc) trace_event_impl.cc:2084 (libbase.a.bc) mime_sniffer.cc:945 (libnet.a.bc) base::trace_event::TraceLog::EventToConsoleMessage( [...]) vulnerability_mitigated [[CVE-1900-XXXXX]] net::SniffMimeType(char const [...]) ChromePluginServiceFilter::IsPluginAvailable( [...]) <> trace_event_impl.cc:2147 (libbase.a.bc) buffered_resource_handler.cc:289 (libcontent_browser.a.bc) plugin_service_impl.cc:536 (libcontent_browser.a.bc) plugin_service_impl.cc:536 (libcontent_browser.a.bc) sandboxed base::trace_event::TraceLog::UpdateTraceEventDuration( [...]) <> content::BufferedResourceHandler::DetermineMimeType( [...]) content::PluginServiceImpl::GetPluginInfo( [...])

private_access trace_event.h:1492 (libbrowser.a.bc) buffered_resource_handler.cc:180 (libcontent_browser.a.bc) buffered_resource_handler.cc:484 (libcontent_browser.a.bc) buffered_resource_handler.cc:484 (libcontent_browser.a.bc) trace_event_internal::ScopedTracer::~ScopedTracer( [...]) ordinary_function content::BufferedResourceHandler::OnReadCompleted( [...]) content::BufferedResourceHandler::HasSupportingPlugin( [...]) Legend resource_loader.cc:770 (libcontent_browser.a.bc) content_main_runner.cc:752 (libcontent_app_both.a.bc) buffered_resource_handler.cc:435 (libcontent_browser.a.bc) buffered_resource_handler.cc:349 (libcontent_browser.a.bc) buffered_resource_handler.cc:349 (libcontent_browser.a.bc) content::ResourceLoader::CompleteRead( [...]) content::ContentMainRunnerImpl::Initialize( [...]) content::BufferedResourceHandler::ReplayReadCompleted( [...]) content::BufferedResourceHandler::SelectNextHandler( [...]) resource_loader.cc:457 (libcontent_browser.a.bc) content_main.cc:15 (libcontent_app_both.a.bc) buffered_resource_handler.cc:252 (libcontent_browser.a.bc) buffered_resource_handler.cc:235 (libcontent_browser.a.bc) buffered_resource_handler.cc:235 (libcontent_browser.a.bc) content::ResourceLoader::OnReadCompleted( [...]) buffered_resource_handler.cc:184 (libcontent_browser.a.bc) content::ContentMain(content: [...]) content::BufferedResourceHandler::ProcessResponse( [...]) url_request.cc:1137 (libnet.a.bc) chrome_main.cc:66 (chrome.bc) buffered_resource_handler.cc:145 (libcontent_browser.a.bc) net::URLRequest::NotifyReadCompleted( [...]) [ ... detail elided ... ] ChromeMain content::BufferedResourceHandler::OnResponseStarted( [...]) url_request_job.cc:561 (libnet.a.bc) net::URLRequest::Read(net::IO [...]) chrome_exe_main_aura.cc:17 (chrome.bc) throttling_resource_handler.cc:128 (libcontent_browser.a.bc) net::URLRequestJob::NotifyReadComplete( [...]) main content::ThrottlingResourceHandler::OnResponseStarted( [...]) Figure 8: An example of data flowing from the network to code that has previously been vulnerable to exploitation. In this example, which has been croppedblob_url_request_job.cc:425 by 38 function (libstorage.a.bc) calls and nine relevant data flows, datathrottling_resource_handler.cc:223 flows from a URLRequest (libcontent_browser.a.bc)to a BlobURLRequestJob to a BufferedResourceHandler, where it is inspected to determine its MIME type. net::SniffForOfficeDocs storage::BlobURLRequestJob::DidReadFile( [...]) content::ThrottlingResourceHandler::ResumeResponse( [...]) was annotated with __soaap_vuln_pt due to a previous critical security vulnerability (see http://crbug.com/239580).

blob_url_request_job.cc:401 (libstorage.a.bc) throttling_resource_handler.cc:167 (libcontent_browser.a.bc) Link chrome storage::BlobURLRequestJob::ReadFileItem(User [...])System tire workingcontent::ThrottlingResourceHandler::Resume( set was able to fit into the ARC [...]) rather than be retrieved from disk on-demand. Our system has dual Xeon llvm-link chrome.bc blob_url_request_job.cc:345 (libstorage.a.bc) E5-2667v3 CPUs with 32 logicalresource_scheduler.cc:202 processors, (libcontent_browser.a.bc) but SOAAP does not currently exploit their parallelism. SOAAP: 28 accesses storage::BlobURLRequestJob::ReadItem( [...]) content::ResourceScheduler::ScheduledResourceRequest::Start( [...]) Figure 9 shows, as we would expect, that linking SOAAP: 1.8M acc. blob_url_request_job.cc:467 (libstorage.a.bc)Chromium as a 985 MiB LLVMresource_scheduler.cc:646 bitcode file (libcontent_browser.a.bc) is slower than 0 100 200 300 400 500 linking a 141 MiB ELF executable. LLVM IR is a higher- storage::BlobURLRequestJob::ReadLoop( [...]) content::ResourceScheduler::Client::StartRequest( [...]) Run time [s] level representation with explicit types and other informa- tion that is not included in machine code. SOAAP’s run- Figure 9: SOAAP’s run time is similarblob_url_request_job.cc:122 to that of linking (libstorage.a.bc) the resource_scheduler.cc:783 (libcontent_browser.a.bc) time cost is either just over or just under this LLVM linking Chromium bitcode usingstorage::BlobURLRequestJob::ReadRawData(llvm-link. With a restricted [...]) set of content::ResourceScheduler::Client::LoadAnyStartablePendingRequests( [...]) private-access annotations, leading to 28 detected private ac- time, depending on the complexity of the data flows that SOAAP must track. Loading this 985 MiB bitcode file into cesses, it is 0.68 that of llvm-link. With theurl_request_job.cc:854 annotation (libnet.a.bc) used resource_scheduler.cc:459 (libcontent_browser.a.bc) in Section 4.4.2, which causes 1.8 M private access warnings, memory required over 10 GiB of memory, approximately the net::URLRequestJob::ReadRawDataHelper( [...]) same amountcontent::ResourceScheduler::Client::OnWillInsertBody( of memory required by llvm-link [...]). Processing the run time is 1.48 times that of llvm-link. the class hierarchy, finding sandboxes and adding informa- url_request_job.cc:112 (libnet.a.bc) resource_scheduler.cc:987 (libcontent_browser.a.bc) rather than the general-purpose net::URLRequest, but our tion about previous vulnerabilities pushed memory usage goal in this work was to explore asnet::URLRequestJob::Read(net: many variations of [...]) data to just overcontent::ResourceScheduler::OnWillInsertBody( 12 GiB, and adding the details [...]) of 1.5 M pri- flowing to risky code as possible. That is, we had very little vate accesses increased memory usage to just over 14 GiB. resource_scheduler_filter.cc:62 (libcontent_browser.a.bc) tolerance for false negatives, so we erred on the side of false The difference in run time between the two SOAAP cases in positives and developed tools to cope with them. Figure 9content::ResourceSchedulerFilter::OnMessageReceived( is due to the private accesses that [...]) were detected, according to the _soaap_private annotations that were ap- 4.4.3 Performance plied. The outcome of SOAAP’sbrowser_message_filter.cc:89 analysis was (libcontent_browser.a.bc) a 978 MiB As a whole-program analysis, SOAAP’s run-time cost JSON filecontent::BrowserMessageFilter::Internal::DispatchMessage( that we initially explored with jq [11][...]) and finally when targeting Chromium is comparable to other whole- processed with our SOAAP graph manipulation tools. program LLVM-based tasks. Figure 9 compares the run Combining SOAAP’s sandbox,browser_message_filter.cc:64 vulnerability (libcontent_browser.a.bc) and data flow browser_message_filter.cc:64 (libcontent_browser.a.bc)

time of four whole-program compilation and analysis tasks: annotationscontent::BrowserMessageFilter::Internal::OnMessageReceived( allowed us to detect the interaction [...]) of risky code linking Chromium’s object files and static archives into an and risky data outside of least-privileged compartments, cre- executable ELF binary, linking its individual LLVM IR ob- ating risk for Chromium’s users.child_process_host_impl.cc:244 These complex (libcontent_common.a.bc) analyses child_process_host_impl.cc:244 (libcontent_common.a.bc)

ject files into a complete bitcode file with llvm-link, run- can be usedcontent::ChildProcessHostImpl::OnMessageReceived( to immediately inform application [...]) authors of ning SOAAP with some private data accesses and running potential risks and inform their decisions about where to in- SOAAP with the annotations described in Section 4.4.1. vest compartmentalization effort.ipc_channel_proxy.cc:282 Even on a(libipc.a.bc) large,ipc_channel_proxy.cc:282 complex (libipc.a.bc) The following measurements were performed on a sys- piece of softwareIPC::ChannelProxy::Context::OnDispatchMessage( such as Chromium, SOAAP [...]) was able to tem running FreeBSD 10.1-RELEASE-p16, with a ZFS ARC produce these data in eight minutes, or approximately the (adaptive replacement cache) of 20–60 GiB (out of a total of time required to link Chromiumipc_sync_channel.cc:126 as LLVM (libipc.a.bc) bitcode.ipc_sync_channel.cc:126 (libipc.a.bc) 128 GiB of system RAM) and no memory pressure: the en- IPC::SyncChannel::ReceivedSyncMsgQueue::DispatchMessages( [...])

ipc_sync_channel.cc:298 (libipc.a.bc) ipc_sync_channel.cc:298 (libipc.a.bc)

IPC::SyncChannel::SyncContext::DispatchMessages( [...])

ipc_sync_channel.cc:500 (libipc.a.bc) ipc_sync_channel.cc:500 (libipc.a.bc)

IPC::SyncChannel::WaitForReply( [...])

ipc_sync_channel.cc:493 (libipc.a.bc) ipc_sync_channel.cc:493 (libipc.a.bc)

IPC::SyncChannel::Send(IPC::M [...])

child_thread_impl.cc:452 (libcontent_child.a.bc)

content::ChildThreadImpl::Send( [...])

thread_safe_sender.cc:24 (libcontent_child.a.bc)

content::ThreadSafeSender::Send( [...])

child_discardable_shared_memory_manager.cc:187 (libcontent_child.a.bc)

content::ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory( [...])

child_discardable_shared_memory_manager.cc:97 (libcontent_child.a.bc)

content::ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory( [...])

discardable_memory_shmem.cc:34 (libbase.a.bc) discardable_memory_shmem.cc:34 (libbase.a.bc)

base::internal::DiscardableMemoryShmem::Lock( [...])

url_request.cc:735 (libnet.a.bc) SkDiscardableMemory_chrome.cc:10 (libskia_chrome.a.bc) SkDiscardableMemory_chrome.cc:10 (libskia_chrome.a.bc)

SkDiscardableMemoryChrome::lock( [...])

SkDiscardablePixelRef.cpp:41 (libskia_library.a.bc) SkDiscardablePixelRef.cpp:41 (libskia_library.a.bc)

SkDiscardablePixelRef::onNewLockPixels( [...])

SkPixelRef.cpp:157 (libskia_library.a.bc) SkPixelRef.cpp:157 (libskia_library.a.bc)

SkPixelRef::lockPixels(SkPixe [...])

SkPixelRef.cpp:170 (libskia_library.a.bc) SkPixelRef.cpp:170 (libskia_library.a.bc)

SkPixelRef::lockPixels()

SkBitmap.cpp:225 (libskia_library.a.bc) SkBitmap.cpp:225 (libskia_library.a.bc)

SkBitmap::lockPixels() const

SkBitmap.h:772 (libbrowser.a.bc) SkBitmap.h:772 (libbrowser.a.bc)

SkAutoLockPixels::SkAutoLockPixels( [...])

devtools_frame_trace_recorder.cc:81 (libcontent_browser.a.bc) devtools_frame_trace_recorder.cc:81 (libcontent_browser.a.bc)

content::DevToolsFrameTraceRecorderData::AppendAsTraceFormat( [...])

trace_event_impl.cc:785 (libbase.a.bc) trace_event_impl.cc:785 (libbase.a.bc)

base::trace_event::TraceEvent::AppendPrettyPrinted( [...])

trace_event_impl.cc:2084 (libbase.a.bc) trace_event_impl.cc:2084 (libbase.a.bc)

base::trace_event::TraceLog::EventToConsoleMessage( [...])

trace_event_impl.cc:2147 (libbase.a.bc)

base::trace_event::TraceLog::UpdateTraceEventDuration( [...])

trace_event.h:1492 (libbrowser.a.bc)

trace_event_internal::ScopedTracer::~ScopedTracer( [...])

content_main_runner.cc:752 (libcontent_app_both.a.bc)

content::ContentMainRunnerImpl::Initialize( [...])

content_main.cc:15 (libcontent_app_both.a.bc)

content::ContentMain(content: [...])

chrome_main.cc:66 (chrome.bc)

ChromeMain

net::URLRequest::Read(net::IO [...]) chrome_exe_main_aura.cc:17 (chrome.bc) main Program Version LOC Running time (secs) IR Null Vuln. Correct Info All fetch r252375 5K 1.17 0.05 0.05 0.06 0.06 0.06 OpenSSH 3.2.2 44K 3.8 0.3 0.3 0.3 0.3 0.3 OpenSSH 6.8 96K 8.7 1.15 1.15 1.15 1.15 1.15 Okular e03e6f 4.2 M 2970 14.28 14.66 14.73 14.74 15.37 Chromium 42 13.1 M 7300 195 261 2156 1028 3048

Table 2: The running times of various SOAAP modes of execution for each of our case studies.

4.5 SOAAP tool performance part of regular tinderboxing, it is easy to imagine a “tinder- Table 2 shows the time taken to run SOAAP on each of sandbox” that regularly reviews sandboxing tradeoffs and the case studies in three different modes. These modes are checks that past and new vulnerabilities are properly miti- selected to correspond to different stages in the development gated. This notion of integrating SOAAP into a continuous cycle for compartmentalized applications: integration cycle, as is done with other types of static anal- Vulnerability analysis checks which of the annotated ysis (e.g., Coverity Prevent) and testing seems promising. vulnerabilities would be mitigated within sandboxes. This mode is used for the first cut at describing a sandbox, to 6. RELATED WORK check that dangerous code is not run with ambient authority. The principle of least privilege and other security goals Sandbox correctness checks whether each of the sand- (such as protecting integrity, confidentiality, and avail- boxes tries to access resources (global variables, system calls, ability) were enumerated in Saltzer and Schroeder’s 1975 and so on) without being explicitly granted capabilities for article, The Protection of Information in Computer Sys- them. This mode is used to check that all of the communica- tems. Karger’s 1987 article on Trojan horse mitigation [18] tion between sandboxes is explicit. Once a program passes lays the conceptual groundwork for privilege separation, this mode, all points that need modifying are annotated. and later application compartmentalization, which became Information flow analysis is the final check, which en- mainstream techniques applied to system-level applications sures that sensitive information is not leaked between sand- in the early 2000s, with Provos’s work on OpenSSH [35], boxes. This is the final step before implementing a chosen and Kilpatrick’s Privman [19]. Application compartmental- compartmentalization strategy, which checks that the secu- ization is applied to user-level applications by Gong et al. in rity goals are met. This also includes the same checks as the Java [12], Reis et al. in the Chromium web browser [36], vulnerability analysis and would be run as part of a contin- and by Watson et al. in Capsicum [41] – where the focus uous integration build to check for sandboxing regressions. is on intra-application security concerns rather than system We distinguish between the cost to compile to LLVM IR privileges. All of these projects have reported difficulty in and the cost to perform the initial analysis setup of loading applying compartmentalization to C-language applications; the IR and building a call graph. We represent these as the we draw particularly on our own experience in developing two modes IR Compilation and Null analysis. Capsicum. The interfaces between separated components We also focus on the Chromium case study, as the one with have also been studied for their security implications – in the longest running time, to provide more detail on where particular, those of cryptographic security APIs [3], whose the time is being spent. Table 2 shows a breakdown of the lessons are also applicable to general-purpose compartmen- SOAAP run according to the time spent in different phases talization. The analysis of Beurdouche et al. [5] suggests of the analysis, generated from a profiling build of SOAAP. the need for further compartmentalization of the client and Note that there is some potential for optimization here, for server sides of OpenSSL and JSSE to mitigate surprising example 10% of the total time is spent on formatting JSON compositional vulnerabilities. output and 35% on reading in the LLVM IR. These can Brumley and Song’s Privtrans [8] and Bittau et al.’s both be improved, for example by constructing the JSON Wedge [6] explore techniques for assisting programmers in concurrently with the main thread and by demand-loading identifying and exploiting compartmentalization opportuni- the LLVM IR from separate files using some of the infras- ties. Privtrans takes a code-oriented view, focusing on di- tructure for more efficient link-time optimization support in viding operation between privileged and unprivileged pro- LLVM that is currently under development at Google [38]. cesses through program annotation, whereas Wedge relies on programmer-provided memory type information. Har- 5. FUTURE WORK ris et al.’s secure programming by parity games [15] reasons SOAAP has proven to be a useful tool for analyzing and about the defense characteristics of Capsicum compartmen- compartmentalizing programs in our environment. A natu- talization, representing policies as automata. ral next step would be to investigate fully automated com- SOAAP benefits from the object-capability philosophy partmentalization – which requires significantly more work explored in HYDRA [22] and rigorously extended by than a simple analysis tool: RPC stubs must be generated, Miller [27]. It is also comparable to Miller et al.’s or Met- and current false positives and negatives in analysis will be- tler et al.’s imposition of object-capability semantics on Java come actual bugs in generated code. Another valuable ex- in DarpaBrowser [39] or Joe-E [26] – albeit in the uncon- ploration would be wider deployment of SOAAP into the strained execution environment of UNIX processes rather software development community; with increasing adoption than a type-safe and already object-oriented language, and of the Clang/LLVM suite in the FreeBSD community, and so requiring the imposition of an object-oriented structure. that community’s heavy use of the Clang static analyzer as SOAAP incorporates decentralized information flow-control techniques [33], past vulnerability information, and source- in this paper are those of the authors and should not code risk analysis, allowing object-capability boundaries to be interpreted as representing the official views or poli- align with critical security constructs in the application and cies, either expressed or implied, of the Department of De- its libraries. Rather than implementing separation policies, fense or the U.S. Government. We also acknowledge the SOAAP is an exploration tool for programmers who may Isaac Newton Trust, the EPSRC REMS Programme Grant not fully understand the code that they are separating, rec- [EP/K008528/1], NSERC Discovery Grant RGPIN/06048- ognizing the complexity of large-scale applications. 2015, and Thales E-Security. Software decomposition for robustness (and sometimes se- curity) has a long history, seeing early exploration in mi- 10. REFERENCES crokernel designs [23], but performance concerns have dis- [1] Apple WebKit Vulnerability Statistics. http://www. couraged widespread use. Growing compartmentalization cvedetails.com/product/10007/Apple-Webkit.html. reflects two changes: improvement in hardware performance, [2] Anderson, J. Computer security technology planning and a pressing need for vulnerability mitigation. Klein et study. Tech. Rep. ESD-TR-73-51, U.S. Air Force al.’s SeL4 microkernel [20] offers a contemporary take on Electronic Systems Division, October 1972. microkernel design, achieving both performance and high as- [3] surance as a compartmentalization substrate. Hardware vir- Anderson, R., Bond, M., Clulow, J., and Cryptographic processors-a tualization extensions can support more efficient separation Skorobogatov, S. survey. Proceedings of the IEEE 94, 2 (Feb 2006), via hypervisors [32], and extensions to the process model 357–369. such as Belay et al.’s Dune [4]. Research architectures such as CHERI [42] may support vastly more scalable compart- [4] Belay, A., Bittau, A., Mashtizadeh, A., Terei, mentalization in the future. SOAAP’s model and analy- D., Mazieres,` D., and Kozyrakis, C. Dune: safe sis spans a broad range of compartmentalization substrates, user-level access to privileged CPU features. In and can assist developers in making safe and effective use of Proceedings of the 10th Conference on Operating new facilities as they become mainstream. Systems Design and Implementation (2012), USENIX. [5] Beurdouche, B., Bhargavan, K., Delignat-Lavaud, A., Fournet, C., Kohlweiss, 7. CONCLUSION M., Pironti, A., Strub, P.-Y., and Zinzindohoue, Application compartmentalization is a key vulnerabil- J. K. A Messy State of the Union: Taming the ity mitigation technique that addresses a broad range of Composite State Machines of TLS. In Proceedings of known (and unknown) attack vectors. Despite increasingly the IEEE Symposium on Security and Privacy (2015). widespread deployment, it is also an approach that is rife [6] Bittau, A., Marchenko, P., Handley, M., and with subtlety: we have demonstrated that developers are Karp, B. Wedge: Splitting Applications into challenged by the need to develop and maintain compart- Reduced-Privilege Compartments. In Proceedings of mentalizations that adequately trade off correctness, secu- the 5th USENIX Symposium on Networked Systems rity, complexity, and performance. SOAAP’s conceptual Design and Implementation (2008), USENIX. framework, and practical tools, have assisted us in analyzing [7] Boebert, W., and Kain, R. A practical alternative current compartmentalizations, and develop new ones, with to hierarchical integrity policies. In Proceedings of the greater understanding and confidence. SOAAP is scalable Eighth DoD/NBS Computer Security Initiative to multi-million LoC code bases, and we are hopeful that Conference (1985). this approach will facilitate greater deployment of compart- [8] Brumley, D., and Song, D. Privtrans: mentalization as a strong mitigation feature. automatically partitioning programs for privilege separation. In Proceedings of the 13th USENIX 8. AVAILABILITY Security Symposium (2004), USENIX. For further details, refer to an extended version of this [9] Dean, J., Grove, D., and Chambers, C. paper [13]. Our prototype is available as open source: Optimization of object-oriented programs using static class hierarchy analysis. In Proceedings of the 9th https://www.cl.cam.ac.uk/research/security/ctsrd/soaap/ European Conference on Object-Oriented Programming (1995), ECOOP ’95, Springer-Verlag. 9. ACKNOWLEDGMENTS [10] Dennis, J. B., and Van Horn, E. C. Programming We thank Ross Anderson, David Drysdale, Ulfar´ Er- semantics for multiprogrammed computations. lingsson, Somesh Jha, Steve Hand, William Harris, Ange- Commun. ACM 9, 3 (1966), 143–155. los Keromytis, Bob Laddaga, Anil Madhavapeddy, Simon [11] Dolan, S., Williams, N., Tolnay, D., Lapresta, Moore, Steven Murdoch, Robert Norton, Thomas Reps, S., Langford, W., and Gordan, A. jq: a Hassen Saidi, Howie Shrobe, Arun Thomas, Munraj Vadera, lightweight and flexible command-line JSON Sam Weber, and Jonathan Woodruff, as well as our anony- processor. http://stedolan.github.io/jq/. mous reviewers, for their feedback and assistance. We grate- [12] Gong, L., Mueller, M., Prafullchandra, H., fully acknowledge Google, Inc., for its support via a Fo- and Schemers, R. Going beyond the sandbox: An cused Research Award. This work is also part of the CT- overview of the new security architecture in the Java SRD, MRC2, and CADETS projects sponsored by the De- Development Kit 1.2. In Proceedings of the Symposium fense Advanced Research Projects Agency (DARPA) and on Internet Technologies and Systems (1997), the Air Force Research Laboratory (AFRL), under con- USENIX. tracts FA8750-10-C-0237, FA8750-11-C-0249, and FA8650- [13] Gudka, K., Watson, R. N. M., Anderson, J., 15-C-7558. The views, opinions, and/or findings contained Chisnall, D., Davis, B., Laurie, B., Madhavapeddy, A., Marinos, I., Murdoch, S. J., [29] MITRE. CVE-2014-0160. Neumann, P. G., and Richardson, A. Clean [30] MITRE. CVE-2014-4877. Application Compartmentalization with SOAAP [31] MITRE. CVE-2014-6271. (extended version). Tech. Rep. UCAM-CL-TR-873, [32] Murray, D. G., and Hand, S. Privilege separation University of Cambridge Computer Laboratory, Sept. made easy: trusting small libraries not big processes. 2015. In Proceedings of the 1st European Workshop on [14] Hamilton, G., and Kougiouris, P. The Spring System Security (2008), EUROSEC ’08, ACM. Nucleus: A microkernel for objects. In Proceedings of [33] Myers, A. C., and Liskov, B. A decentralized the 1993 Summer Usenix Conference (1993), USENIX. model for information flow control. SIGOPS Oper. [15] Harris, W. R., Farley, B., Jha, S., and Reps, T. Syst. Rev. 31 (October 1997), 129–142. Secure Programming as a Parity Game. Tech. Rep. [34] NIST. libpoppler CVEs. https://web.nvd.nist.gov/ 1694, University of Wisconsin Madison, July 2011. view/vuln/search-results?cpe_vendor=cpe:/: [16] Jurczyk, M., and Coldwind, G. FFmpeg and a freedesktop&cpe_product=cpe:/::poppler. thousand fixes. Google Online Security Blog, January [35] Provos, N., Friedl, M., and Honeyman, P. 2014. http://googleonlinesecurity.blogspot.com/ Preventing privilege escalation. In Proceedings of the 2014/01/ffmpeg-and-thousand-fixes.html. 12th USENIX Security Symposium (2003), USENIX. [17] Kamp, P., and Watson, R. N. M. Jails: Confining [36] Reis, C., and Gribble, S. D. Isolating web the omnipotent root. In Proceedings of the 2nd programs in modern browser architectures. In EuroSys International SANE Conference (2000). ’09: Proceedings of the 4th ACM European Conference [18] Karger, P. A. Limiting the damage potential of on Computer Systems (2009), ACM. discretionary trojan horses. In Proceedings of the IEEE [37] Saltzer, J. H., and Schroeder, M. D. The Symposium on Security and Privacy (1987), IEEE. protection of information in computer systems. [19] Kilpatrick, D. Privman: A Library for Partitioning Proceedings of the IEEE 63, 9 (September 1975), Applications. In Proceedings of USENIX Annual 1278–1308. Technical Conference (2003), USENIX. [38] Teresa Johnson, X. D. L. ThinLTO: A [20] Klein, G., Andronick, J., Elphinstone, K., Fine-Grained Demand-Driven Infrastructure. In Heiser, G., Cock, D., Derrin, P., Elkaduwe, D., EuroLLVM (2015). Engelhardt, K., Kolanski, R., Norrish, M., [39] Wagner, D., and Tribble, D. A security analysis of Sewell, T., Tuch, H., and Winwood, S. seL4: the combex darpabrowser architecture, March 2002. Formal verification of an operating-system kernel. [40] Watson, R. N. M. A decade of OS access-control Commun. ACM 53 (June 2009), 107–115. extensibility. Commun. ACM 56, 2 (Feb. 2013). [21] LLVM: A compilation Lattner, C., and Adve, V. [41] Watson, R. N. M., Anderson, J., Laurie, B., and framework for lifelong program analysis & Kennaway, K. Capsicum: Practical capabilities for transformation. In Proceedings of the International UNIX. In Proceedings of the 19th USENIX Security Symposium on Code Generation and Optimization Symposium (2010), USENIX. (2004), CGO ’04, IEEE. [42] Watson, R. N. M., Woodruff, J., Neumann, [22] Levin, R., Cohen, E., Corwin, W., Pollack, F., P. G., Moore, S. W., Anderson, J., Chisnall, D., Policy/mechanism separation in and Wulf, W. Dave, N., Davis, B., Gudka, K., Laurie, B., Hydra. In SOSP ’75: Proceedings of the fifth ACM Murdoch, S. J., Norton, R., Roe, M., Son, S., Symposium on Operating Systems Principles (1975). and Vadera, M. CHERI: A Hybrid [23] Lipner, S. B., Wulf, W. A., Schell, R. R., Capability-System Architecture for Scalable Software Popek, G. J., Neumann, P. G., Weissman, C., Compartmentalization. In Proceedings of the 36th and Linden, T. A. Security kernels. In AFIPS ’74: IEEE Symposium on Security and Privacy (2015). Proceedings of the May 6-10, 1974, National Computer Conference and Exposition (1974), ACM. APPENDIX [24] Loscocco, P., and Smalley, S. Integrating flexible support for security policies into the linux operating A. ADDITIONAL GRAPH DETAIL system. In Proceedings of the USENIX Annual Figure 10 provides a larger example of a call and data Technical Conference (2001), USENIX. flow graph emitted by SOAAP tools than could be included [25] McKusick, M. K., Neville-Neil, G. V., and in Section 4.4. This particular graph is an example of a Watson, R. N. M. The Design and Implementation false-positive result that was obtained by annotating a low- of the FreeBSD Operating System. Pearson, 2014. level networking method that is used by several Chromium [26] Mettler, A., Wagner, D., and Close, T. Joe-E: subsystems, not just communication with remote hosts. A Security-Oriented Subset of Java. In Proceedings of the Network and Distributed System Security Symposium (2010), NDSS’10. [27] Miller, M. S. Robust composition: towards a unified approach to access control and concurrency control. PhD thesis, Johns Hopkins University, Baltimore, MD, USA, 2006. [28] MITRE. CVE-2012-0652. blink::InlineFlowBox::getFlowSpacingLogicalWidth( [...])

RenderBlockLineLayout.cpp:582 (libwebcore_rendering.a.bc) RenderBlockLineLayout.cpp:582 (libwebcore_rendering.a.bc)

blink::InlineFlowBox::addToLine( [...]) blink::RenderBlockFlow::computeInlineDirectionPositionsForSegment( [...]) [[Cr issue #51602]]

RenderBlockLineLayout.cpp:570 (libwebcore_rendering.a.bc) RenderBlockLineLayout.cpp:570 (libwebcore_rendering.a.bc) RenderBlockLineLayout.cpp:234 (libwebcore_rendering.a.bc)

blink::RenderBlockFlow::computeInlineDirectionPositionsForLine( [...]) blink::RenderBlockFlow::constructLine( [...])

RenderBlockLineLayout.cpp:698 (libwebcore_rendering.a.bc) RenderBlockLineLayout.cpp:698 (libwebcore_rendering.a.bc) RenderBlockLineLayout.cpp:685 (libwebcore_rendering.a.bc)

blink::RenderBlockFlow::createLineBoxesFromBidiRuns( [...])

RenderBlockLineLayout.cpp:860 (libwebcore_rendering.a.bc) RenderBlockLineLayout.cpp:860 (libwebcore_rendering.a.bc)

blink::RenderBlockFlow::layoutRunsAndFloatsInRange( [...])

RenderBlockLineLayout.cpp:770 (libwebcore_rendering.a.bc) RenderBlockLineLayout.cpp:770 (libwebcore_rendering.a.bc)

blink::RenderBlockFlow::layoutRunsAndFloats( [...])

RenderBlockLineLayout.cpp:1590 (libwebcore_rendering.a.bc) RenderBlockLineLayout.cpp:1590 (libwebcore_rendering.a.bc)

blink::RenderBlockFlow::layoutInlineChildren( [...])

LayoutSVGText.cpp:389 (libwebcore_svg.a.bc) LayoutSVGText.cpp:389 (libwebcore_svg.a.bc)

blink::LayoutSVGText::layout()

FrameView.cpp:857 (libwebcore_remaining.a.bc) FrameView.cpp:857 (libwebcore_remaining.a.bc)

blink::FrameView::performLayout( [...])

FrameView.cpp:1015 (libwebcore_remaining.a.bc) FrameView.cpp:1015 (libwebcore_remaining.a.bc)

blink::InlineFlowBox::getFlowSpacingLogicalWidth(blink::FrameView::layout() [...])

RenderBlockLineLayout.cpp:582 Document.cpp:2537(libwebcore_rendering.a.bc) (libwebcore_dom.a.bc)RenderBlockLineLayout.cpp:582Document.cpp:2537 (libwebcore_rendering.a.bc) (libwebcore_dom.a.bc)

blink::Document::implicitClose( [...]) blink::InlineFlowBox::addToLine( [...]) blink::RenderBlockFlow::computeInlineDirectionPositionsForSegment( [...]) [[Cr issue #51602]] XMLHttpRequest.cpp:1557 (libwebcore_remaining.a.bc) FrameLoader.cpp:494 (libwebcore_remaining.a.bc) RenderBlockLineLayout.cpp:570 (libwebcore_rendering.a.bc) RenderBlockLineLayout.cpp:570 (libwebcore_rendering.a.bc) RenderBlockLineLayout.cpp:234 (libwebcore_rendering.a.bc) blink::XMLHttpRequest::notifyParserStopped( [...]) blink::FrameLoader::checkCompleted( [...]) blink::RenderBlockFlow::computeInlineDirectionPositionsForLine( [...]) blink::RenderBlockFlow::constructLine( [...]) DocumentParser.cpp:90 (libwebcore_dom.a.bc) FrameLoader.cpp:617 (libwebcore_remaining.a.bc) RenderBlockLineLayout.cpp:698 (libwebcore_rendering.a.bc) RenderBlockLineLayout.cpp:698 (libwebcore_rendering.a.bc) RenderBlockLineLayout.cpp:685 (libwebcore_rendering.a.bc) blink::DocumentParser::stopParsing( [...]) blink::FrameLoader::loadInSameDocument( [...]) blink::RenderBlockFlow::createLineBoxesFromBidiRuns( [...]) XMLHttpRequest.cpp:1105 (libwebcore_remaining.a.bc) FrameLoader.cpp:1358 (libwebcore_remaining.a.bc) RenderBlockLineLayout.cpp:860 (libwebcore_rendering.a.bc) RenderBlockLineLayout.cpp:860 (libwebcore_rendering.a.bc) blink::XMLHttpRequest::internalAbort( [...]) blink::FrameLoader::loadHistoryItem( [...]) blink::RenderBlockFlow::layoutRunsAndFloatsInRange( [...]) XMLHttpRequest.cpp:1219 (libwebcore_remaining.a.bc) FrameLoader.cpp:177 (libwebcore_remaining.a.bc) RenderBlockLineLayout.cpp:770 (libwebcore_rendering.a.bc) RenderBlockLineLayout.cpp:770 (libwebcore_rendering.a.bc) blink::XMLHttpRequest::handleDidCancel( [...]) blink::FrameLoader::setDefersLoading( [...]) blink::RenderBlockFlow::layoutRunsAndFloats( [...]) XMLHttpRequest.cpp:1425 (libwebcore_remaining.a.bc) Page.cpp:316 (libwebcore_remaining.a.bc) RenderBlockLineLayout.cpp:1590 (libwebcore_rendering.a.bc) RenderBlockLineLayout.cpp:1590 (libwebcore_rendering.a.bc) blink::XMLHttpRequest::didFail( [...]) blink::Page::setDefersLoading( [...]) blink::RenderBlockFlow::layoutInlineChildren( [...]) DocumentThreadableLoader.cpp:244 (libwebcore_remaining.a.bc) ScopedPageLoadDeferrer.cpp:51 (libwebcore_remaining.a.bc) LayoutSVGText.cpp:389 (libwebcore_svg.a.bc) LayoutSVGText.cpp:389 (libwebcore_svg.a.bc) blink::DocumentThreadableLoader::cancelWithError( [...]) blink::ScopedPageLoadDeferrer::ScopedPageLoadDeferrer( [...]) blink::LayoutSVGText::layout() DocumentThreadableLoader.cpp:229 (libwebcore_remaining.a.bc) WebViewImpl.cpp:317 (libblink_web.a.bc) FrameView.cpp:857 (libwebcore_remaining.a.bc) FrameView.cpp:857 (libwebcore_remaining.a.bc) blink::DocumentThreadableLoader::cancel( [...]) blink::WebView::willEnterModalLoop( [...]) blink::FrameView::performLayout( [...]) WorkerScriptLoader.cpp:183 (libwebcore_remaining.a.bc) render_thread_impl.cc:828 (libcontent_renderer.a.bc) FrameView.cpp:1015 (libwebcore_remaining.a.bc) FrameView.cpp:1015 (libwebcore_remaining.a.bc) blink::WorkerScriptLoader::cancel( [...]) content::RenderThreadImpl::Send( [...]) blink::FrameView::layout() WebSharedWorkerImpl.cpp:116 (libblink_web.a.bc) thread_safe_sender.cc:24 (libcontent_child.a.bc) Document.cpp:2537 (libwebcore_dom.a.bc) Document.cpp:2537 (libwebcore_dom.a.bc) blink::WebSharedWorkerImpl::Loader::cancel( [...]) content::ThreadSafeSender::Send( [...]) blink::Document::implicitClose( [...]) WebSharedWorkerImpl.cpp:186 (libblink_web.a.bc) child_discardable_shared_memory_manager.cc:187 (libcontent_child.a.bc) XMLHttpRequest.cpp:1557 (libwebcore_remaining.a.bc) FrameLoader.cpp:494 (libwebcore_remaining.a.bc) blink::WebSharedWorkerImpl::stopWorkerThread( [...]) content::ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory( [...]) blink::XMLHttpRequest::notifyParserStopped( [...]) blink::FrameLoader::checkCompleted( [...]) WebSharedWorkerImpl.cpp:433 (libblink_web.a.bc) child_discardable_shared_memory_manager.cc:97 (libcontent_child.a.bc) DocumentParser.cpp:90 (libwebcore_dom.a.bc) FrameLoader.cpp:617 (libwebcore_remaining.a.bc) blink::WebSharedWorkerImpl::terminateWorkerContext( [...]) content::ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory( [...]) blink::DocumentParser::stopParsing( [...]) blink::FrameLoader::loadInSameDocument( [...]) embedded_shared_worker_stub.cc:294 (libcontent_renderer.a.bc) discardable_memory_shmem.cc:34 (libbase.a.bc) discardable_memory_shmem.cc:34 (libbase.a.bc) XMLHttpRequest.cpp:1105 (libwebcore_remaining.a.bc) FrameLoader.cpp:1358 (libwebcore_remaining.a.bc) content::EmbeddedSharedWorkerStub::OnTerminateWorkerContext( [...]) base::internal::DiscardableMemoryShmem::Lock( [...]) blink::XMLHttpRequest::internalAbort( [...]) blink::FrameLoader::loadHistoryItem( [...]) embedded_shared_worker_stub.cc:160 (libcontent_renderer.a.bc) SkDiscardableMemory_chrome.cc:10 (libskia_chrome.a.bc) SkDiscardableMemory_chrome.cc:10 (libskia_chrome.a.bc) XMLHttpRequest.cpp:1219 (libwebcore_remaining.a.bc) FrameLoader.cpp:177 (libwebcore_remaining.a.bc) content::EmbeddedSharedWorkerStub::OnChannelError( [...]) SkDiscardableMemoryChrome::lock( [...]) blink::XMLHttpRequest::handleDidCancel( [...]) blink::FrameLoader::setDefersLoading( [...]) ipc_channel_mojo.cc:312 (libipc_mojo.a.bc) SkDiscardablePixelRef.cpp:41 (libskia_library.a.bc) SkDiscardablePixelRef.cpp:41 (libskia_library.a.bc) XMLHttpRequest.cpp:1425 (libwebcore_remaining.a.bc) Page.cpp:316 (libwebcore_remaining.a.bc) IPC::ChannelMojo::OnPipeError( [...]) SkDiscardablePixelRef::onNewLockPixels( [...]) blink::XMLHttpRequest::didFail( [...]) blink::Page::setDefersLoading( [...]) ipc_message_pipe_reader.cc:100 (libipc_mojo.a.bc) SkPixelRef.cpp:157 (libskia_library.a.bc) SkPixelRef.cpp:157 (libskia_library.a.bc) DocumentThreadableLoader.cpp:244 (libwebcore_remaining.a.bc) ScopedPageLoadDeferrer.cpp:51 (libwebcore_remaining.a.bc) IPC::internal::MessagePipeReader::OnPipeError( [...]) SkPixelRef::lockPixels(SkPixe [...]) blink::DocumentThreadableLoader::cancelWithError( [...]) blink::ScopedPageLoadDeferrer::ScopedPageLoadDeferrer( [...]) ipc_message_pipe_reader.cc:38 (libipc_mojo.a.bc) SkPixelRef.cpp:170 (libskia_library.a.bc) SkPixelRef.cpp:170 (libskia_library.a.bc) DocumentThreadableLoader.cpp:229 (libwebcore_remaining.a.bc) WebViewImpl.cpp:317 (libblink_web.a.bc) IPC::internal::MessagePipeReader::CloseWithError( [...]) SkPixelRef::lockPixels() blink::DocumentThreadableLoader::cancel( [...]) blink::WebView::willEnterModalLoop( [...]) ipc_message_pipe_reader.cc:62 (libipc_mojo.a.bc) SkBitmap.cpp:225 (libskia_library.a.bc) SkBitmap.cpp:225 (libskia_library.a.bc) WorkerScriptLoader.cpp:183 (libwebcore_remaining.a.bc) render_thread_impl.cc:828 (libcontent_renderer.a.bc) IPC::internal::MessagePipeReader::Send( [...]) SkBitmap::lockPixels() const blink::WorkerScriptLoader::cancel( [...]) content::RenderThreadImpl::Send( [...]) ipc_channel_mojo.cc:322 (libipc_mojo.a.bc) SkBitmap.h:772 (libbrowser.a.bc) SkBitmap.h:772 (libbrowser.a.bc) WebSharedWorkerImpl.cpp:116 (libblink_web.a.bc) thread_safe_sender.cc:24 (libcontent_child.a.bc) IPC::ChannelMojo::Send(IPC::M [...]) SkAutoLockPixels::SkAutoLockPixels( [...]) blink::WebSharedWorkerImpl::Loader::cancel( [...]) content::ThreadSafeSender::Send( [...]) event_router.cc:136 (libextensions_browser.a.bc) devtools_frame_trace_recorder.cc:81 (libcontent_browser.a.bc) devtools_frame_trace_recorder.cc:81 (libcontent_browser.a.bc) WebSharedWorkerImpl.cpp:186 (libblink_web.a.bc) child_discardable_shared_memory_manager.cc:187 (libcontent_child.a.bc) extensions::EventRouter::DispatchExtensionMessage( [...]) content::DevToolsFrameTraceRecorderData::AppendAsTraceFormat( [...]) blink::WebSharedWorkerImpl::stopWorkerThread( [...]) content::ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory( [...]) event_router.cc:170 (libextensions_browser.a.bc) trace_event_impl.cc:785 (libbase.a.bc) trace_event_impl.cc:785 (libbase.a.bc) WebSharedWorkerImpl.cpp:433 (libblink_web.a.bc) child_discardable_shared_memory_manager.cc:97 (libcontent_child.a.bc) extensions::EventRouter::DispatchEvent( [...]) base::trace_event::TraceEvent::AppendPrettyPrinted( [...]) blink::WebSharedWorkerImpl::terminateWorkerContext( [...]) content::ChildDiscardableSharedMemoryManager::AllocateLockedDiscardableMemory( [...]) web_request_api.cc:1209 (libextensions_browser.a.bc) trace_event_impl.cc:2084 (libbase.a.bc) trace_event_impl.cc:2084 (libbase.a.bc) embedded_shared_worker_stub.cc:294 (libcontent_renderer.a.bc) discardable_memory_shmem.cc:34 (libbase.a.bc) discardable_memory_shmem.cc:34 (libbase.a.bc) ExtensionWebRequestEventRouter::DispatchEvent( [...]) base::trace_event::TraceLog::EventToConsoleMessage( [...]) content::EmbeddedSharedWorkerStub::OnTerminateWorkerContext( [...]) base::internal::DiscardableMemoryShmem::Lock( [...]) web_request_api.cc:1124 (libextensions_browser.a.bc) trace_event_impl.cc:2147 (libbase.a.bc) embedded_shared_worker_stub.cc:160 (libcontent_renderer.a.bc) SkDiscardableMemory_chrome.cc:10 (libskia_chrome.a.bc) SkDiscardableMemory_chrome.cc:10 (libskia_chrome.a.bc) ExtensionWebRequestEventRouter::OnCompleted( [...]) base::trace_event::TraceLog::UpdateTraceEventDuration( [...]) content::EmbeddedSharedWorkerStub::OnChannelError( [...]) SkDiscardableMemoryChrome::lock( [...]) chrome_extensions_network_delegate.cc:216 (libbrowser.a.bc) trace_event.h:1492 (libbrowser.a.bc) previously_vulnerable ipc_channel_mojo.cc:312 (libipc_mojo.a.bc) SkDiscardablePixelRef.cpp:41 (libskia_library.a.bc) SkDiscardablePixelRef.cpp:41 (libskia_library.a.bc) [[CVE-1900-XXXXX]] ( namespace)::Chrome [...]) trace_event_internal::ScopedTracer::~ScopedTracer( [...]) IPC::ChannelMojo::OnPipeError( [...]) SkDiscardablePixelRef::onNewLockPixels( [...]) network_delegate.cc:147 (libnet.a.bc) content_main_runner.cc:752 (libcontent_app_both.a.bc) vulnerability_mitigated ipc_message_pipe_reader.cc:100 (libipc_mojo.a.bc) SkPixelRef.cpp:157 (libskia_library.a.bc) SkPixelRef.cpp:157 (libskia_library.a.bc) [[CVE-1900-XXXXX]] net::NetworkDelegate::NotifyCompleted( [...]) content::ContentMainRunnerImpl::Initialize( [...]) <> IPC::internal::MessagePipeReader::OnPipeError( [...]) SkPixelRef::lockPixels(SkPixe [...]) url_request.cc:1174 (libnet.a.bc) content_main.cc:15 (libcontent_app_both.a.bc) ipc_message_pipe_reader.cc:38 (libipc_mojo.a.bc) SkPixelRef.cpp:170 (libskia_library.a.bc) SkPixelRef.cpp:170 (libskia_library.a.bc) net::URLRequest::NotifyRequestCompleted( [...]) content::ContentMain(content: [...]) sandboxed <> IPC::internal::MessagePipeReader::CloseWithError( [...]) [ ... detailSkPixelRef::lockPixels() elided ... ] chrome_main.cc:66 (chrome.bc) ipc_message_pipe_reader.cc:62 (libipc_mojo.a.bc) SkBitmap.cpp:225 (libskia_library.a.bc) SkBitmap.cpp:225 (libskia_library.a.bc) url_request.cc:744 (libnet.a.bc) ChromeMain private_access IPC::internal::MessagePipeReader::Send( [...]) SkBitmap::lockPixels() const

net::URLRequest::Read(net::IO [...]) chrome_exe_main_aura.cc:17 (chrome.bc) ipc_channel_mojo.cc:322 (libipc_mojo.a.bc) SkBitmap.h:772 (libbrowser.a.bc) SkBitmap.h:772 (libbrowser.a.bc) ordinary_function

IPC::ChannelMojo::Send(IPC::M [...]) SkAutoLockPixels::SkAutoLockPixels(main [...]) Legend

event_router.cc:136 (libextensions_browser.a.bc) devtools_frame_trace_recorder.cc:81 (libcontent_browser.a.bc) devtools_frame_trace_recorder.cc:81 (libcontent_browser.a.bc)

extensions::EventRouter::DispatchExtensionMessage( [...]) content::DevToolsFrameTraceRecorderData::AppendAsTraceFormat( [...])

Figure 10: An exampleevent_router.cc:170 of a false (libextensions_browser.a.bc) positive result (cropped to fit: wetrace_event_impl.cc:785 have elided (libbase.a.bc) ninetrace_event_impl.cc:785 calls and (libbase.a.bc) eight flows). Here, data flows from

URLRequest::Readextensions::EventRouter::DispatchEvent(towards previously [...]) vulnerable code,base::trace_event::TraceEvent::AppendPrettyPrinted( which we deem to be [...]) “risky” code. However, these data flows go through

IPC interfaces that areweb_request_api.cc:1209 used for (libextensions_browser.a.bc) communicating between the browsertrace_event_impl.cc:2084 and renderer(libbase.a.bc) trace_event_impl.cc:2084 processes. (libbase.a.bc) Rather than exposing privileged code to arbitraryExtensionWebRequestEventRouter::DispatchEvent( data, this data [...]) flow passes highlybase::trace_event::TraceLog::EventToConsoleMessage( constrained data for the[...]) purpose of enabling compartmentalization.

web_request_api.cc:1124 (libextensions_browser.a.bc) trace_event_impl.cc:2147 (libbase.a.bc)

ExtensionWebRequestEventRouter::OnCompleted( [...]) base::trace_event::TraceLog::UpdateTraceEventDuration( [...])

chrome_extensions_network_delegate.cc:216 (libbrowser.a.bc) trace_event.h:1492 (libbrowser.a.bc)

(anonymous namespace)::Chrome [...]) trace_event_internal::ScopedTracer::~ScopedTracer( [...])

network_delegate.cc:147 (libnet.a.bc) content_main_runner.cc:752 (libcontent_app_both.a.bc)

net::NetworkDelegate::NotifyCompleted( [...]) content::ContentMainRunnerImpl::Initialize( [...])

url_request.cc:1174 (libnet.a.bc) content_main.cc:15 (libcontent_app_both.a.bc)

net::URLRequest::NotifyRequestCompleted( [...]) content::ContentMain(content: [...])

chrome_main.cc:66 (chrome.bc)

url_request.cc:744 (libnet.a.bc) ChromeMain

net::URLRequest::Read(net::IO [...]) chrome_exe_main_aura.cc:17 (chrome.bc)

main