Skip to main content
main-content
Top

About this book

This book constitutes the refereed proceedings of the 12th European Symposium on Programming, ESOP 2003, held in Warsaw, Poland, in April 2003.

The 25 revised full papers presented together with two invited papers were carefully reviewed and selected from 99 submissions. Among the topics addressed are programming paradigms and their integration, program semantics, calculi of computation, security, advanced type systems, program analysis, program transformation, and practical algorithms based on theoretical developments.

Table of Contents

Frontmatter

Invited Talks

Computer Security from a Programming Language and Static Analysis Perspective

(Extended Abstract of Invited Lecture)
Abstract
Computer security [16,5] is usually defined as ensuring integrity, confidentiality, and availability requirements even in the presence of a determined, malicious opponent. Sensitive data must be modified and consulted by authorized users only (integrity, confidentiality); moreover, the system should resist “denial of service” attacks that attempt to render it unusable (availability). In more colorful language, computer security has been described as “programming Satan’s computer” [6]: the implementor must assume that every weakness that can be exploited will be.
Xavier Leroy

What Makes a Cryptographic Protocol Secure? The Evolution of Requirements Specification in Formal Cryptographic Protocol Analysis

Abstract
Much attention has been paid to the design of languages for the specification of cryptographic protocols. However, the ability to specify their desired behavior correctly is also important; indeed many perceived protocol flaws arise out of a misunderstanding of the protocol’s requirements. In this talk we give a brief survey of the history of requirements specification in formal analysis of cryptographic protocols. We outline the main approaches and describe some of the open issues.
Catherine Meadows

Contributed Papers

A Tail-Recursive Semantics for Stack Inspections

Abstract
Security folklore holds that a security mechanism based on stack inspection is incompatible with a global tail call optimization policy. An implementation of such a language may have to allocate memory for a source-code tail call, and a program that uses only tail calls (and no other memory-allocating construct) may nevertheless exhaust the available memory. In this paper, we prove this widely held belief wrong. We exhibit an abstract machine for a language with security stack inspection whose space consumption function is equivalent to that of the canonical tail call optimizing abstract machine. Our machine is surprisingly simple and suggests that tail-calls are as easy to implement in a security setting as they are in a conventional one.
John Clements, Matthias Felleisen

Flexible Models for Dynamic Linking

Abstract
Dynamic linking supports flexible code deployment: partially linked code links further code on the fly, as needed; and thus, end-users receive updates automatically. On the down side, each program run may link different versions of the same code, possibly causing subtle errors which mystify end-users.
Dynamic linking in Java and C# are similar: The same linking phases are involved, soundness is based on similar ideas, and executions which do not throw linking errors give the same result. They are, however, not identical: the linking phases are combined differently, and take place in a different order.
We develop a non-deterministic model, which includes the behaviour of Java and C#. The non-determinism allows us to describe the design space, to distill the similarities between the two languages, and to use one proof of soundness for both. We also prove that all execution strategies are equivalent in the sense that all terminating executions which do not involve a link error, give the same result.
Sophia Drossopoulou, Giovanni Lagorio, Susan Eisenbach

Correction of Functional Logic Programs

Abstract
We propose a new methodology for synthesizing correct functional logic programs. We aim to create an integrated development environment in which it is possible to debug a program and correct it automatically. We start from a declarative diagnoser that we have developed previously which allows us to identify wrong program rules w.r.t. an intended specification. Then a bug-correction, program synthesis methodology tries to correct the erroneous components of the wrong code. We propose a hybrid, top-down (unfolding-based) as well as bottom-up (induction-based), approach for the automatic correction of functional logic programs which is driven by a set of evidence examples which are automatically produced as an outcome by the diagnoser. The resulting program is proven to be correct and complete w.r.t. the considered example sets. Finally, we also provide a prototypical implementation which we use for an experimental evaluation of our system.
Maria Alpuente, Demis Ballis, Francisco J. Correa, Moreno Falaschi

Approximate Pruning in Tabled Logic Programming

Abstract
Pruning provides an important tool for control of nondeterminism in Prolog systems. Current Tabled Prolog systems improve Prolog’s evaluation strategy in several ways, but lack satisfactory support for pruning operations. In this paper we present an extension to the evaluation mechanism of Tabled Prolog to support pruning. This extension builds on the concept of demand to select tables to prune. In particular, we concentrate on systems based on SLG resolution. A once operator is described, which approximates demand-based pruning, providing for an efficient implementation in the XSB system.
Luís F. Castro, David S. Warren

Goal-Independent Suspension Analysis for Logic Programs with Dynamic Scheduling

Abstract
A goal-independent suspension analysis is presented that infers a class of goals for which a logic program with delays can be executed without suspension. The crucial point is that the analysis does not verify that an (abstract) goal does not lead to suspension but rather it infers abstract) goals which do not lead to suspension.
Samir Genaim, Andy King

Security Properties: Two Agents Are Sufficient

Abstract
We consider arbitrary cryptographic protocols and security properties. We show that it is always sufficient to consider a bounded number of agents b (actually b = 2 in most of the cases): if there is an attack involving n agents, then there is an attack involving at most b agents.
Hubert Comon-Lundh, Véronique Cortier

A Simple Language for Real-Time Cryptographic Protocol Analysis

Abstract
A real-time process algebra, enhanced with specific constructs for handling cryptographic primitives, is proposed to model cryptographic protocols in a simple way.We show that some security properties, such as authentication and secrecy, can be re-formulated in this timed setting. Moreover, we show that they can be seen as suitable instances of a general information flow-like scheme, called tGN DC, parametric w.r.t. the observational semantics of interest.We show that, when considering timed trace semantics, there exists a most powerful hostile environment (or enemy) that can try to compromise the protocol. Moreover, we hint some compositionality results.
Roberto Gorrieri, Enrico Locatelli, Fabio Martinelli

Rule Formats for Non Interference

Abstract
We present the SBSNNI rule format. We prove that any Process Algebra construct whose SOS-style semantics is defined by SOS transition rules respecting such a format, preserves the well known non interference properties Persistent BNDC, SBSNNI, and SBNDC.
Simone Tini

On the Secure Implementation of Security Protocols

Abstract
We consider the problem of implementing a security protocol in such a manner that secrecy of sensitive data is not jeopardized. Implementation is assumed to take place in the context of an API that provides standard cryptography and communication services. Given a dependency specification, stating how API methods can produce and consume secret information, we propose an information flow property based on the idea of invariance under perturbation, relating observable changes in output to corresponding changes in input. Besides the information flowcondition itself, the main contributions of the paper are results relating the admissibility property to a direct flow property in the special case of programs which branch on secrets only in cases permitted by the dependency rules. These results are used to derive an unwinding-like theorem, reducing a behavioral correctness check (strong bisimulation) to an invariant.
Pablo Giambiagi, Mads Dam

Handling Encryption in an Analysis for Secure Information Flow

Abstract
This paper presents a program analysis for secure information flow. The analysis works on a simple imperative programming language containing a cryptographic primitive—encryption—as a possible operation. The analysis captures the intuitive qualities of the (lack of) information flow from a plaintext to its corresponding ciphertext. The analysis is proved correct with respect to a complexity-theoretical definition of the security of information flow. In contrast to the previous results, the analysis does not put any restrictions on the structure of the program, especially on the ways of how the program uses the encryption keys.
Peeter Laud

Using Controller-Synthesis Techniques to Build Property-Enforcing Layers

Abstract
In complex systems, like robot plants, applications are built on top of a set of components, or devices. Each of them has particular individual constraints, and there are also logical constraints on their interactions, related to e.g., mechanical characteristics or access to shared resources. Managing these constraints may be separated from the application, and performed by an intermediate layer.
We show how to build such property-enforcing layers, in a mixed imperative/declarative style: 1) the constraints intrinsic to one component are modeled by an automaton; the product of these automata is a first approximation of the set of constraints that should be respected; 2) the constraints that involve several components are expressed as temporal logic properties of this product; 3) we use general controller synthesis techniques and tools in order to combine the set of communicating parallel automata with the global constraint.
Karine Altisen, Aurélie Clodic, Florence Maraninchi, Eric Rutten

Automatic Software Model Checking Using CLP

Abstract
This paper proposes the use of constraint logic programming (CLP) to perform model checking of traditional, imperative programs. We present a semantics-preserving translation from an imperative language with heap-allocated mutable data structures and recursive procedures into CLP. The CLP formulation (1) provides a clean way to reason about the behavior and correctness of the original program, and (2) enables the use of existing CLP implementations to perform bounded software model checking, using a combination of symbolic reasoning and explicit path exploration.
Cormac Flanagan

Verifying Temporal Heap Properties Specified via Evolution Logic

Abstract
This paper addresses the problem of establishing temporal properties of programs written in languages, such as Java, that make extensive use of the heap to allocate—and deallocate—new objects and threads. Establishing liveness properties is a particularly hard challenge. One of the crucial obstacles is that heap locations have no static names and the number of heap locations is unbounded. The paper presents a framework for the verification of Java-like programs. Unlike classical model checking, which uses propositional temporal logic, we use first-order temporal logic to specify temporal properties of heap evolutions; this logic allows domain changes to be expressed, which permits allocation and deallocation to be modelled naturally. The paper also presents an abstract-interpretation algorithm that automatically verifies temporal properties expressed using the logic.
Eran Yahav, Thomas Reps, Mooly Sagiv, Reinhard Wilhelm

Correctness of Data Representations Involving Heap Data Structures

Abstract
While the semantics of local variables in programming languages is by now well-understood, the semantics of pointer-addressed heap variables is still an outstanding issue. In particular, the commonly assumed relational reasoning principles for data representations have not been validated in a semantic model of heap variables. In this paper, we define a parametricity semantics for a Pascal-like language with pointers and heap variables which gives such reasoning principles. It is found that the correspondences between data representations are not simply relations between states, but more intricate correspondences that also need to keep track of visible locations whose pointers can be stored and leaked.
Uday S. Reddy, Hongseok Yang

Modeling Web Interactions

Abstract
Programmers confront a minefield when they design interactive Web programs. Web interactions take place via Web browsers. With browsers, consumers can whimsically navigate among the various stages of a dialog and can thus confuse the most sophisticated corporate Web sites. In turn,Web services can fault in frustrating and inexplicable ways. The quickening transition from Web scripts toWeb services lends these problems immediacy.
To address this programming problem, we develop a foundational model of Web interactions and use it to formally describe two classes of errors. The model suggests techniques for detecting both classes of errors. For one class we present an incrementally checked record type system, which effectively eliminates these errors. For the other class, we introduce a dynamic safety check, which catches the mistakes relative to programmers’ simple annotations.
Paul Graunke, Robert Bruce Findler, Shriram Krishnamurthi, Matthias Felleisen

Type Inference for a Distributed π-Calculus

Abstract
We study the type inference problem for a distributed π- calculus with explicit notions of locality and migration. Location types involve names that may be bound in terms. This requires some accurate new treatments. We define a notion of principal typing. We provide a formal description of sound and complete type inference algorithm.
Cédric Lhoussaine

Type-Safe Update Programming

Abstract
Many software maintenance problems are caused by using text editors to change programs. A more systematic and reliable way of performing program updates is to express changes with an update language. In particular, updates should preserve the syntax- and type-correctness of the transformed object programs.
We describe an update calculus that can be used to update lambdacalculus programs. We develop a type system for the update language that infers the possible type changes that can be caused by an update program. We demonstrate that type-safe update programs that fulfill certain structural constraints preserve the type-correctness of lambda terms.
Martin Erwig, Deling Ren

Type Error Slicing in Implicitly Typed Higher-Order Languages

Abstract
Previous methods have generally identified the location of a type error as a particular program point or the program subtree rooted at that point. We present a new approach that identifies the location of a type error as a set of program points (a slice) all of which are necessary for the type error. We describe algorithms for finding minimal type error slices for implicitly typed higher-order languages like Standard ML.
Christian Haack, J. B. Wells

Core Formal Molecular Biology

Abstract
A core modeling language for Molecular Biology is introduced, where two simple forms of interaction are considered, complexation and activation. This core language is equipped with two sensible bisimulation-based equivalences, and it is shown that interactions involving complex reactants are superfluous up to these notions. Strong compilations in π-calculus are given, following Regev’s principle of translating physical connection as private name sharing.
Vincent Danos, Cosimo Laneve

Requirements on the Execution of Kahn Process Networks

Abstract
Kahn process networks (KPNs) are a programming paradigm suitable for streaming-based multimedia and signal-processing applications. We discuss the execution of KPNs, and the criteria for correct scheduling of their realisations. In [12], Parks shows how process networks can be scheduled in bounded memory; the proposed method is used in many implementations of KPNs. However, it does not result in the correct behaviour for all KPNs. We investigate the requirements for a scheduler to guarantee both correct and bounded execution of KPNs and present an improved scheduling strategy that satisfies them.
Marc Geilen, Twan Basten

Tagging, Encoding, and Jones Optimality

Abstract
A partial evaluator is said to be Jones-optimal if the result of specializing a self-interpreter with respect to a source program is textually identical to the source program, modulo renaming. Jones optimality has already been obtained if the self-interpreter is untyped. If the selfinterpreter is typed, however, residual programs are cluttered with type tags. To obtain the original source program, these tags must be removed.
A number of sophisticated solutions have already been proposed. We observe, however, that with a simple representation shift, ordinary partial evaluation is already Jones-optimal, modulo an encoding. The representation shift amounts to reading the type tags as constructors for higherorder abstract syntax. We substantiate our observation by considering a typed self-interpreter whose input syntax is higher-order. Specializing this interpreter with respect to a source program yields a residual program that is textually identical to the source program, modulo renaming.
Olivier Danvy, Pablo E. Martínez López

The Rely-Guarantee Method in Isabelle/HOL

Abstract
We present the formalization of the rely-guarantee method in the theorem prover Isabelle/HOL. This method consists of a Hoarelike system of rules to verify concurrent imperative programs with shared variables in a compositional way. Syntax, semantics and proof rules are de.ned in higher-order logic. Soundness of the proof rules w.r.t. the semantics is proven mechanically. Also parameterized programs, where the number of parallel components is a parameter, are included in the programming language and thus can be verified directly in the system. We prove that the system is complete for parameterized programs. Finally, we show by an example how the formalization can be used for verifying concrete programs.
Leonor Prensa Nieto

Building Certified Libraries for PCC: Dynamic Storage Allocation

Abstract
Proof-Carrying Code (PCC) allows a code producer to provide to a host a program along with its formal safety proof. The proof attests a certain safety policy enforced by the code, and can be mechanically checked by the host. While this language-based approach to code certification is very general in principle, existing PCC systems have only focused on programs whose safety proofs can be automatically generated. As a result, many low-level system libraries (e.g., memory management) have not yet been handled. In this paper, we explore a complementary approach in which general properties and program correctness are semiautomatically certified. In particular, we introduce a low-level language CAP for building certified programs and present a certified library for dynamic storage allocation.
Dachuan Yu, Nadeem A. Hamid, Zhong Shao

Finite Differencing of Logical Formulas for Static Analysis

Abstract
This paper concerns mechanisms for maintaining the value of an instrumentation predicate (a.k.a. derived predicate or view), defined via a logical formula over core predicates, in response to changes in the values of the core predicates. It presents an algorithm for transforming the instrumentation predicate’s defining formula into a predicate-maintenance formula that captures what the instrumentation predicate’s new value should be.
This technique applies to program-analysis problems in which the semantics of statements is expressed using logical formulas that describe changes to corepredicate values, and provides a way to reflect those changes in the values of the instrumentation predicates.
Thomas Reps, Mooly Sagiv, Alexey Loginov

Register Allocation by Proof Transformation

Abstract
This paper presents a proof-theoretical framework that accounts for the entire process of register allocation - liveness analysis is proof reconstruction (similar to type inference), and register allocation is proof transformation from a proof system with unrestricted variable accesses to a proof system with restricted variable access. In our framework, the set of registers acts as a “working set” of the live variables at each instruction step, which changes during the execution of the code. This eliminates the ad-hoc notion of “spilling”. The necessary memoryregister moves are systematically incorporated in our proof transformation process. Its correctness is a direct corollary of our construction; the resulting proof is equivalent to the proof of the original code modulo treatment of structural rules. The framework yields a clean and powerful register allocation algorithm. The algorithm has been implemented, demonstrating the feasibility of the framework.
Atsushi Ohori

Backmatter

Additional information