P2FAAS: Toward Privacy-Preserving Fuzzing as a Service

Global corporations (e.g., Google and Microsoft) have recently introduced a new model of cloud services, fuzzing-as-a-service (FaaS). Despite effectively alleviating the cost of fuzzing, the model comes with privacy concerns. For example, the end user has to trust both cloud and service providers who have access to the application to be fuzzed. Such concerns are due to the platform is under the control of its provider and the application and the fuzzer are highly coupled. In this paper, we propose P2FaaS, a new ecosystem that preserves end user's privacy while providing FaaS in the cloud. The key idea of P2FaaS is to utilize Intel SGX for preventing cloud and service providers from learning information about the application. Our preliminary evaluation shows that P2FaaS imposes 45% runtime overhead to the fuzzing compared to the baseline. In addition, P2FaaS demonstrates that, with recently introduced hardware, Intel SGX Card, the fuzzing service can be scaled up to multiple servers without native SGX support.


Introduction
Fuzzing-as-a-service (FaaS) is an emerging paradigm to accelerate the adoption of a popular bug finding technique, fuzzing. FaaS services, such as Google OSS-Fuzz [8], Microsoft Security Risk Detection [21], and Fuzzbuzz [5], have been designed to alleviate technical and operational burdens of integrating fuzzing as part of software development: e.g., incorporating a well-known fuzzing driver, such as AFL [18], that provides various mutation strategies for the software under testing, and scaling it to a large number of servers on demand.
However, such benefits come with serious privacy concerns of the software, hindering the wider adoption of the fuzzing technique. First of all, in the current FaaS model, developers should trust the cloud provider, its underlying infrastructure, as well as operators; it means that pre-released software under active development has to leave out of the developer's complete control. Second, since the fuzzing techniques are continuously discovering 0day vulnerabilities, malicious (i.e., compromised or curious [4]) cloud providers would face some incentives to monetize the security bugs without disclosing them to the software developers. Third, such limitations are the concerns of not just the users (i.e., software developers) but cloud providers as well: the cloud providers should spend more operating costs to manage the security of the infrastruc-ture and the users' software, as well as to avoid the damage of the users' reputation when leaked.
We propose a new ecosystem that preserves users' privacy while servicing fuzzing on the cloud, shortly P 2 FAAS. The key idea is to utilize a modern, commodity trusted execution environment (TEE), called Intel SGX, as the root of trust. It not only helps FaaS' users eliminate the cloud provider from the trust domain, but also helps the FaaS providers focus on taking advantage of the economy of scaling without worrying about users' privacy. We believe fuzzing can be a killer application of SGX for two reasons: 1) fuzzing is a CPU intensive task avoiding the current memory limitation of SGX, and 2) when the active working set is small, SGX provides near-native performance so that developers do not have to trade performance-fuzzer's great strength-off for privacy.
This paper attempts to draw a picture of an end-to-end ecosystem of the SGX-enabled FaaS that addresses the privacy concerns of end-users as well as the scalability and early adoption of the fuzzing service. P 2 FAAS provides a toolchain that assists developers to package their software for testing in a privacy-preserving manner ( §4.2) securely scaling to multiple servers as necessary ( §4.3), and helps the cloud operators to adopt it even on a legacy server with an extension card, Intel SGX Card ( §4.4). We make P 2 FAAS as an open-source project to inspire and direct current FaaS providers to foster the fuzzing techniques for broader audience in a convenient and privacy-aware manner. Summary. This paper makes the following contributions: • We propose an end-to-end ecosystem, P 2

Background and Related Work
Fuzzing. The idea of fuzzing is providing randomly mutated inputs to a program that aims for triggering abnormal behaviors such as crashes representing potential bugs. This process allows fuzzing to execute automatically and detect bugs with high accuracy. To improve the effectiveness of fuzzing, one direction is to increase the throughput of fuzzing. Approaches for this direction include scaling up the fuzzing with distributed machines [7] and designing specialized system support [30]. Another direction is to improve the strategy of the seed selection; that is, inputs derived from a seed that trigger more execution paths of the program usually lead to more bug findings.
Fuzzing as a service. Instead of physically owning and maintaining multiple machines for fuzzing, end-users now have an option to fuzz their applications on the cloud via "fuzzing as a service" (FaaS). The idea of FaaS has service providers to set up the fuzzing infrastructure, typically involves numbers of machines, on the cloud such that end users can fuzz their applications with a pay-as-you-go model. The existing service providers include cloud providers themselves (e.g., Microsoft and Google) and third parties (e.g., Fuzzbuzz and Fuzzit). Although FaaS makes fuzzing more accessible and successfully finds thousands of bugs in real-world applications, privacy concerns arise.
Intel SGX Applications.
Communities have proposed several SGX-based solutions for preserving privacy in existing applications. The examples include network functions [26,24], anonymity network [14,13], and machine learning [22,11]. To the best of our knowledge, P 2 FAAS is the first work that uses SGX to address the privacy problem with FaaS. Intel SGX Card. Although quickly becoming a general security feature in recent desktop-focused CPUs, SGX receives relatively small support in server-class CPUs that cloud platforms typically adopt. To fill this gap, Intel has recently introduced new hardware, the Intel SGX Card. Intel SGX Card is a re-configured graphic card that consists of three independent, SGX-capable CPUs. Similar to a graphic card, the Intel SGX Card is pluggable to multi-socket server CPUs (connected via PCIe interfaces), and each CPU can have up to four such cards. As a result, the cards allow both an SGX-and a none-SGX-capable CPU to have additional SGX support with a high resource density. Moreover, opposed to buying new SGX-capable machines, adding the cards to existing ones is more cost-and space-efficient. These advantages make the Intel SGX Card an optimal, practical option in response to the growing demand of SGX support in the cloud [6,19].

Threat Model
The setting of P 2 FAAS involves three parties, including a cloud provider who offers SGX-capable platforms, a service provider who sets up fuzzers with enclaves in the cloud platforms and offers fuzzing as a service, and an end-user who uses the service to fuzz her application. Among these parties, P 2 FAAS assumes the cloud provider is the only untrusted one-either being compromised or simply because of the other parties do not fully trust-who aims for obtaining information about the fuzzer and the application which both are proprietary. Having full control over the cloud platforms, the cloud provider can intercept all the incoming and outgoing network traffic. Further, the cloud provider can freely analyze an initial program binary to be running inside an enclave. However, our model assumes the program binary does not contain memory corruption vulnerabilities that allow for control-flow hijacking and memory leaks. Although SGX ensures the confidentiality of the enclave during its runtime, the cloud provider may still learn information about the enclave based on observable behaviors such as crashes. Our model considers side-channel attacks [9,31,16] against SGX as out of scope. However, existing side-channel mitigations [27,10,23] are applicable to P 2 FAAS.

Goals
1 Privacy-preserving. P 2 FAAS considers two types of privacy: a fuzzing instance and its runtime behavior. The fuzzing instance includes a target program and a fuzzer that provides mutated inputs. In addition to prevent the cloud provider from accessing the program and the fuzzer, P 2 FAAS also aims for protecting the inputs, especially for ones that trigger crashes. Leakage of such inputs indirectly discloses the vulnerabilities of the program. Moreover, P 2 FAAS aims to prevent the cloud provider from directly inferring the observable runtime behavior, more specifically, crashes. The occurrence of crashes directly affects the reputation of end users (i.e., indicating the number of bugs in the program). 2 Performance. Runtime performance directly contributes to the quality of fuzzing services (i.e., number of bugs found). Poor performance reduces the quality of service and weakens the motivation of using the service. Therefore, naïvely trading performance for privacy in the case of fuzzing is not acceptable. P 2 FAAS aims to maintain the fuzzing performance while achieving privacy preservation ( 1 ). 3 Deployability. P 2 FAAS aims for being deployable to existing cloud platforms. One aspect for this requirement is that platforms should provide SGX support that P 2 FAAS depends on. For platforms that already provide native SGX support, such as Microsoft Azure [20] and IBM Cloud [12], P 2 FAAS is directly deployable. For platforms provide SGX support via additional hardware (e.g, Intel SGX Card), P 2 FAAS should also accommodate to such environment. The other aspect is that P 2 FAAS should allow for easily adoption; that is, the service provider requires minimal effort to scale up the fuzzing service across multiple machines regardless of the type of SGX support (native or non-native).

Workflow
We provide a detailed walk-through of steps to achieve a complete service cycle with P 2 FAAS, as shown in Figure 1. 1 Fuzzing toolchain. The service provider develops a complete fuzzing tool-chain in order to provide fuzzing service. Those tools include, but not limited to, a fuzzer and corresponding public APIs, a compiler that generates binaries conform to SGX programming practices, and a loader that loads both the fuzzer and the target program into SGX enclave memory. Although parts of the fuzzing toolchain, the compiler and loader are not privacy sensitive but publicly available and verifiable, serving as trusted anchors to assist further provisioning of the fuzzing instance into trusted SGX enclave memory.
2 Service tool provisioning. The toolchain loader developed by the service provider will be provisioned to SGX enclaves by cloud providers before fuzzer APIs are released to the public. Once provisioned, the cloud provider will be ready to accept fuzzing instance submissions and serve endusers with fuzzing service.
3 Applying fuzzer API. The prospective end-user integrates fuzzer APIs released by the service provider into the target program during development, and compiles the program using the toolchain compiler. Usages of fuzzer APIs vary across different fuzzers and is up to the service provider to specify. 4 Fuzzing instance provisioning. The target program binary will be submitted to the cloud provider after being compiled by the end-user. Meanwhile, the service provider will be notified and the corresponding fuzzer binary matching the fuzzer API usages of the target program will also be submitted to the cloud provider. The toolchain loader will then load the fuzzer binary and the target program binary into individual SGX local enclaves when both are present. 5 Fuzzing instance execution. After both the fuzzer and target program binaries are loaded into SGX enclaves, execution of the fuzzing instance starts. Necessary service information is transmitted constantly via the trusted communication channel between local enclaves. Specifically, the fuzzer generates and passes numerous inputs to the target program for execution, and the target program passes back essential feedback information to the fuzzer for consumption (e.g., coverage feedback, crashes). 6 Fuzzing results. Finally, the fuzzing service periodically sends fuzzing results (e.g., crashes triggered) back to the end-user via a trusted communication channel between the cloud provider and the end-user. The trusted communication channel can either be established as TLS using SGX Remote Attestation, as suggested by Intel [15], or other methods specified by the providers.

Oblivious Crash
The fuzzing instance is naturally protected since it entirely resides in SGX enclave memory. However, program behaviors especially crashes, require additional protection mechanisms as the cloud provider is directly aware of such events. P 2 FAAS resolves this challenge by introducing a technique called oblivious crash. Whose name adopted from oblivious memory, oblivious crash hides the actual crash behavior from observers. That is, by randomly generating fake crashes from the target program after fuzzer instrumentation, the crashing behavior is normalized and external observers cannot distinguish real crashes from fake ones.
Not only that, P 2 FAAS also utilizes fakes crashes as heartbeat messages to attest availability and legitimacy of cloud provider. On one hand, fake crash results with extended time interval indicates reduced network condition, and failing to deliver fake crashes periodically indicates lost of service availability. On the other hand, degraded fake crash heartbeat quality might also indicate potentially malicious operations are performed, e.g. the cloud provider pauses the execution and attempts to distinguish fake crashes. P 2 FAAS provides the end user with a handful way to sense such situations upon experiencing different heartbeat behaviors, and react accordingly.

In-Memory Corpus Management
One of the significant performance bottlenecks of SGX application is OCalls. To minimize OCalls while fuzzing, P 2 FAAS keeps the corpus and coverage map inside the enclave as long as the memory can tolerate. From the initial fuzzer setup, P 2 FAAS reads in every content of the shared corpus directory. Afterwards, corpus related operations such as mutating and pruning are done inside the memory. If the memory is overwhelmed, or the corpus status is significantly updated, the in-memory corpus is synced with the shared corpus directory. Ultimately, the shared corpus directory selectively holds the corpus that maximizes the code coverage.

Platform-independent Architecture
Similar to traditional fuzzing in parallel [30], P 2 FAAS fuzzing instances can easily run on multiple SGX-capable nodes in parallel to scale up execution speed. However, as shown in Figure 1, there are two types of platforms within cloud providers: SGX-capable platforms and SGX-incapable ones. Likely, instances reside in different cloud providers consist of a mixture of those two types of platforms.
In order to deploy P 2 FAAS fuzzing instances on multiple cloud nodes in parallel and achieve the performance scalability without platform restriction, P 2 FAAS considers Intel SGX Card as the most economical and pluggable SGX enabler for SGX-incapable platforms. Mutated inputs are shared via the network across all P 2 FAAS fuzzing instances (shown by 5 in Figure 1), either hosted on natively SGX-capable platforms, or hosted on SGX nodes inside Intel SGX Cards. Therefore, P 2 FAAS achieves platform-independent deployability and scalability by treating each SGX-incapable platforms as several (3-12) SGX-capable nodes enabled by Intel SGX Cards. We further show that distributing P 2 FAAS to SGX nodes enabled by Intel SGX Card achieves the same performance scalability as by multiple natively SGX-capable instances in section §6, proving that Intel SGX Card is the key to maximize P 2 FAAS deployability and scalability.

Implementation
We implemented the prototype of P 2 FAAS with roughly 1,000 lines of C code on top of existing open source projects (SGX-Shield [25] and libfuzzer [17]). The prototype includes a fuzzer, a customized toolchain, and an in-enclave loader.
Fuzzer. For simplicity, our fuzzer adopts the model of libfuzzer, which is a part of the target program, allowing the program to fuzz itself. We leave the fuzzer decoupling from the program as future work. Our fuzzer is tailored to dealing with the limitations of SGX (e.g., limited memory and no syscall capabilities). For example, to implement the mutation engine without OCalls, we use sgx-rand for randomness entropy. Ultimately, the fuzzer exports a call-back API similar to the fuzz-driver in libfuzzer.
Toolchain. P 2 FAAS service user should port their code with the provided call-back API; that is, compiling the program with our toolchain (Clang/LLVM 4.0) with a new sanitizer option (-fsanitize=sgxfuzz) for the LLVM pass. The compiled program automatically generates both coverage information and crash reports during the fuzzing. Our implementation uses 4KB edge coverage map similar to AFL. To optimize the runtime performance (i.e., minimizing the number of ECalls and OCalls), we maintain the seed corpus inside the enclave and only synchronize it with the file system when needed.
Oblivious crash. To implement oblivious crash, we added a fake-crash generator as a part of the LLVM pass. The Fake-crash generator randomly chooses a time between the pre-configured interval. If a real crash does not occur until the configured time period, the instrumented program triggers crash. The crash is caused by invalid memory access to random address (using the sgx-rand API). Upon crashes (real or fake ones), the instrumented program sends out the crash report. To further hide the crash information, we can encrypt the report.
Cloud provider. For P 2 FAAS cloud provider, we setup an SGX host (Intel i7-6700K) and a No-SGX host (Intel Xeon E5-2620) with two Intel SGX Cards. We pin the fuzzer to each of cores for distributed fuzzing. For corpus and coverage synchronization, we use network file system (NFS) interface.

Evaluation
In this section, we evaluate the achievement of privacy preservation, the usability and performance characteristics of P 2 FAAS. Experiment setup. We ported three fuzz-drivers: (i) typical toy example for libfuzzer/AFL (byte-to-byte string match), (ii) arithmetic expression evaluator (30 LoC), and (iii) C-ARES DNS API from Google fuzzer-test-suite (1,225 LoC). Our evaluation numbers are based on an average of ten iterations.

Privacy Preservation
While the fuzzing instance is protected by relying on SGX security guarantees, P 2 FAAS target program raises random fake crashes based on a configurable normalized crash frequency to obfuscate its runtime behavior (oblivious crash). Figure 2 shows the outcome of a normalized 3 crashes per minute. Specifically, the frequency of real crashes starts with a spike and decreases as time progresses. Such runtime behavior is normalized by injecting fake crashes with an inverted frequency distribution. The resulting observable crash behavior is represented by Real+Fake in Figure 2, where the crash frequency appears stable over time. By applying such techniques to normalize crash frequencies, real crashes are indistinguishable from fake ones, thus protecting the runtime behavior of the target program.

Usability
One of the major challenges affecting P 2 FAAS usability is porting the target program into SGX, as SGX does not natively support system calls. To evaluate P 2 FAAS with our libfuzzer-based implementation, 15 OCalls are added in the fuzzer to accommodate SGX environment. For end users, depending on the target program and fuzzer interface, number of required OCalls can significantly differ. In our evaluation, we selected target programs that do not invoke system calls to avoid adding OCalls.
For the toy and arithmetic parser examples, the entire programs operate based on memory and arithmetic operations. In the case of fuzzer-test-suite example, the parser with vulnerability (CVE-2016-5180 [1]) does not require to invoke any system call. However, depending on the fuzzer interface and program size, non-trivial porting effort could be involved. We note that these porting efforts can be relaxed with existing techniques [29]. 0k   200k   400k   600k   800k   1000k   0  5  10  15  20  25  30  35  40  45  50 Exec/sec # core (w/ Intel SGX Card) Figure 3: P 2 FAAS performance scaling with Intel SGX Card.

Performance Characteristics
Scaling with Intel SGX Card. To demonstrate the scalability of P 2 FAAS, we used two Intel SGX Cards to setup a 48-core distributed P 2 FAAS environment. Fuzzers running on each core share the corpus and coverage information via network file system (NFS). Using toy fuzz-driver, we were able to achieve near one million executions per second as shown in Figure 3. CPU overhead. To measure the CPU overhead of P 2 FAAS, we show a comparison result with three configurations: (i) running the fuzzer without actually using the SGX feature at all (no-sgx), (ii) running the fuzzer inside enclave with SGX simulation mode (sgx-sim), and (iii) running the fuzzer inside enclave with SGX hardware mode (sgx-hw). In particular, we measured the execution time of one million executions. Numbers in Table 1 are the average of ten iterations.
The evaluation results show that SGX environment imposes around 45% performance overhead. We suspect this is due to the less optimized cache/TLB implementation. Memory overhead. Memory usage is another potential cause of performance degradation of P 2 FAAS under SGX environment. We measure the resident set size (RSS) with and without P 2 FAAS using pmap to analyze the memory overhead.
Regardless of the target program, the evaluation results give a memory overhead of around 2MB. The memory overhead is mainly caused by the in-memory corpus data structure, coverage bitmap, added fuzzer runtime code, and so forth. Such a small memory overhead is ideal for SGX environment as the runtime memory consumption of the fuzzing instance is more likely not to exceed SGX EPC size limitation, thus avoiding the long-worried performance degradation caused by SGX demand paging mechanism.

Discussion and Future Work
Inferring information from fuzzing inputs. Using SGX allows P 2 FAAS to protect the target program and its fuzzing inputs against the cloud provider. To further prevent the service provider from accessing the program, P 2 FAAS puts the program and the fuzzer in separate enclaves. However, because the program still relies on the fuzzer to provide inputs, the service provider may be able to infer the information about the program from the inputs. At this point, P 2 FAAS do not protect programs from such threats. We leave it to future works. Programs with large working set. Our evaluation test cases used a reasonably small amount of memory, thus fitting an enclave. Currently, size of SGX Enclave Page Cache (EPC) is limited to 128MB. Instances with larger working set that exceeds the size limitation will incur the SGX demand paging mechanism, which is extremely expensive, slowing down the system on average by 5 times [28]. This is harmful to the service quality of P 2 FAAS. We leave the solution to foreseeable future SGX support for larger EPC size.

Conclusion
Motivated from the rapidly emerging FaaS services, we propose P 2 FAAS to provide privacy on top. Our design demonstrates that SGX is a promising underlying technology for P 2 FAAS without harming usability and performance. As a prototype, we implemented a P 2 FAAS infrastructure based on SGX-enabled host and none-SGX host with SGX Card extension. Our implementation and evaluation demonstrates that P 2 FAAS is scalable and deployable in practice.