Demonstration venue · read-only. Every page can be browsed; the buttons that would change it are switched off. Create an account to run TaxoReview on your own data. A simulation from public publication records: the people listed were not invited and did not agree to review.
? Tutorial for this page

George C. Necula

dblp:n/GeorgeCNecula · DBLP profile ↗
← Back
59ranked-venue papers
15as first author
0since 2021 · last 2018
—ORCID · none

Domains — the database's venue-derived domains; a paper can count in several

Software engineering, systems software and programming languages · 48 · 11 first-authorTheory of computation · 13 · 5 first-authorArtificial intelligence and machine learning · 3 · 1 first-authorSystems, architecture and hardware · 2Security and privacy · 2 · 1 first-authorComputer networks · 1

Expertise — from the expertise taxonomy: the topics of the expert's papers under the CCF categories. A weight counts papers with recency: 1 for a paper about the topic, 0.3 when the topic is its context, halved every five years.

Software engineering, system software, and programming languages
33 papers
Software testing · 36% Program analysis · 23% Program verification · 15%
Computer architecture, parallel and distributed computing, and storage systems
2 papers
Distributed systems · 77% Parallel and multicore computing · 20% Cloud and datacenter computing · 3%
Network and information security
9 papers
Systems and software security · 85% Web and mobile security · 14% Network security · 2%
Theoretical computer science
4 papers
Logic in computer science · 79% Automated reasoning and model checking · 21%

Topics — the 30 heaviest of 84, each with the papers that count most for it

TopicWeightPapersLastEvidence papers
Software testing
GUI testing
0.522018
DetReduce: minimizing Android GUI test suites for regression testing · ICSE 2018
Guided GUI testing of android apps with minimal restart and approximate learning · OOPSLA 2013
Software testing › GUI testing
Android GUI testing
0.312018
DetReduce: minimizing Android GUI test suites for regression testing · ICSE 2018
Software testing
regression testing
0.312018
DetReduce: minimizing Android GUI test suites for regression testing · ICSE 2018
Software testing › regression testing
test suite reduction
0.312018
DetReduce: minimizing Android GUI test suites for regression testing · ICSE 2018
Distributed systems
fault tolerance
0.212016
Minimizing Faulty Executions of Distributed Systems · NSDI 2016
Software testing
test generation
0.222014
EventBreak: analyzing the responsiveness of user interfaces through performance-guided test generation · OOPSLA 2014
CONCURRIT: a domain specific language for reproducing concurrency bugs · PLDI 2013
Software testing
test input generation
0.222015
Guided GUI testing of android apps with minimal restart and approximate learning · OOPSLA 2013
MultiSE: multi-path symbolic execution using value summaries · ESEC/SIGSOFT FSE 2015
Program analysis
static analysis
0.242008
Exceptional situations and program reliability · ACM Trans. Program. Lang. Syst. 2008
Precise interprocedural analysis using random interpretation · POPL 2005
Global value numbering using random interpretation · POPL 2004
Program analysis › symbolic execution
dynamic symbolic execution
0.212015
MultiSE: multi-path symbolic execution using value summaries · ESEC/SIGSOFT FSE 2015
Program analysis › symbolic execution
state merging
0.212015
MultiSE: multi-path symbolic execution using value summaries · ESEC/SIGSOFT FSE 2015
Program analysis
symbolic execution
0.212015
MultiSE: multi-path symbolic execution using value summaries · ESEC/SIGSOFT FSE 2015
Software testing › mobile application testing
android app testing
0.212013
Guided GUI testing of android apps with minimal restart and approximate learning · OOPSLA 2013
Concurrent programming
concurrency bugs
0.212013
CONCURRIT: a domain specific language for reproducing concurrency bugs · PLDI 2013
Concurrent programming › concurrency bugs
concurrency bug reproduction
0.212013
CONCURRIT: a domain specific language for reproducing concurrency bugs · PLDI 2013
Programming languages and type systems
domain-specific languages
0.212013
CONCURRIT: a domain specific language for reproducing concurrency bugs · PLDI 2013
Software testing
model-based testing
0.212013
Guided GUI testing of android apps with minimal restart and approximate learning · OOPSLA 2013
Program verification › dynamic verification
runtime verification
0.222011
NDSeq: runtime checking for nondeterministic sequential specifications of parallel correctness · PLDI 2011
CCured: type-safe retrofitting of legacy code · POPL 2002
Program verification
proof-carrying code
0.262003
A Sound Framework for Untrusted Verification-Condition Generators · LICS 2003
A certifying compiler for Java · PLDI 2000
A Proof-Carrying Code Architecture for Java · CAV 2000
Program analysis › data flow analysis
dynamic data flow analysis
0.112012
NDetermin: inferring nondeterministic sequential specifications for parallelism correctness · PPoPP 2012
Program analysis
specification mining
0.112012
NDetermin: inferring nondeterministic sequential specifications for parallelism correctness · PPoPP 2012
Systems and software security
memory safety
0.142005
CCured: type-safe retrofitting of legacy software · ACM Trans. Program. Lang. Syst. 2005
CCured in the real world · PLDI 2003
CCured: type-safe retrofitting of legacy code · POPL 2002
Program analysis
data flow analysis
0.122008
Exceptional situations and program reliability · ACM Trans. Program. Lang. Syst. 2008
Finding and preventing run-time error handling mistakes · OOPSLA 2004
Operating systems
resource management
0.122008
Exceptional situations and program reliability · ACM Trans. Program. Lang. Syst. 2008
Finding and preventing run-time error handling mistakes · OOPSLA 2004
Concurrent programming
atomicity
0.112011
Specifying and checking semantic atomicity for multithreaded programs · ASPLOS 2011
Program verification
parallel program correctness
0.112011
NDSeq: runtime checking for nondeterministic sequential specifications of parallel correctness · PLDI 2011
Programming languages and type systems
type systems
0.122008
Exceptional situations and program reliability · ACM Trans. Program. Lang. Syst. 2008
A Proof-Carrying Code Architecture for Java · CAV 2000
Operating systems › extensible operating systems › kernel extensibility › kernel extensions
safe kernel extensions
0.132006
SafeDrive: Safe and Recoverable Extensions Using Language-Based Techniques · OSDI 2006
XFI: Software Guards for System Address Spaces · OSDI 2006
Safe Kernel Extensions Without Run-Time Checking · OSDI 1996
Software testing
software reliability
0.122008
Exceptional situations and program reliability · ACM Trans. Program. Lang. Syst. 2008
Finding and preventing run-time error handling mistakes · OOPSLA 2004
Program analysis › control flow analysis
exception flow analysis
0.112008
Exceptional situations and program reliability · ACM Trans. Program. Lang. Syst. 2008
Programming languages and type systems
type inference
0.122003
CCured in the real world · PLDI 2003
CCured: type-safe retrofitting of legacy code · POPL 2002

Methods — techniques the papers use, named apart from their topics

systematic event pair search · 0.4performance-guided testing · 0.4value summaries · 0.2constraint solving · 0.2randomized algorithms · 0.2thread schedule exploration · 0.2source instrumentation · 0.2machine learning · 0.2approximate learning · 0.2dynamic data flow analysis · 0.1run-time type information · 0.1instrumentation · 0.1type inference · 0.1uninterpreted function symbols · 0.1randomized algorithm · 0.1physical subtyping · 0.1arithmetic reasoning · 0.1untrusted verification-condition generator · 0.0
YearPublicationVenuePosition
2018 DetReduce: minimizing Android GUI test suites for regression testing
abstract
In recent years, several automated GUI testing techniques for Android apps have been proposed. These tools have been shown to be effective in achieving good test coverage and in finding bugs without human intervention. Being automated, these tools typically run for a long time (say, for several hours), either until they saturate test coverage or until a testing time budget expires. Thus, these automated tools are not good at generating concise regression test suites that could be used for testing in incremental development of the apps and in regression testing.
Wontae Choi, Koushik Sen, George C. Necula
ICSE3
2016 Minimizing Faulty Executions of Distributed Systems
Colin Scott, Aurojit Panda, Vjekoslav Brajkovic, George C. Necula, Arvind Krishnamurthy, Scott Shenker
NSDI4
2015 SJS: A Type System for JavaScript with Fixed Object Layout
Wontae Choi, Satish Chandra 0001, George C. Necula, Koushik Sen
SAS3
2015 MultiSE: multi-path symbolic execution using value summaries
abstract
Dynamic symbolic execution (DSE) has been proposed to effectively generate test inputs for real-world programs. Unfortunately, DSE techniques do not scale well for large realistic programs, because often the number of feasible execution paths of a program increases exponentially with the increase in the length of an execution path. In this paper, we propose MultiSE, a new technique for merging states incrementally during symbolic execution, without using auxiliary variables. The key idea of MultiSE is based on an alternative representation of the state, where we map each variable, including the program counter, to a set of guarded symbolic expressions called a value summary. MultiSE has several advantages over conventional DSE and conventional state merging techniques: value summaries enable sharing of symbolic expressions and path constraints along multiple paths and thus avoid redundant execution. MultiSE does not introduce auxiliary symbolic variables, which enables it to 1) make progress even when merging values not supported by the constraint solver, 2) avoid expensive constraint solver calls when resolving function calls and jumps, and 3) carry out most operations concretely. Moreover, MultiSE updates value summaries incrementally at every assignment instruction, which makes it unnecessary to identify the join points and to keep track of variables to merge at join points. We have implemented MultiSE for JavaScript programs in a publicly available open-source tool. Our evaluation of MultiSE on several programs shows that 1) value summaries are an eective technique to take advantage of the sharing of value along multiple execution path, that 2) MultiSE can run significantly faster than traditional dynamic symbolic execution and, 3) MultiSE saves a substantial number of state merges compared to conventional state-merging techniques.
Koushik Sen, George C. Necula, Wontae Choi
ESEC/SIGSOFT FSE2
2014 EventBreak: analyzing the responsiveness of user interfaces through performance-guided test generation
abstract
Event-driven user interface applications typically have a single thread of execution that processes event handlers in response to input events triggered by the user, the network, or other applications. Programmers must ensure that event handlers terminate after a short amount of time because otherwise, the application may become unresponsive. This paper presents EventBreak, a performance-guided test generation technique to identify and analyze event handlers whose execution time may gradually increase while using the application. The key idea is to systematically search for pairs of events where triggering one event increases the execution time of the other event. For example, this situation may happen because one event accumulates data that is processed by the other event. We implement the approach for JavaScript-based web applications and apply it to three real-world applications. EventBreak discovers events with an execution time that gradually increases in an unbounded way, which makes the application unresponsive, and events that, if triggered repeatedly, reveal a severe scalability problem, which makes the application unusable. The approach reveals two known bugs and four previously unknown responsiveness problems. Furthermore, we show that EventBreak helps in testing that event handlers avoid such problems by bounding a handler's execution time.
Michael Pradel, Parker Schuh, George C. Necula, Koushik Sen
OOPSLA3
2013 Towards hinted collection: annotations for decreasing garbage collector pause times
abstract
Garbage collection is widely used and has largely been a boon for programmer productivity. However, traditional garbage collection is approaching both practical and theoretical performance limits. In practice, the maximum heap size and heap structure of large applications are influenced as much by garbage collector behavior as by resource availability.
Philip Reames, George C. Necula
ISMM2
2013 Guided GUI testing of android apps with minimal restart and approximate learning
abstract
Smartphones and tablets with rich graphical user interfaces (GUI) are becoming increasingly popular. Hundreds of thousands of specialized applications, called apps, are available for such mobile platforms. Manual testing is the most popular technique for testing graphical user interfaces of such apps. Manual testing is often tedious and error-prone. In this paper, we propose an automated technique, called Swift-Hand, for generating sequences of test inputs for Android apps. The technique uses machine learning to learn a model of the app during testing, uses the learned model to generate user inputs that visit unexplored states of the app, and uses the execution of the app on the generated inputs to refine the model. A key feature of the testing algorithm is that it avoids restarting the app, which is a significantly more expensive operation than executing the app on a sequence of inputs. An important insight behind our testing algorithm is that we do not need to learn a precise model of an app, which is often computationally intensive, if our goal is to simply guide test execution into unexplored parts of the state space. We have implemented our testing algorithm in a publicly available tool for Android apps written in Java. Our experimental results show that we can achieve significantly better coverage than traditional random testing and L*-based testing in a given time budget. Our algorithm also reaches peak coverage faster than both random and L*-based testing.
Wontae Choi, George C. Necula, Koushik Sen
OOPSLA2
2013 CONCURRIT: a domain specific language for reproducing concurrency bugs
abstract
We present CONCURRIT, a domain-specific language (DSL) for reproducing concurrency bugs. Given some partial information about the nature of a bug in an application, a programmer can write a CONCURRIT script to formally and concisely specify a set of thread schedules to explore in order to find a schedule exhibiting the bug. Further, the programmer can specify how these thread schedules should be searched to find a schedule that reproduces the bug. We implemented CONCURRIT as an embedded DSL in C++, which uses manual or automatic source instrumentation to partially control the scheduling of the software under test. Using CONCURRIT, we were able to write concise tests to reproduce concurrency bugs in a variety of benchmarks, including the Mozilla's SpiderMonkey JavaScript engine, Memcached, Apache's HTTP server, and MySQL.
Tayfun Elmas, Jacob Burnim, George C. Necula, Koushik Sen
PLDI3
2012 NDetermin: inferring nondeterministic sequential specifications for parallelism correctness
abstract
Nondeterministic Sequential (NDSeq) specifications have been proposed as a means for separating the testing, debugging, and verifying of a program's parallelism correctness and its sequential functional correctness. In this work, we present a technique that, given a few representative executions of a parallel program, combines dynamic data flow analysis and Minimum-Cost Boolean Satisfiability (MinCostSAT) solving for automatically inferring a likely NDSeq specification for the parallel program. For a number of Java benchmarks, our tool NDetermin infers equivalent or stronger NDSeq specifications than those previously written manually.
Jacob Burnim, Tayfun Elmas, George C. Necula, Koushik Sen
PPoPP3
2011 Specifying and checking semantic atomicity for multithreaded programs
abstract
In practice, it is quite difficult to write correct multithreaded programs due to the potential for unintended and nondeterministic interference between parallel threads. A fundamental correctness property for such programs is atomicity---a block of code in a program is atomic if, for any parallel execution of the program, there is an execution with the same overall program behavior in which the block is executed serially.We propose semantic atomicity, a generalization of atomicity with respect to a programmer-defined notion of equivalent behavior. We propose an assertion framework in which a programmer can use bridge predicates to specify noninterference properties at the level of abstraction of their application. Further, we propose a novel algorithm for systematically testing atomicity specifications on parallel executions with a bounded number of interruptions---i.e. atomic blocks whose execution is interleaved with that of other threads. We further propose a set of sound heuristics and optional user annotations that increase the efficiency of checking atomicity specifications in the common case where the specifications hold.We have implemented our assertion framework for specifying and checking semantic atomicity for parallel Java programs, and we have written semantic atomicity specifications for a number of benchmarks. We found that using bridge predicates allowed us to specify the natural and intended atomic behavior of a wider range of programs than did previous approaches. Further, in checking our specifications, we found several previously unknown bugs, including in the widely-used java.util.concurrent library.
Jacob Burnim, George C. Necula, Koushik Sen
ASPLOS2
2011 NDSeq: runtime checking for nondeterministic sequential specifications of parallel correctness
abstract
We propose to specify the correctness of a program's parallelism using a sequential version of the program with controlled nondeterminism. Such a nondeterministic sequential specification allows (1) the correctness of parallel interference to be verified independently of the program's functional correctness, and (2) the functional correctness of a program to be understood and verified on a sequential version of the program, one with controlled nondeterminism but no interleaving of parallel threads.
Jacob Burnim, Tayfun Elmas, George C. Necula, Koushik Sen
PLDI3
2008 Exceptional situations and program reliability
abstract
It is difficult to write programs that behave correctly in the presence of run-time errors. Proper behavior in the face of exceptional situations is important to the reliability of long-running programs. Existing programming language features often provide poor support for executing clean-up code and for restoring invariants. We present a data-flow analysis for finding a certain class of exception-handling defects: those related to a failure to release resources or to clean up properly along all paths. Many real-world programs violate such resource usage rules because of incorrect exception handling. Our flow-sensitive analysis keeps track of outstanding obligations along program paths and does a precise modeling of control flow in the presence of exceptions. Using it, we have found over 1,300 exception handling defects in over 5 million lines of Java code. Based on those defects we propose a programming language feature, the compensation stack, that keeps track of obligations at run time and ensures that they are discharged. We present a type system for compensation stacks that tracks collections of obligations. Finally, we present case studies to demonstrate that this feature is natural, efficient, and can improve reliability.
Westley Weimer, George C. Necula
ACM Trans. Program. Lang. Syst.2
2007 Dependent Types for Low-Level Programming
Jeremy Condit, Matthew Harren, Zachary R. Anderson, David Gay, George C. Necula
ESOP5
2007 Beyond Bug-Finding: Sound Program Analysis for Linux
Zachary R. Anderson, Eric A. Brewer, Jeremy Condit, Robert Ennals, David Gay, Matthew Harren, George C. Necula
HotOS7
2007 Shape Analysis with Structural Invariant Checkers
Bor-Yuh Evan Chang, Xavier Rival, George C. Necula
SAS3
2007 A polynomial-time algorithm for global value numbering
Sumit Gulwani, George C. Necula
Sci. Comput. Program.2
2007 Enforcing resource bounds via static verification of dynamic checks
abstract
We show how to limit a program's resource usage in an efficient way, using a novel combination of dynamic checks and static analysis. Usually, dynamic checking is inefficient due to the overhead of checks, while static analysis is difficult and rejects many safe programs. We propose a hybrid approach that solves these problems. We split each resource-consuming operation into two parts. The first is a dynamic check, called reserve. The second is the actual operation, called consume, which does not perform any dynamic checks. The programmer is then free to hoist and combine reserve operations. Combining reserve operations reduces their overhead, while hoisting reserve operations ensures that the program does not run out of resources at an inconvenient time. A static verifier ensures that the program reserves resources before it consumes them. This verification is both easier and more flexible than an a priori static verification of resource usage. We present a sound and efficient static verifier based on Hoare logic and linear inequalities. As an example, we present a version of tar written in Java.
Ajay Chander, David Espinosa, Nayeem Islam, Peter Lee 0001, George C. Necula
ACM Trans. Program. Lang. Syst.5
2006 Using Dependent Types to Port Type Systems to Low-Level Languages
George C. Necula
CC1
2006 XFI: Software Guards for System Address Spaces
Úlfar Erlingsson, Martín Abadi, Michael Vrable, Mihai Budiu, George C. Necula
OSDI5
2006 SafeDrive: Safe and Recoverable Extensions Using Language-Based Techniques
Jeremy Condit, Zachary R. Anderson, Ilya Bagrak, Robert Ennals, Matthew Harren, George C. Necula, Eric A. Brewer
OSDI7
2006 Analysis of Low-Level Code Using Cooperating Decompilers
Bor-Yuh Evan Chang, Matthew Harren, George C. Necula
SAS3
2006 A Framework for Certified Program Analysis and Its Applications to Mobile-Code Safety
Bor-Yuh Evan Chang, Adam Chlipala, George C. Necula
VMCAI3
2005 JVer: A Java Verifier
Ajay Chander, David Espinosa, Nayeem Islam, Peter Lee 0001, George C. Necula
CAV5
2005 Data Structure Specifications via Local Equality Axioms
Scott McPeak, George C. Necula
CAV2
2005 Randomized Algorithms for Program Analysis and Verification
George C. Necula, Sumit Gulwani
CAV1
2005 Data Slicing: Separating the Heap into Independent Regions
Jeremy Condit, George C. Necula
CC2
2005 Enforcing Resource Bounds via Static Verification of Dynamic Checks
Ajay Chander, David Espinosa, Nayeem Islam, Peter Lee 0001, George C. Necula
ESOP5
2005 Precise interprocedural analysis using random interpretation
abstract
We describe a unified framework for random interpretation that generalizes previous randomized intraprocedural analyses, and also extends naturally to efficient interprocedural analyses. There is no such natural extension known for deterministic algorithms. We present a general technique for extending any intraprocedural random interpreter to perform a context-sensitive interprocedural analysis with only polynomial increase in running time. This technique involves computing random summaries of procedures, which are complete and probabilistically sound.As an instantiation of this general technique, we obtain the first polynomial-time randomized algorithm that discovers all linear relationships interprocedurally in a linear program. We also obtain the first polynomial-time randomized algorithm for precise interprocedural value numbering over a program with unary uninterpreted functions.We present experimental evidence that quantifies the precision and relative speed of the analysis for discovering linear relationships along two dimensions: intraprocedural vs. interprocedural, and deterministic vs. randomized. We also present results that show the variation of the error probability in the randomized analysis with changes in algorithm parameters. These results suggest that the error probability is much lower than the existing conservative theoretical bounds.
Sumit Gulwani, George C. Necula
POPL2
2005 Using Dependent Types to Certify the Safety of Assembly Code
Matthew Harren, George C. Necula
SAS2
2005 Mining Temporal Specifications for Error Detection
Westley Weimer, George C. Necula
TACAS2
2005 A randomized satisfiability procedure for arithmetic and uninterpreted function symbols
Sumit Gulwani, George C. Necula
Inf. Comput.2
2005 CCured: type-safe retrofitting of legacy software
abstract
This article describes CCured, a program transformation system that adds type safety guarantees to existing C programs. CCured attempts to verify statically that memory errors cannot occur, and it inserts run-time checks where static verification is insufficient.CCured extends C's type system by separating pointer types according to their usage, and it uses a surprisingly simple type inference algorithm that is able to infer the appropriate pointer kinds for existing C programs. CCured uses physical subtyping to recognize and verify a large number of type casts at compile time. Additional type casts are verified using run-time type information. CCured uses two instrumentation schemes, one that is optimized for performance and one in which metadata is stored in a separate data structure whose shape mirrors that of the original user data. This latter scheme allows instrumented programs to invoke external functions directly on the program's data without the use of a wrapper function.We have used CCured on real-world security-critical network daemons to produce instrumented versions without memory-safety vulnerabilities, and we have found several bugs in these programs. The instrumented code is efficient enough to be used in day-to-day operations.
George C. Necula, Jeremy Condit, Matthew Harren, Scott McPeak, Westley Weimer
ACM Trans. Program. Lang. Syst.1
2004 Elkhound: A Fast, Practical GLR Parser Generator
Scott McPeak, George C. Necula
CC2
2004 By Reason and Authority: A System for Authorization of Proof-Carrying Code
Nathan Whitehead, Martín Abadi, George C. Necula
CSFW3
2004 Join Algorithms for the Theory of Uninterpreted Functions
Sumit Gulwani, Ashish Tiwari 0001, George C. Necula
FSTTCS3
2004 Finding and preventing run-time error handling mistakes
abstract
It is difficult to write programs that behave correctly in the presence of run-time errors. Existing programming language features often provide poor support for executing clean-up code and for restoring invariants in such exceptional situations. We present a dataflow analysis for finding a certain class of error-handling mistakes: those that arise from a failure to release resources or to clean up properly along all paths. Many real-world programs violate such resource safety policies because of incorrect error handling. Our flow-sensitive analysis keeps track of outstanding obligations along program paths and does a precise modeling of control flow in the presence of exceptions. Using it, we have found over 800 error handling mistakes almost 4 million lines of Java code. The analysis is unsound and produces false positives, but a few simple filtering rules suffice to remove them in practice. The remaining mistakes were manually verified. These mistakes cause sockets, files and database handles to be leaked along some paths. We present a characterization of the most common causes of those errors and discuss the limitations of exception handling, finalizers and destructors in addressing them. Based on those errors, we propose a programming language feature that keeps track of obligations at run time and ensures that they are discharged. Finally, we present case studies to demonstrate that this feature is natural, efficient, and can improve reliability; for example, retrofitting a 34kLOC program with it resulted in a 0.5% code size decrease, a surprising 17% speed increase (from correctly deallocating resources in the presence of exceptions), and more consistent behavior.
Westley Weimer, George C. Necula
OOPSLA2
2004 Global value numbering using random interpretation
abstract
We present a polynomial time randomized algorithm for global value numbering. Our algorithm is complete when conditionals are treated as non-deterministic and all operators are treated as uninterpreted functions. We are not aware of any complete polynomial-time deterministic algorithm for the same problem. The algorithm does not require symbolic manipulations and hence is simpler to implement than the deterministic symbolic algorithms. The price for these benefits is that there is a probability that the algorithm can report a false equality. We prove that this probability can be made arbitrarily small by controlling various parameters of the algorithm.Our algorithm is based on the idea of random interpretation, which relies on executing a program on a number of random inputs and discovering relationships from the computed values. The computations are done by giving random linear interpretations to the operators in the program. Both branches of a conditional are executed. At join points, the program states are combined using a random affine combination. We discuss ways in which this algorithm can be made more precise by using more accurate interpretations for the linear arithmetic operators and other language constructs.
Sumit Gulwani, George C. Necula
POPL2
2004 A Polynomial-Time Algorithm for Global Value Numbering
Sumit Gulwani, George C. Necula
SAS2
2004 Path-Sensitive Analysis for Linear Arithmetic and Uninterpreted Functions
Sumit Gulwani, George C. Necula
SAS2
2003 A Randomized Satisfability Procedure for Arithmetic and Uninterpreted Function Symbols
Sumit Gulwani, George C. Necula
CADE2
2003 A Sound Framework for Untrusted Verification-Condition Generators
abstract
We propose a framework called configurable proof-carrying code, which allows the untrusted producer of mobile code to provide the bulk of the code verifier used by a code receiver to check the safety of the received code. The resulting system is both more flexible and also more trustworthy than a standard proof-carrying code system, because only a small part of the verifier needs to be trusted, while the remaining part can be configured freely to suit the safety policy on one hand, and the structure of the mobile code on the other hand. In this paper we describe formally the protocol that the untrusted verifier must follow in the interaction with the trusted infrastructure. We present a proof of the soundness of the system, and we give preliminary evidence that the architecture is expressive enough to delegate to the untrusted verifier even the handling of loop invariants, indirect jumps and calling conventions.
George C. Necula, Robert R. Schneck
LICS1
2003 CCured in the real world
abstract
CCured is a program transformation system that adds memory safety guarantees to C programs by verifying statically that memory errors cannot occur and by inserting run-time checks where static verification is insufficient.This paper addresses major usability issues in a previous version of CCured, in which many type casts required the use of pointers whose representation was expensive and incompatible with precompiled libraries. We have extended the CCured type inference algorithm to recognize and verify statically a large number of type casts; this goal is achieved by using physical subtyping and pointers with run-time type information to allow parametric and subtype polymorphism. In addition, we present a new instrumentation scheme that splits CCured's metadata into a separate data structure whose shape mirrors that of the original user data. This scheme allows instrumented programs to invoke external functions directly on the program's data without the use of a wrapper function.With these extensions we were able to use CCured on real-world security-critical network daemons and to produce instrumented versions without memory-safety vulnerabilities.
Jeremy Condit, Matthew Harren, Scott McPeak, George C. Necula, Westley Weimer
PLDI4
2003 Discovering affine equalities using random interpretation
abstract
We present a new polynomial-time randomized algorithm for discovering affine equalities involving variables in a program. The key idea of the algorithm is to execute a code fragment on a few random inputs, but in such a way that all paths are covered on each run. This makes it possible to rule out invalid relationships even with very few runs.The algorithm is based on two main techniques. First, both branches of a conditional are executed on each run and at joint points we perform an affine combination of the joining states. Secondly, in the branches of an equality conditional we adjust the data values on the fly to reflect the truth value of the guarding boolean expression. This increases the number of affine equalities that the analysis discovers.The algorithm is simpler to implement than alternative deterministic versions, has better computational complexity, and has an extremely small probability of error for even a small number of runs. This algorithm is an example of how randomization can provide a trade-off between the cost and complexity of program analysis, and a small probability of unsoundness.
Sumit Gulwani, George C. Necula
POPL2
2003 Capriccio: scalable threads for internet services
abstract
This paper presents Capriccio, a scalable thread package for use with high-concurrency servers. While recent work has advocated event-based systems, we believe that thread-based systems can provide a simpler programming model that achieves equivalent or superior performance.By implementing Capriccio as a user-level thread package, we have decoupled the thread package implementation from the underlying operating system. As a result, we can take advantage of cooperative threading, new asynchronous I/O mechanisms, and compiler support. Using this approach, we are able to provide three key features: (1) scalability to 100,000 threads, (2) efficient stack management, and (3) resource-aware scheduling.We introduce linked stack management, which minimizes the amount of wasted stack space by providing safe, small, and non-contiguous stacks that can grow or shrink at run time. A compiler analysis makes our stack implementation efficient and sound. We also present resource-aware scheduling, which allows thread scheduling and admission control to adapt to the system's current resource usage. This technique uses a blocking graph that is automatically derived from the application to describe the flow of control between blocking points in a cooperative thread package. We have applied our techniques to the Apache 2.0.44 web server, demonstrating that we can achieve high performance and scalability despite using a simple threaded programming model.
J. Robert von Behren, Jeremy Condit, George C. Necula, Eric A. Brewer
SOSP4
2002 A Gradual Approach to a More Trustworthy, Yet Scalable, Proof-Carrying Code
Robert R. Schneck, George C. Necula
CADE2
2002 Temporal-Safety Proofs for Systems Code
Thomas A. Henzinger, Ranjit Jhala, Rupak Majumdar, George C. Necula, Grégoire Sutre, Westley Weimer
CAV4
2002 CIL: Intermediate Language and Tools for Analysis and Transformation of C Programs
George C. Necula, Scott McPeak, Shree Prakash Rahul, Westley Weimer
CC1
2002 CCured: type-safe retrofitting of legacy code
abstract
In this paper we propose a scheme that combines type inference and run-time checking to make existing C programs type safe. We describe the CCured type system, which extends that of C by separating pointer types according to their usage. This type system allows both pointers whose usage can be verified statically to be type safe, and pointers whose safety must be checked at run time. We prove a type soundness result and then we present a surprisingly simple type inference algorithm that is able to infer the appropriate pointer kinds for existing C programs.Our experience with the CCured system shows that the inference is very effective for many C programs, as it is able to infer that most or all of the pointers are statically verifiable to be type safe. The remaining pointers are instrumented with efficient run-time checks to ensure that they are used safely. The resulting performance loss due to run-time checks is 0-150%, which is several times better than comparable approaches that use only dynamic checking. Using CCured we have discovered programming bugs in established C programs such as several SPECINT95 benchmarks.
George C. Necula, Scott McPeak, Westley Weimer
POPL1
2001 Oracle-based checking of untrusted software
abstract
We present a variant of Proof-Carrying Code (PCC) in which the trusted inference rules are represented as a higherorder logic program, the proof checker is replaced by a nondeterministic higher-order logic interpreter and the proof by an oracle implemented as a stream of bits that resolve the nondeterministic interpretation choices. In this setting, Proof-Carrying Code allows the receiver of the code the luxury of using nondeterminism in constructing a simple yet powerful checking procedure. This oracle-based variant of PCC is able to adapt quite naturally to situations when the property being checked is simple or there is a fairly directed search procedure for it. As an example, we demonstrate that if PCC is used to verify type safety of assembly language programs compiled from Java source programs, the oracles that are needed are on the average just 12% of the size of the code, which represents an improvement of a factor of 30 over previous syntactic representations of PCC proofs. ...
George C. Necula, Shree Prakash Rahul
POPL1
2000 Proof Generation in the Touchstone Theorem Prover
George C. Necula, Peter Lee 0001
CADE1
2000 A Proof-Carrying Code Architecture for Java
Christopher Colby, Peter Lee 0001, George C. Necula
CAV3
2000 A certifying compiler for Java
abstract
This paper presents the initial results of a project to determine if the techniques of proof-carrying code and certifying compilers can be applied to programming languages of realistic size and complexity. The experiment shows that: (1) it is possible to implement a certifying native-code compiler for a large subset of the Java programming language; (2) the compiler is freely able to apply many standard local and global optimizations; and (3) the PCC binaries it produces are of reasonable size and can be rapidly checked for type safety by a small proof-checker. This paper also presents further evidence that PCC provides several advantages for compiler development. In particular, generating proofs of the target code helps to identify compiler bugs, many of which would have been dicult to discover by testing.
Christopher Colby, Peter Lee 0001, George C. Necula, Fred Blau, Mark Plesko, Kenneth Cline
PLDI3
2000 Translation validation for an optimizing compiler
abstract
We describe a translation validation infrastructure for the GNU C compiler. During the compilation the infrastructure compares the intermediate form of the program before and after each compiler pass and verifies the preservation of semantics. We discuss a general framework that the optimizer can use to communicate to the validator what transformations were performed. Our implementation however does not rely on help from the optimizer and it is quite successful by using instead a few heuristics to detect the transformations that take place.
George C. Necula
PLDI1
2000 Proof-carrying code: design, implementation and applications (abstract)
George C. Necula
PPDP1
1998 Efficient Representation and Validation of Proofs
abstract
This paper presents a logical framework derived from the Edinburgh Logical Framework (LF) that can be used to obtain compact representations of proofs and efficient proof checkers. These are essential ingredients of any application that manipulates proofs as first-class objects, such as a Proof-Carrying Code system, in which proofs are used to support easy validation of properties of safety-critical or untrusted code. Our framework, which we call LF/sub i/, inherits from LF the capability to encode various logics in a natural way. In addition, the LF/sub i/ framework allows proof representations without the high degree of redundancy that is characteristic of LF representations. The missing parts of LF/sub i/ proof representations can be reconstructed during proof checking by an efficient reconstruction algorithm. We also describe an algorithm that can be used to strip the unnecessary parts of an LF representation of a proof. The experimental data that we gathered in the context of a Proof-Carrying Code system shows that the savings obtained from using LF/sub i/ instead of LF can make the difference between practically useless proofs of several megabytes and manageable proofs of tens of kilobytes.
George C. Necula, Peter Lee 0001
LICS1
1998 The Design and Implementation of a Certifying Compiler
abstract
This paper presents the design and implementation of a compiler that translates programs written in a type-safe subset of the C programming language into highly optimized DEC Alpha assembly language programs, and a certifier that automatically checks the type safety and memory safety of any assembly language program produced by the compiler. The result of the certifier is either a formal proof of type safety or a counterexample pointing to a potential violation of the type system by the target program. The ensemble of the compiler and the certifier is called a certifying compiler.Several advantages of certifying compilation over previous approaches can be claimed. The notion of a certifying compiler is significantly easier to employ than a formal compiler verification, in part because it is generally easier to verify the correctness of the result of a computation than to prove the correctness of the computation itself. Also, the approach can be applied even to highly optimizing compilers, as demonstrated by the fact that our compiler generates target code, for a range of realistic C programs, which is competitive with both the cc and gcc compilers with all optimizations enabled. The certifier also drastically improves the effectiveness of compiler testing because, for each test case, it statically signals compilation errors that might otherwise require many executions to detect. Finally, this approach is a practical way to produce the safety proofs for a Proof-Carrying Code system, and thus may be useful in a system for safe mobile code.
George C. Necula, Peter Lee 0001
PLDI1
1997 Proof-Carrying Code
abstract
This paper describes proof-carrying code (PCC), a mechanism by which a host system can determine with certainty that it is safe to execute a program supplied (possibly in binary form) by an untrusted source. For this to be possible, the untrusted code producer must supply with the code a safety proof that attests to the code's adherence to a previously defined safety policy. The host can then easily and quickly validate the proof without using cryptography and without consulting any external agents.In order to gain preliminary experience with PCC, we have performed several case studies. We show in this paper how proof-carrying code might be used to develop safe assembly-language extensions of ML programs. In the context of this case study, we present and prove the adequacy of concrete representations for the safety policy, the safety proofs, and the proof validation. Finally, we briefly discuss how we use proof-carrying code to develop network packet filters that are faster than similar filters developed using other techniques and are formally guaranteed to be safe with respect to a given operating system safety policy.
George C. Necula
POPL1
1997 Research on Proof-Carrying Code for Untrusted-Code Security
abstract
A powerful method of interaction between two software systems is through mobile code. By allowing code to be installed dynamically and then executed, a host system can provide a flexible means of access to its internal resources and services. There are many problems to be solved before such uses of untrusted code can become practical. We focus on the problem of how to establish guarantees about the intrinsic behavior of untrusted programs. Of particular interest are the following: (1) How can the host system ensure that the untrusted code will not damage it, for example, by corrupting internal data structures? (2) How can the host ensure that the untrusted code will not use too many resources (such as CPU, memory, and so forth) or use them for too long a time period? (3) How can the host make these assurances without undue effort and deleterious effect on overall system performance? Our position is that the theory of programming languages, including formal semantics, type theory, and applications of logic, are critical to solving the untrusted code security problem. To illustrate the possibilities of programming language theory, we briefly describe one rather extreme but promising example, which is proof carrying code (PCC). This is a technique by which the host establishes a set of safety rules that guarantee safe behavior of programs, and the code producer creates a formal safety proof that proves, for the untrusted code, adherence to the safety rules. Then, the host is able to use a simple and fast proof validator to check, with certainty, that the proof is valid and hence the foreign code is safe to execute.
George C. Necula, Peter Lee 0001
S&P1
1996 Safe Kernel Extensions Without Run-Time Checking
abstract
No abstract available.
George C. Necula, Peter Lee 0001
OSDI1