613 research outputs found
Inference of Resource Management Specifications
A resource leak occurs when a program fails to free some finite resource
after it is no longer needed. Such leaks are a significant cause of real-world
crashes and performance problems. Recent work proposed an approach to prevent
resource leaks based on checking resource management specifications. A resource
management specification expresses how the program allocates resources, passes
them around, and releases them; it also tracks the ownership relationship
between objects and resources, and aliasing relationships between objects.
While this specify-and-verify approach has several advantages compared to prior
techniques, the need to manually write annotations presents a significant
barrier to its practical adoption.
This paper presents a novel technique to automatically infer a resource
management specification for a program, broadening the applicability of
specify-and-check verification for resource leaks. Inference in this domain is
challenging because resource management specifications differ significantly in
nature from the types that most inference techniques target. Further, for
practical effectiveness, we desire a technique that can infer the resource
management specification intended by the developer, even in cases when the code
does not fully adhere to that specification. We address these challenges
through a set of inference rules carefully designed to capture real-world
coding patterns, yielding an effective fixed-point-based inference algorithm.
We have implemented our inference algorithm in two different systems,
targeting programs written in Java and C#. In an experimental evaluation, our
technique inferred 85.5% of the annotations that programmers had written
manually for the benchmarks. Further, the verifier issued nearly the same rate
of false alarms with the manually-written and automatically-inferred
annotations
On Leveraging Tests to Infer Nullable Annotations
Issues related to the dereferencing of null pointers are a pervasive and widely studied problem, and numerous static analyses have been proposed for this purpose. These are typically based on dataflow analysis, and take advantage of annotations indicating whether a type is nullable or not. The presence of such annotations can significantly improve the accuracy of null checkers. However, most code found in the wild is not annotated, and tools must fall back on default assumptions, leading to both false positives and false negatives. Manually annotating code is a laborious task and requires deep knowledge of how a program interacts with clients and components.
We propose to infer nullable annotations from an analysis of existing test cases. For this purpose, we execute instrumented tests and capture nullable API interactions. Those recorded interactions are then refined (santitised and propagated) in order to improve their precision and recall. We evaluate our approach on seven projects from the spring ecosystems and two google projects which have been extensively manually annotated with thousands of @Nullable annotations. We find that our approach has a high precision, and can find around half of the existing @Nullable annotations. This suggests that the method proposed is useful to mechanise a significant part of the very labour-intensive annotation task
Putting the Semantics into Semantic Versioning
The long-standing aspiration for software reuse has made astonishing strides
in the past few years. Many modern software development ecosystems now come
with rich sets of publicly-available components contributed by the community.
Downstream developers can leverage these upstream components, boosting their
productivity.
However, components evolve at their own pace. This imposes obligations on and
yields benefits for downstream developers, especially since changes can be
breaking, requiring additional downstream work to adapt to. Upgrading too late
leaves downstream vulnerable to security issues and missing out on useful
improvements; upgrading too early results in excess work. Semantic versioning
has been proposed as an elegant mechanism to communicate levels of
compatibility, enabling downstream developers to automate dependency upgrades.
While it is questionable whether a version number can adequately characterize
version compatibility in general, we argue that developers would greatly
benefit from tools such as semantic version calculators to help them upgrade
safely. The time is now for the research community to develop such tools: large
component ecosystems exist and are accessible, component interactions have
become observable through automated builds, and recent advances in program
analysis make the development of relevant tools feasible. In particular,
contracts (both traditional and lightweight) are a promising input to semantic
versioning calculators, which can suggest whether an upgrade is likely to be
safe.Comment: to be published as Onward! Essays 202
On the Relationship between Code Verifiability and Understandability
Proponents of software verification have argued that simpler code is easier
to verify: that is, that verification tools issue fewer false positives and
require less human intervention when analyzing simpler code. We empirically
validate this assumption by comparing the number of warnings produced by four
state-of-the-art verification tools on 211 snippets of Java code with 20
metrics of code comprehensibility from human subjects in six prior studies. Our
experiments, based on a statistical (meta-)analysis, show that, in aggregate,
there is a small correlation (r = 0.23) between understandability and
verifiability. The results support the claim that easy-to-verify code is often
easier to understand than code that requires more effort to verify. Our work
has implications for the users and designers of verification tools and for
future attempts to automatically measure code comprehensibility: verification
tools may have ancillary benefits to understandability, and measuring
understandability may require reasoning about semantic, not just syntactic,
code properties.Comment: to appear at Proceedings of the 31st ACM Joint European Software
Engineering Conference and Symposium on the Foundations of Software
Engineering (ESEC/FSE'23
Inferring Concise Specifications of APIs
Modern software relies on libraries and uses them via application programming
interfaces (APIs). Correct API usage as well as many software engineering tasks
are enabled when APIs have formal specifications. In this work, we analyze the
implementation of each method in an API to infer a formal postcondition.
Conventional wisdom is that, if one has preconditions, then one can use the
strongest postcondition predicate transformer (SP) to infer postconditions.
However, SP yields postconditions that are exponentially large, which makes
them difficult to use, either by humans or by tools. Our key idea is an
algorithm that converts such exponentially large specifications into a form
that is more concise and thus more usable. This is done by leveraging the
structure of the specifications that result from the use of SP. We applied our
technique to infer postconditions for over 2,300 methods in seven popular Java
libraries. Our technique was able to infer specifications for 75.7% of these
methods, each of which was verified using an Extended Static Checker. We also
found that 84.6% of resulting specifications were less than 1/4 page (20 lines)
in length. Our technique was able to reduce the length of SMT proofs needed for
verifying implementations by 76.7% and reduced prover execution time by 26.7%
A Lightweight Type System with Uniqueness and Typestates for the Java Cryptography API
Java cryptographic APIs facilitate building secure applications, but not all developers have strong cryptographic knowledge to use these APIs correctly.
Several studies have shown that misuses of those cryptographic APIs may cause significant security vulnerabilities, compromising the integrity of applications and exposing sensitive data. Hence,
it is an important problem to design methodologies and techniques, which can guide developers in building secure applications with minimum effort, and that are accessible to non-experts in cryptography.
In this thesis, we present a methodology that reasons about the correct usage of Java cryptographic APIs with types, specifically targeting to cryptographic applications.
Our type system combines aliasing control and the abstraction of object states into typestates, allowing users to express a set of user-defined disciplines on the use of cryptographic APIs and invariants on variable usage. More specifically, we employ the typestate automaton to depict typestates within our type system, and we control aliases by applying the principle of uniqueness to sensitive data.
We mainly focus on the usage of initialization vectors. An initialization vector is a binary vector used as the input to initialize the state for the encryption of a plaintext block sequence. Randomization and uniqueness are crucial to an initialization vector. Failing to maintain a unique initialization vector for encryption can compromise confidentiality. Encrypting the same plaintext with the same initialization vector always yields the same ciphertext, thereby simplifying the attacker's task of guessing the cipher pattern.
To address this problem practically, we implement our approach as a pluggable type system on top of the EISOP Checker Framework.
To minimize the cryptographic expertise required by application developers looking to incorporate secure computing concepts into their software, our approach allows cryptographic experts to plug in the protocols into the system.
In this setting, developers merely need to provide minimal annotations on sensitive data—requiring little cryptographic knowledge.
We also evaluated our work by performing experiments over one benchmark and 7 real-world Java projects from Github. We found that 6 out 7 projects have security issues. In summary, we found 12 misuses in initialization vectors
Runtime Verification Of SQL Correctness Properties with YR-DB-RUNTIME-VERIF
Software correctness properties are essential to maintain quality by continuous and regressive inte-
gration testing, as well as runtime monitoring the program after customer deployment. This paper
presents an effective and lightweight C ++ program verification framework: YR_DB_RUNTIME_VERIF,
to check SQL (Structure Query Language) [1] software correctness properties specified as temporal
safety properties [2]. A temporal safety property specifies what behavior shall not occur, in a software,
as sequence of program events. YR_DB_RUNTIME_VERIF allows specification of a SQL temporal safety
property by means of a very small state diagram mealy machine [3]. In YR_DB_RUNTIME_VERIF, a spec-
ification characterizes effects of program events (via SQL statements) on database table columns by
means of set interface operations (∈, ∈), and, enable to check these characteristics hold or not at
runtime. Integration testing is achieved for instance by expressing a state diagram that encompasses
both Graphical User Interface (GUI) states and MySQL [4] databases queries that glue them. For
example, a simple specification would encompass states between ’Department administration’ and
’Stock listing’ GUI interfaces, and transitions between them by means of MySQL databases oper-
ations. YR_DB_RUNTIME_VERIF doesn’t generate false warnings; YR_DB_RUNTIME_VERIF specifications
are not desirable (forbidden) specifications (fail traces). This paper focuses its examples on MySQL
database specifications, labeled as states diagrams events, for the newly developed and FOSS (Free
and Open Source Software) Enterprise Resource Planing Software YEROTH–ERP–3.0 [5].PROF. DR.-ING. DIPL.-INF. xavier noumbissi noundo
Integrated Reasoning and Proof Choice Point Selection in the Jahob System – Mechanisms for Program Survival
In recent years researchers have developed a wide range of powerful automated reasoning systems. We have leveraged these systems to build Jahob, a program specification, analysis, and verification system. In contrast to many such systems, which use a monolithic reasoning approach, Jahob provides a general integrated reasoning framework, which enables multiple automated reasoning systems to work together to prove the desired program correctness properties.
We have used Jahob to prove the full functional correctness of a collection of linked data structure implementations. The automated reasoning systems are able to automatically perform the vast majority of the reasoning steps required for this verification. But there are some complex verification conditions that they fail to prove. We have therefore developed a proof language, integrated into the underlying imperative Java programming language, that developers can use to control key choice points in the proof search space. Once the developer has resolved these choice points, the automated reasoning systems are able to complete the verification. This approach appropriately leverages both the developer’s insight into the high-level structure of the proof and the ability of the automated reasoning systems to perform the mechanical steps required to prove the verification conditions.
Building on Jahob’s success with this challenging program verification problem, we contemplate the possibility of verifying the complete absence of fatal errors in large software systems. We envision combining simple techniques that analyze the vast majority of the program with heavyweight techniques that analyze those more sophisticated parts of the program that may require arbitrarily sophisticated reasoning. Modularity mechanisms such as abstract data types enable the sound division of the program for this purpose. The goal is not a completely correct program, but a program that can survive any remaining errors to continue to provide acceptable service
- …