skip to main content
research-article
Open Access

On Time-sensitive Control Dependencies

Authors Info & Claims
Published:09 December 2021Publication History

Skip Abstract Section

Abstract

We present efficient algorithms for time-sensitive control dependencies (CDs). If statement y is time-sensitively control dependent on statement x, then x decides not only whether y is executed but also how many timesteps after x. If y is not standard control dependent on x, but time-sensitively control dependent, then y will always be executed after x, but the execution time between x and y varies. This allows us to discover, e.g., timing leaks in security-critical software.

We systematically develop properties and algorithms for time-sensitive CDs, as well as for nontermination-sensitive CDs. These work not only for standard control flow graphs (CFGs) but also for CFGs lacking a unique exit node (e.g., reactive systems). We show that Cytron’s efficient algorithm for dominance frontiers [10] can be generalized to allow efficient computation not just of classical CDs but also of time-sensitive and nontermination-sensitive CDs. We then use time-sensitive CDs and time-sensitive slicing to discover cache timing leaks in an AES implementation. Performance measurements demonstrate scalability of the approach.

Skip 1INTRODUCTION AND OVERVIEW Section

1 INTRODUCTION AND OVERVIEW

Timing Leaks are a major source of software security problems today. Attacks based on timing leaks such as Spectre [22] have become known to the general public. Yet there are not many program analysis tools that detect timing leaks in software.

In this article, we describe a new kind of dependency between program statements, the time-sensitive control dependency. It is able to discover timing leaks and can be implemented as an automatic program analysis. We will explain time-sensitive dependencies, provide efficient algorithms, provide a soundness proof and apply it to discover timing leaks in an implementation of the AES cryptographic standard.

The construction of time-sensitive control dependencies starts with classical control dependencies. We will thus begin by sketching the research path from control dependencies (CDs) to timing dependencies, and provide introductory examples. Later in the article, we will provide formal definitions, proofs, and algorithms.

CDs, originally introduced in References [11, 33], are a fundamental building block in program analysis. CDs have many applications: They can, for example, be used for program optimizations such as code scheduling, loop fusion, or code motion (see, e.g., Reference [25]) or for program transformations such as partial evaluation (e.g., Reference [20]) or refactoring (e.g., Reference [5]). CDs are in particular fundamental for program dependence graphs (PDGs) and program slicing [11, 19, 23]. Intuitively, a program statement y is control dependent on another statement x, written \(x \rightarrow _{cd}y\), if x—typically an if or while statement—decides whether y will be executed or not. Classical CDs are defined via postdominators; in fact classical CDs are essentially the postdominance frontiers in the control flow graph (CFG) [10]. Postdominance frontiers can be computed by an efficient algorithm due to Cytron [10].

Unfortunately, the classic CD definition is limited to CFGs with unique exit node, and thus assumes that all programs can terminate. In 2007, Ranganath et al. [29] generalized control dependence to CFGs without unique exits and nonterminating programs (e.g., reactive systems); providing the first algorithm for nontermination-sensitive CDs. Later, Amtoft [3] provided definitions and algorithms for nontermination-insensitive CDs, which allow for sound analysis and slicing of nonterminating programs. But these algorithms could no longer be based on the efficient Cytron algorithm for postdominance frontiers.

In this contribution, we not only present new efficient algorithms for the Ranganath-Amtoft CD definitions. We will also provide definitions and algorithms for time-sensitive CDs and time-sensitive slicing. Time-sensitive CD, written \(x \rightarrow _{\mathrm{tscd}} y\), holds if x decides whether y is executed or if x decides when y is executed (even if y is always executed after x)—that is, how many time units after execution of x. Intuitively, \(x \rightarrow _{\mathrm{tscd}} y\) while not \(x\rightarrow _{cd} y\) means that y will always be executed after x, but the execution time between x and y varies. The latter property is important to discover timing leaks in security-critical software.

We systematically develop theoretical properties and efficient algorithms for \(\rightarrow _{\mathrm{tscd}}\) and evaluate their performance. It turns out that Cytron’s efficient algorithm for dominance frontiers can be generalized to an abstract notion of dominance, which then can be used for the efficient computation of both the Ranganath/Amtoft CD, as well as our new time-sensitive CD. We then apply \(\rightarrow _{\mathrm{tscd}}\) to (models of) hardware microarchitectures, and use it to find cache timing leaks in an AES implementation.

Many of the theorems in this article have been formalized and machine-checked using the machine prover Isabelle. Such theorems are marked with a sign. The Isabelle proofs can be found in the electronic appendix of this article. For some theorems in Section 5, such an Isabelle proof has not yet been completed. Manual proofs are available but are not presented in this article. Consequently, such theorems are called “observations.”

1.1 Overview

The main part of this article will present time-sensitive CDs and algorithms in a rather technical manner. Before we embark on this, we present an informal overview of our research path and results. We begin with a discussion of classical control dependencies and compare these to our new notion of time-sensitive control dependencies.

1.1.1 Control Dependence.

Informally, a control dependence in a CFG, written \(x\rightarrow _{cd} y\), means that x decides whether y is executed or not. In structured programs, x is typically an if or while statement. Figure 1 presents two examples: In the first example (left), node (5) is control dependent on node (1); node (3) is not control dependent on (1) but on (2). In the second example (right),1 nodes (2), (3), and (4) are control dependent on node (1). Technically, CD is based on the notion of postdomination in CFGs. y postdominates x (written \(y~\sqsubseteq _{\mathrm{POST}}~x\)) if any path from x to the \({exit}\) node must pass through y. Several formal CD definitions exist; as this may be confusing we will relate the most popular definitions to the examples in Figure 1. The original definition of CD in Reference [11] is as follows: \[ x\rightarrow _{cd} y \iff \lnot \bigl (y~\sqsubseteq _{\mathrm{POST}}~x\bigr) \wedge \exists \mbox{ path } \pi : x \rightarrow ^{*} y \mbox{ such that } \forall z\in \pi \setminus \lbrace x,y\rbrace : y~\sqsubseteq _{\mathrm{POST}}~z. \]

Fig. 1.

Fig. 1. Two simple control flow graphs illustrating control dependence.

The condition that y is not a postdominator for x means that from x there is a second path (not containing y) to the exit node. That is, there is a conditional branch at x. The next condition demands that there is a path from x to y, and that y is a postdominator for all nodes z between x and y. Thus there is no side branch from any z to the exit node; hence x is directly controlling whether y is executed.

In Figure 1 (left), node (5) postdominates all nodes on paths between (1) and (5), but (5) does not postdominate (1); hence \(\left(1\right)\rightarrow _{cd}\left(5\right)\). But (3) does not postdominate (2) (this node being the only one between (1) and (3)), hence \(\lnot \bigl (\left(1\right)\rightarrow _{cd}\left(3\right)\bigl)\). In Figure 1 (right), node (4) is control dependent on node (1). Since we have \(\left(1\right)\rightarrow \left(5\right)\), node (4) does not postdominate (1). The path \(\left(1\right)\rightarrow \left(3\right)\rightarrow \left(4\right)\) only contains the additional \(z=\left(3\right)\), and (4) postdominates (3), so the second condition is satisfied. But what about the path \(\left(1\right)\rightarrow \left(2\right)\rightarrow \left(3\right)\rightarrow \left(4\right)\)? It is irrelevant, as the CD definition only demands there exists a path where for all z, and so on; it does not demand the z condition for all paths. Likewise, (2) as well as (3) are control dependent on (1).

An alternate, more compact CD definition was provided in Reference [33], and is used in this article. Here x is a branch node with direct successors n and m, where the control-dependent y postdominates one but not the other: \[ x\rightarrow _{cd} y \iff \exists n, m: x\rightarrow n, x\rightarrow m, y~\sqsubseteq _{\mathrm{POST}}~n, \lnot \bigl (y~\sqsubseteq _{\mathrm{POST}}~m\bigr). \]

Lemma 1.1.

The above definitions for \(x\rightarrow _{cd} y\) are equivalent whenever \(x\ne y\).

Applied to Figure 1 (right), again we conclude that (4) is CD on (1). Choose (2) (n = (3) also works), m = (5), then (4) postdominates (2) (and (3)), but (4) does not postdominate (5). Note that both n and m in the definition are existentially quantified. Thus the definition neither demands nor inhibits that (4) postdominates (3).

Lemma 1.2.

In Figure 1 (right), we have \(\left(4\right)~\sqsubseteq _{\mathrm{POST}}~\left(2\right)\), \(\left(4\right)~\sqsubseteq _{\mathrm{POST}}~\left(3\right)\), \(\lnot \bigl (\left(4\right)~\sqsubseteq _{\mathrm{POST}}~\left(5\right)\bigr)\), and thus \(\left(1\right)\rightarrow _{cd}\left(4\right)\).

1.1.2 CFGs without Unique Exit.

CFGs without unique exit, in particular with no exit or unreachable exits, are important for modern language constructs, for example, event handlers or loops in reactive systems. Ranganath and Amtoft had generalized postdominance and CD for such CFGs. The resulting postdominance relations are called max- and sink-postdominance and will be explained in Section 2.2. If these are used in CD definitions, then one obtains non-termination-sensitive control dependence, written \(\rightarrow _{\mathrm{ntscd}}\); and non-termination-insensitive control dependence, written \(\rightarrow _{\mathrm{nticd}}\). \(\rightarrow _{\mathrm{nticd}}\) is identical to \(\rightarrow _{cd}\) but also works for graphs without unique exit. \(\rightarrow _{\mathrm{ntscd}}\) is identical to \(\rightarrow _{wcd}\) (weak control dependence, see Section 2.1) but also works for graphs without unique exit.

\(\rightarrow _{\mathrm{nticd}}\) and \(\rightarrow _{\mathrm{ntscd}}\) are important building blocks for \(\rightarrow _{\mathrm{tscd}}\). A comparison between \(\rightarrow _{\mathrm{nticd}}\), \(\rightarrow _{\mathrm{ntscd}}\), and \(\rightarrow _{\mathrm{tscd}}\) is given in the next section.

1.1.3 Time-sensitive Control Dependence.

Time-sensitive CD, written \(x \rightarrow _{\mathrm{tscd}} y\), holds if x decides when or whether y is executed. This dependence is more relaxed than standard CD. Intuitively, \(x \rightarrow _{\mathrm{tscd}} y\) while not \(x\rightarrow _{cd} y\) means that y will always be executed after x, but the execution time between x and y varies.

The latter property is important to discover timing leaks in security-critical software. A typical situation is as follows: y is not control dependent on x, but there are at least two paths from x to y. Then the runtime between x and y varies: \(x \rightarrow _{\mathrm{tscd}} y\). If this variation depends on secret data, and can be measured by an attacker, then a timing leak has been born. \(x \rightarrow _{\mathrm{tscd}} y\) will uncover this leak.

In our work time is discrete; a unit of time coincides with a transition in the CFG. Since steps of an abstraction of real programs and hardware are timed, this is therefore a “weakly timing-sensitive” model in the sense of Reference [21].

Now, let us illustrate the differences between the different kinds of control dependencies. A node y is non-termination sensitively control dependent on node x, written \(x \rightarrow _{\mathrm{ntscd}} y\), if x decides whether y will be executed. In Figure 2, we have \(\left(1\right) \rightarrow _{\mathrm{ntscd}} \left(2\right)\), because we will execute (2) when choosing (2) as the successor of (1) but not if we choose (10). Also, due to the loop at (3), we have \(\left(3\right) \rightarrow _{\mathrm{ntscd}} \left(10\right)\): By choosing (9) as the successor of (3) we are guaranteed to reach (10). But if we choose (4) as the successor, then we might avoid reaching (10) by staying in the loop forever, so (3) decides if (10) will be executed.

Fig. 2.

Fig. 2. A CFG G.

y is non-termination insensitively control dependent on x, written \(x \rightarrow _{\mathrm{nticd}} y\), if x decides whether y will be executed, assuming we eventually exit all loops that can be exited. In Figure 2, we still have \(\left(1\right) \rightarrow _{\mathrm{nticd}} \left(2\right)\), with the same reasoning as above. But now we have \(\lnot \left(\left(3\right) \rightarrow _{\mathrm{ntscd}} \left(10\right)\right)\): Since we assume that we always exit the loop at (3), we are guaranteed to reach (10), no matter which successor we choose at (3).

y is timing sensitively control dependent on x, written \(x \rightarrow _{\mathrm{tscd}} y\), if x decides when y will be executed. In Figure 2, we have \(\left(7\right) \rightarrow _{\mathrm{tscd}} \left(8\right)\), because we will execute (8) after one step when choosing (8) as the successor of (7) but not if we choose (11), when it takes two or three steps. Therefore, the choice taken at (7) influences the timing of (8). On the contrary, \(\lnot \left(\left(4\right) \rightarrow _{\mathrm{tscd}} \left(5\right)\right)\), because no matter how we choose, we will always reach (5) in two steps. An interesting case is \(\left(1\right) \rightarrow _{\mathrm{tscd}} \left(2\right)\): If we choose (2) as successor of (1), then we will reach (2) in exactly one step, but we will not if we choose (10), because we then will not reach (2).

1.1.4 Applications for Software Security.

As indicated, \(\rightarrow _{\mathrm{tscd}}\) may help to discover timing leaks. More generally, \(\rightarrow _{\mathrm{tscd}}\) is useful for Information Flow Control (IFC). IFC uses program analysis techniques to discover leaks in software. Technically, noninterference is a property that guarantees that a program does not leak secret data. Probabilistic noninterference guarantees that there are no internal timing leaks, which arise if secret data influence scheduling or other measurable timing properties. For an introduction to IFC, see, e.g., Reference [31].

Indeed \(\rightarrow _{\mathrm{tscd}}\) was developed as an instrument to improve the precision of probabilistic noninterference analysis. We will report on applications of \(\rightarrow _{\mathrm{tscd}}\) for IFC in a separate article. In the current article, we focus on algorithms for \(\rightarrow _{\mathrm{tscd}}\) and use a different security example: In Section 4, we will analyse an implementation of the AES cryptographic standard and discover cache leaks in this implementation. These infamous cache leaks have been known for some time [4], but so far no program analysis tool was able to discover such leaks.

1.1.5 Algorithms.

The major part of this contribution is concerned with efficient algorithms for \(\rightarrow _{\mathrm{tscd}}\). For the classical \(\rightarrow _{cd}\), Cytron’s efficient algorithm for dominance frontiers can be used; but this algorithm was not employed by Ranganath/Amtoft.

We discovered that a generalized version of Cytron’s algorithm can not only be used for both \(\rightarrow _{\mathrm{nticd}}\) and \(\rightarrow _{\mathrm{ntscd}}\) but also for \(\rightarrow _{\mathrm{tscd}}\). Thus we have been able to obtain efficient implementations for all these dependence notions. The algorithms are described in Section 5. Performance evaluations are described in Section 6.

Skip 2CONTROL DEPENDENCE IN GRAPHS WITHOUT UNIQUE EXIT Section

2 CONTROL DEPENDENCE IN GRAPHS WITHOUT UNIQUE EXIT

Our work was strongly motivated by earlier results of Ranganath et al. [29] and Amtoft [3]. These authors extended the classical notion of CD and slicing to CFGs that do not contain a unique exit node. As multiple exit nodes can trivially be handled by adding a new “global” exit node, Ranganath’s and Amtoft’s work is in fact concerned with CFGs that do not have a single, unique exit node. A typical example is a CFG with an infinite loop from which an exit node cannot be reached. Such CFGs are relevant, because modern programs need not necessarily terminate through exit nodes. One paramount example are reactive systems, which are assumed to run forever; and thus have no exit node at all. Another example are event handlers, which may shutdown a thread while the thread has no explicit exit. Thus Ranganath and Amtoft opened the door to apply CD and slicing to modern program structures.

Time-sensitive CD will also work on graphs without unique exit. It is therefore necessary to recall Ranganath’s and Amtoft’s work. We begin with fundamental definitions of CDs and postdomination for CFGs with no unique exit.

2.1 Classical Control Dependence and Weak Control Dependence

CFGs are a standard representation of programs, e.g., in compilers, and many tools are available that extract CFGs from source code.2 Thus let \(G = \left(N, \rightarrow _{G} \right)\) be the CFG of a program. In this article, we once and for all assume a fixed CFG G and therefore omit the sub- or superscript G whenever possible; e.g., we write \(n\rightarrow m\) instead of \(n \rightarrow _{G} m\). In the classical case of a unique exit node, there is \({exit} \in N\) such that \(n\rightarrow ^{*} {exit}\) for all nN, and \({exit}\rightarrow n\) for no node nN.

Node m postdominates n (\(m~\sqsubseteq _{\mathrm{POST}}~n\)) iff \(m \in \pi\) for every path π from n to \({exit}\). Node m strongly postdominates n (\(m~\sqsubseteq _{\mathrm{SPOST}}~n\)) iff \(m~\sqsubseteq _{\mathrm{POST}}~n\), and there exists some \(k \ge 1\) such that \(m \in \pi\) for every path π starting in n with length \(\ge k\) [27]. In contrast to \(m~\sqsubseteq _{\mathrm{POST}}~n\), \(m~\sqsubseteq _{\mathrm{SPOST}}~n\) does not hold if there is an infinite loop between m and n: Assume such a loop exists, then there will be paths π starting at n of arbitrary length k that never pass through m: \(\forall k\exists \pi : \mbox{len}(\pi)=k\wedge m \not\in \pi\). If this happens, then \(~\sqsubseteq _{\mathrm{SPOST}}~\) is not supposed to hold; hence the negation of the latter condition must hold for \(~\sqsubseteq _{\mathrm{SPOST}}~\).

Classical (nontermination-insensitive) CD, denoted \(\rightarrow _{cd}\), is defined in terms of postdominance. Formally (as already explained above), \[ x\rightarrow _{cd} y \iff \exists n, m\in N: x\rightarrow n, x\rightarrow m, y~\sqsubseteq _{\mathrm{POST}}~n, \lnot \bigl (y~\sqsubseteq _{\mathrm{POST}}~m\bigr). \]

This CD definition can be modified to react sensitively to infinite loops. This nontermination-sensitive form of CD, called “weak control dependence” and written \(x\rightarrow _{wcd}y\), was introduced in Reference [27] and is defined in terms of strong postdominance. The formal definition is identical to the above CD definition; with \(\sqsubseteq _{\mathrm{SPOST}}\) instead of \(\sqsubseteq _{\mathrm{POST}}\) . Even if \(x\rightarrow _{cd} y\) does not hold, \(x\rightarrow _{wcd}y\) might still hold if there is an infinite loop between x and y. Note that weak control dependence does not imply that this infinite loop is in fact executed.

2.2 Postdominance in Graphs without Unique Exit

To understand how the above definitions are generalized to arbitrary graphs with no unique exit node, consider the example in Figure 2. It has no unique exit node, since the only candidate node 10 is unreachable from, e.g., node 6. Thus the classical definitions for \(\sqsubseteq _{\mathrm{POST}}\) and \(\sqsubseteq _{\mathrm{SPOST}}\) cannot be applied. Instead, Ranganath et al. [29] proposed control dependence for arbitrary graphs based on the notions of maximal and sink paths.

A maximal path is a path that cannot be extended (i.e., is infinite, or ends in some node n without successor). However, a (control-) sink is a strongly connected component S such that no edge leaves S.3 Specifically, all nodes n without successor (in particular \(n=\mathit {exit}\)) form a (trivial) sink. A sink path then is a path π such that sS for some node \(s \in \pi\) and some sink S, and if S is nontrivial (i.e., not a singleton), then all nodes in S appear in π infinitely often. In programming terms, S would be an infinite loop in the CFG, and a sink path corresponds to an execution that infinitely loops in S.

Definition 2.1

(Implicit in Reference [29]).

A node mN nontermination-sensitively postdominates a node nN (written \(m~\sqsubseteq _{\mathrm{MAX}}~n\)) iff \(m \in \pi\) for all maximal paths π starting in n. Similarly, a node m nontermination-insensitively postdominates a node n (written \(m~\sqsubseteq _{\mathrm{SINK}}~n\)) iff \(m \in \pi\) for all sink paths π starting in n.

Since every sink path is a maximal path, \(m~\sqsubseteq _{\mathrm{MAX}}~n\) implies \(m~\sqsubseteq _{\mathrm{SINK}}~n\) . \(m~\sqsubseteq _{\mathrm{SINK}}~n\) while \(\lnot \left(m~\sqsubseteq _{\mathrm{MAX}}~n\right)\) means that on reaching n, m will later be executed unless an infinite loop is entered.

The following definition is equivalent to those in Reference [29] whenever \(n \ne m\).

Definition 2.2.

A node yN is non-termination sensitively (respectively, insensitively) control-dependent on xN, written \(x \rightarrow _{\mathrm{ntscd}} y\) (respectively, \(x \rightarrow _{\mathrm{nticd}} y\)), if there exist edges \(x\rightarrow n\), \(x\rightarrow m\) such that \(y~\sqsubseteq _{\mathrm{MAX}}~n\) (respectively, \(y~\sqsubseteq _{\mathrm{SINK}}~n\)), but \(\lnot \bigl (y~\sqsubseteq _{\mathrm{MAX}}~m\bigr)\) (respectively, \(\lnot \bigl (y~\sqsubseteq _{\mathrm{SINK}}~m\bigr)\)).

Note that this definition is identical to the original CD definition, with \(\sqsubseteq _{\mathrm{MAX}}\) , respectively, \(\sqsubseteq _{\mathrm{SINK}}\) instead of \(\sqsubseteq _{\mathrm{POST}}\) . In fact, for graphs with unique exit node, we have \(\rightarrow _{\mathrm{ntscd}} ~=~\rightarrow _{wcd}\) and \(\rightarrow _{\mathrm{nticd}} ~=~\rightarrow _{cd}\) [29]. Figure 3 shows \(\rightarrow _{\mathrm{ntscd}}\) and \(\rightarrow _{\mathrm{nticd}}\) for the CFG from Figure 2.

Fig. 3.

Fig. 3. Nontermination-(in)sensitive CDs for CFG from Figure 2.

Like many program analysis problems, postdominance and CD can be characterized as a fixpoint computation. Our first new insight is that both \(\sqsubseteq _{\mathrm{MAX}}\) and \(\sqsubseteq _{\mathrm{SINK}}\) can be characterized as a greatest, respectively, least fix point of one rule set \(\mathsf {D}_{}\). This surprising fact is the basis for our generalization of Cytron’s algorithm.

Theorem 2.1.

4 Let \(\mathsf {D}_{}\) be the following rule system, and let \(\mathsf {D}_{}\) also denote its implicit functional; write \(\mu\) for the least fixpoint, and \(\nu\) the greatest fixpoint. Then \(\mathsf {D}_{}\) is a monotone functional in the (finite) lattice \(\bigl (2^{N\times N}, \subseteq \bigr)\), and \(\mu \mathsf {D}_{}~=~ \sqsubseteq _{\mathrm{MAX}}\), and \(\nu \mathsf {D}_{}~=~ \sqsubseteq _{\mathrm{SINK}}\).

The reachability side-condition \(n\rightarrow ^{*} m\) is in most cases redundant for the least fixed point \(\mu \mathsf {D}_{}\), but essential for the greatest fixed point \(\nu \mathsf {D}_{}\).5

Of course, algorithms for \(\rightarrow _{\mathrm{ntscd}}\) and \(\rightarrow _{\mathrm{nticd}}\) are needed, and indeed Ranganath et al. proposed such algorithms. The algorithm for \(\rightarrow _{\mathrm{ntscd}}\) from Reference [29] can in principle be thought of as a simple least fixed point computation of the set of nodes m such that \(m~\sqsubseteq _{\mathrm{MAX}}~n\) but only for nodes n that are successors of branching nodes.

We, however, discovered a more general and systematic algorithmic approach, which exploits the above fix-point theorem. It is based on the insight that Cytron’s efficient algorithm for dominance frontiers can be generalized to an abstract notion of “dominance” and thus can be used for \(\sqsubseteq _{\mathrm{POST}}\) , \(\sqsubseteq _{\mathrm{SPOST}}\) , \(\sqsubseteq _{\mathrm{MAX}}\) , \(\sqsubseteq _{\mathrm{SINK}}\) , \(\rightarrow _{\mathrm{ntscd}}\), \(\rightarrow _{\mathrm{nticd}}\), and in particular for \(\rightarrow _{\mathrm{tscd}}\). We will present all algorithms in a separate section (Section 5), as they demand a rather heavy technical machinery.

In conclusion of this section, we recall another notion from Ranganath et al., which will also be helpful to characterise \(\rightarrow _{\mathrm{tscd}}\).

Definition 2.3

([29]).

Decisive order dependence, written \(n\rightarrow {\mathrm{dod}}\left(m_1,m_2\right)\) is a ternary relation, which means that n controls the order in which \(m_1, m_2\) are executed.

We omit the formal definition, but provide an intuition: In Reference [29], the necessity of \(\rightarrow {\mathrm{dod}}\) was motivated by an irreducible6 graph, such as the graph shown in Figure 4. Here, neither \(m_1\) nor \(m_2\) is nontermination sensitively control dependent on n: \(\lnot (n \rightarrow _{\mathrm{ntscd}} m_1) \wedge \lnot (n \rightarrow _{\mathrm{ntscd}} m_2)\). But the decision at n determines which node is executed next: Leaving n via the left branch will execute \(m_1\) before \(m_2\) but leaving n via the right branch will execute \(m_2\) before \(m_1\). Thus, \(n\rightarrow {\mathrm{dod}}\left(m_1,m_2\right)\) holds. Ranganath and Amtoft used \(\rightarrow _{\mathrm{ntscd}}\) and \(\rightarrow {\mathrm{dod}}\) to define a sound notion of nontermination-sensitive backward slicing. This is consistent with the fact that CDs are fundamental for slicing and PDGs.

Fig. 4.

Fig. 4. The canonical irreducible graph, where neither \( n \rightarrow _{\mathrm{ntscd}} m_1 \) nor \( n \rightarrow _{\mathrm{ntscd}} m_2 \).

Skip 3TIMING-SENSITIVE CONTROL DEPENDENCE Section

3 TIMING-SENSITIVE CONTROL DEPENDENCE

3.1 Why Time Sensitivity Matters

Before we formally develop timing-sensitive CDs, let us motivate the usefulness of this concept for software security analysis. Known attacks exploiting timing side channels include Spectre [22] and cache attacks on implementations of the cryptographic standard AES [4]. In this kind of attack, the attacker is able to observe the timing behaviour of certain instructions; from this observation determine whether some specific data are in the cache or not; and from this knowledge infer values of secret variables (e.g., by using the secret value as an array index) or draw conclusions about control flow.

Timing-sensitive CDs can reveal such potential attacks or prove that such attacks are impossible. For example, in a specific AES implementation7 we find the code lines

sbox is a constant array that typically spans multiple memory blocks, while r1, r2, r3 are registers. Thus the value of r2 in one iteration may influence whether the read of r3 in a later iteration is served from cache (namely if, earlier, the corresponding memory block was already loaded into the cache), or from main memory. This makes a difference in execution time and can be observed by an attacker; who may thus be able to infer the value of r2. Such leaks can be discovered by timing-sensitive CDs; provided the CFG not just describes the code, but additionally models relevant hardware features such as cache behaviour.

Figure 5 shows the standard CFG for the AES code fragment, as well as the micro-architectural CFG, which models timing differences due to cache hits and misses. The latter CFG indicates that array access r3 := sbox[r2] in line (3) may either result in a cache hit or cache miss. In the control flow, this is modeled via two paths leaving node (3) that are joined after following a different number of edges, and take a different amount of time to execute. Specifically, the time at which execution reaches the exit node (5) depends on which paths are taken at (3): Node (5) is time sensitively control dependent on node (3). The edge annotations use r2 indicate that the value register r2 determines which array index, and hence which cache line is accessed at (3). Furthermore, due to the previous assignment r2 := state[r1], node (3) is data dependent on the initialization of the state array from the plain text message and the key, as indicated in node (0).8 Thus we obtain the following dependency chain (where \(\rightarrow _{dd}\) denotes data dependency): \((\mbox{secret input})\rightarrow _{dd} \mathtt {state}\rightarrow _{dd} \mathtt {r2} \rightarrow _{dd} (3)\rightarrow _{\mathrm{tscd}} (5)\). This means that the time until (5) is reached depends on secret input. Thus time-sensitive CDs reveal that sbox access is not constant time (in contrast to the AES specification); opening a door to cache-leak based attacks.

Fig. 5.

Fig. 5. Control Flow Graphs for AES Sbox substitution.

If a \(\rightarrow _{\mathrm{tscd}}\) dependency is not (indirectly) data dependent on secret data, then it does not generate a timing leak. For example, in the AES CFG, \((2) \rightarrow _{\mathrm{tscd}} (5)\) also holds. But the value of r1 (and thus (2)) is not data dependent on any secret value, so no timing leak arises via (2). We will discuss this in more depth in Section 3.4; and come back to AES and micro-architectural CFGs in Section 4.

3.2 Timing-sensitive Control Dependence

Consider Figure 6(a): \(m_x\) is guaranteed to be executed, no matter which branch is taken at n, so we have \(\lnot \left(n \rightarrow _{\mathrm{ntscd}} m_x\right)\). But let us assume that we could measure execution times. Now, n can control at which time \(m_x\) will be executed, namely 4 or 2 steps after executing n. We will say that \(m_x\) is timing sensitively control dependent on n, or \(n \rightarrow _{\mathrm{tscd}} m_x\). In Figure 6(b), however, \(m_x\) will always be executed 4 steps after n, so there we have \(\lnot \left(n \rightarrow _{\mathrm{tscd}} m_x\right)\).

Fig. 6.

Fig. 6. Dependence of execution time of \( m_x \) on n.

We will now formally define \(\rightarrow _{\mathrm{tscd}}\). Specifically, we will

(1)

Propose a notion \(\sqsubseteq _{\mathrm{TIME}}\) of timing-sensitive postdominance.

(2)

Give a least fixed point characterization of \(\sqsubseteq _{\mathrm{TIME}}\).

(3)

Propose a notion \(\rightarrow _{\mathrm{tscd}}\) of timing-sensitive control dependence. It will be based on \(\sqsubseteq _{\mathrm{TIME}}\) the same way that \(\rightarrow {ntscd}\) is based on \(\sqsubseteq _{\mathrm{MAX}}\).

(4)

Prove soundness and minimality of \(\rightarrow _{\mathrm{tscd}}\).

To start with, remember that \(\sqsubseteq _{\mathrm{MAX}}\) was defined via \[ m~\sqsubseteq _{\mathrm{MAX}}~n \iff \forall \pi \in {}_{n}\Pi _{\mathrm{MAX}}.~\ m \in \pi , \] where \({}_{n}\Pi _{\mathrm{MAX}}\) is the set of maximal paths starting in n. For example, in Figure 6(a) it holds that \(m_x~\sqsubseteq _{\mathrm{MAX}}~n\), because any maximal path starting in any successor of n must contain \(m_x\) (i.e., both \(m_x~\sqsubseteq _{\mathrm{MAX}}~n^{\prime }\) and \(m_x~\sqsubseteq _{\mathrm{MAX}}~n^{\prime \prime }\)), and so must any maximal path starting in n.

Now for time-sensitive postdominance we additionally want to express that in Figure 6(a) \(m_x\) can be reached via two different paths, with varying execution time. To account for the different timing of the (first) occurrence of \(m_x\) in maximal paths starting in n, the following auxiliary definition is needed.

Definition 3.1.

Given any path \(\pi = m_0,m_1,m_2,\ldots\), we say that m appears in π at position k iff \(m = m_k\) and write \(m \in ^{k} \pi\). If additionally, \(m_i \ne m\) for all \(i \lt k\), then we say that m first appears in π at position k and write \(m \in ^{k}_{\mathrm{FIRST}} \pi\).

Using this notation, we can define time-sensitive postdominance as follows.

Definition 3.2.

(a) m timing-sensitively postdominates n at position \(k \in \mathbb {N}\), written \(m~\sqsubseteq _{\mathrm{TIME}}^{k}~n\), iff on all maximal paths starting in n, m first appears at position k. Formally, \[ m~\sqsubseteq _{\mathrm{TIME}}^{k}~n \iff \forall \pi \in {}_{n}\Pi _{\mathrm{MAX}}.~\ m \in ^{k}_{\mathrm{FIRST}} \pi . \] (b) m timing-sensitively postdominates n, written \(m~\sqsubseteq _{\mathrm{TIME}}~n\), if there exists k such that \(m~\sqsubseteq _{\mathrm{TIME}}^{k}~n\). Thus \[ m~\sqsubseteq _{\mathrm{TIME}}~n \iff \exists k\in \mathbb {N}~ \forall \pi \in {}_{n}\Pi _{\mathrm{MAX}}.~\ m \in ^{k}_{\mathrm{FIRST}} \pi . \]

If we compare \(m~\sqsubseteq _{\mathrm{TIME}}^{k}~n\) to \(m~\sqsubseteq _{\mathrm{MAX}}~n\), then the difference is that in the latter, m must occur somewhere in all maximal paths from n, while in the former m must first occur at a specific position k in all maximal paths from n. Thus, if \(m~\sqsubseteq _{\mathrm{TIME}}~n\), then m must appear in all maximal paths from n at the same position. Therefore in Figure 6(a), \(m_x~\sqsubseteq _{\mathrm{TIME}}~n\) does not hold, while in Figure 6(b), \(m_x~\sqsubseteq _{\mathrm{TIME}}~n\) does hold.

Lemma 3.1.

Given m and n, the k such that \(m~\sqsubseteq _{\mathrm{TIME}}^{k}~n\) (if it exists) is unique.

Following the definitions for nontermination sensitive and insensitive control dependence \(\rightarrow {ntscd}\) and \(\rightarrow {nticd}\), we define the following timing-sensitive notion of control dependence:

Definition 3.3.

y is said to be timing sensitively control-dependent on x, written \(x \rightarrow _{\mathrm{tscd}} y\), if there exist edges \(x\rightarrow n\) and \(x\rightarrow m\) as well as some \(k \in \mathbb {N}\) such that \[ y~\sqsubseteq _{\mathrm{TIME}}^{k}~n \mbox{and} \lnot \left(y~\sqsubseteq _{\mathrm{TIME}}^{k}~m\right). \] Note that this definition is identical to the definition of \(\rightarrow _{\mathrm{ntscd}}\), respectively, \(\rightarrow _{cd}\); with \(~\sqsubseteq _{\mathrm{TIME}}^{k}~\) instead of \(~\sqsubseteq _{\mathrm{MAX}}~\), respectively, \(~\sqsubseteq _{\mathrm{POST}}~\). Thus \(\rightarrow _{\mathrm{tscd}}\) has the same formal structure as classical CD and its later extensions.

In Figure 6(a), we have \(m_x~\sqsubseteq _{\mathrm{TIME}}^{3}~n^{\prime }\) but \(\lnot (m_x~\sqsubseteq _{\mathrm{TIME}}^{3}~n^{\prime \prime })\), and thus we have \(n \rightarrow _{\mathrm{tscd}} m_x\); while in Figure 6(b) we have \(m_x~\sqsubseteq _{\mathrm{TIME}}^{3}~n^{\prime }\) and \(m_x~\sqsubseteq _{\mathrm{TIME}}^{3}~n^{\prime \prime }\) and thus not \(n \rightarrow _{\mathrm{tscd}} m_x\). For more complex examples, consider again the CFG in Figure 2. The timing-sensitive postdominance for this CFG is shown in Figure 7(b). Figure 7(c) and Figure 7(d) show the corresponding non-termination-sensitive and timing-sensitive control dependencies. Note, for example, that \(7 \rightarrow _{\mathrm{tscd}} 8\), because a choice \(7 \rightarrow _{G\hspace{1.42271pt}} 11\) can delay node 8, but in contrast: \(\lnot (7 \rightarrow _{\mathrm{ntscd}}^{*} 8)\), because no choice at node 7 can prevent node 8 from being executed. It is not the case that, in general, \(n \rightarrow _{\mathrm{ntscd}} m\) implies \(n \rightarrow _{\mathrm{tscd}} m\). For example: \(2 \rightarrow _{\mathrm{ntscd}} 8\), but \(\lnot (2 \rightarrow _{\mathrm{tscd}} 8)\). What does hold here is \(2 \rightarrow _{\mathrm{tscd}}^{*} 8\) via \(2 \rightarrow _{\mathrm{tscd}} 7 \rightarrow _{\mathrm{tscd}} 8\).

Fig. 7.

Fig. 7. Timing-sensitive postdomination. Edges \( n \xrightarrow {k} m \) indicate \( m~\sqsubseteq _{\mathrm{TIME}}^{k}~n \).

We will now provide a fixpoint characterization of \(m~\sqsubseteq _{\mathrm{TIME}}^{k}~n\). Remember from Theorem 2.1 that \(\sqsubseteq _{\mathrm{MAX}}\) is the least fixed point of the rule system \(\mathsf {D}_{},\)

in the lattice \(\left(2^{N \times N}, \subseteq \right)\). Similarly, the ternary relation \(m~\sqsubseteq _{\mathrm{TIME}}^{k}~n\) is the least fixed point of the rule system \(\mathsf {T}_{\mathrm{FIRST}}\) in the underlying lattice \(\left(2^{N \times \mathbb {N} \times N}, \subseteq \right)\),

Theorem 3.1.

Let \(\mathsf {T}_{\mathrm{FIRST}}\) be the rule-system

Then \(\sqsubseteq _{\mathrm{TIME}}~=~ \mu \mathsf {T}_{\mathrm{FIRST}}\).

Note that the condition \(n \rightarrow _{\hspace{1.42271pt}}^{*} m\) is redundant for nodes n that have some successor x, since we consider only the least, but not the greatest, fixed point of \(\mathsf {T}_{\mathrm{FIRST}}\). The condition \(m \ne n\) ensures that we only consider the first occurrence of m in each path.

We will now demonstrate that \(\rightarrow _{\mathrm{tscd}}\) is transitively a stricter requirement than non-termination-sensitive control independence. To this end, we use the following notation.

Definition 3.4.

For \(M\subseteq N\) and \(\rightarrow\) a relation on N, the backward slice of M is \[ \bigl (\rightarrow \bigr)^{*}\left(M\right) = \lbrace y\mid \exists x\in M: y\rightarrow ^{*} x\rbrace . \] This definition can be generalized to the ternary relation \(\rightarrow {\mathrm{dod}}\): If \(y\rightarrow {\mathrm{dod}}\left(x_1,x_2\right)\), \(y\in \bigl (\rightarrow {\mathrm{dod}}\bigr)^{*}\left(M\right)\) only if \(x_1\) and \(x_2\in \bigl (\rightarrow {\mathrm{dod}}\bigr)^{*}\left(M\right)\) [29].

Theorem 3.2.

Let \(M \subseteq N\). Then

That is, there are more transitive time-sensitive CDs than the transitive closure of even the union of \(\rightarrow _{\mathrm{ntscd}}\) and \(\rightarrow {\mathrm{dod}}\). Now remember that Ranganath and Amtoft introduced \(\rightarrow {ntscd}\) and \(\rightarrow {\mathrm{dod}}\) to provide a sound notion of nontermination-sensitive backward slicing. Thus in the language of PDGs, \(\bigl (\rightarrow \bigr)^{*}\left(M\right)\) is just the backward slice of M, and the theorem states that the timing-sensitive backward slice of M contains the nontermination-sensitive backward slice of M.

It is worth noting that the \(\rightarrow _{\mathrm{tscd}}\) slice in Theorem 3.2 does not require a timing-sensitive analogue of the relation \(\rightarrow {\mathrm{dod}}\). As seen above, the necessity of \(\rightarrow {\mathrm{dod}}\) was motivated by an irreducible graph, such as the graph in Figure 4. But while in Figure 4 neither \(m_1\) nor \(m_2\) is nontermination sensitively control dependent on n, both \(m_1\) and \(m_2\) are timing-sensitively control dependent on n (e.g., \(n \rightarrow _{\mathrm{tscd}} m_1\), because \(m_1~\sqsubseteq _{\mathrm{TIME}}^{1}~n^{\prime }\), but \(\lnot (m_1~\sqsubseteq _{\mathrm{TIME}}^{1}~n^{\prime \prime })\), and also: \(m_1~\sqsubseteq _{\mathrm{TIME}}^{2}~n^{\prime \prime }\), but \(\lnot (m_1~\sqsubseteq _{\mathrm{TIME}}^{2}~n^{\prime })\). This \(m_1\)/\(m_2\) symmetry makes a ternary “\(\rightarrow \!\mbox{tsdod}\)” unnecessary.

3.3 Soundness and Minimality of \(\rightarrow _{\mathrm{tscd}}\)

It is our ultimate goal to discover timing leaks. We thus need a soundness proof for \(\rightarrow _{\mathrm{tscd}}\), which guarantees that \(\rightarrow _{\mathrm{tscd}}\) will indeed discover all potential timing leaks. We will further show that \(\rightarrow _{\mathrm{tscd}}\) is minimal, which means there are no spurious time-sensitive dependencies.

Any soundness proof makes assumptions about the possibilities of attackers; this is called the attacker model. To prove soundness of \(\rightarrow _{\mathrm{tscd}}\) under an attacker model, we use a technique called trace equivalence. Let us thus describe our attacker model, and then define trace equivalence. We imagine an attacker who tries to infer secret values (such as r2 in the AES example) measuring execution times for certain execution paths. But the attacker cannot observe all nodes, he can only observe certain “observable” nodes.9 The goal of security analysis is then to guarantee that secret information cannot flow to observable nodes, respectively, that execution times measured at observable nodes will not allow the attacker to infer secret values at unobservable nodes.10 Technically, for \(\rightarrow _{\mathrm{tscd}}\) this guarantee is based on trace equivalence of clocked traces.

Definition 3.5.

An (unclocked) trace t is a sequence of edges \(\left(n,n^{\prime }\right) \in ~\left(\rightarrow _G\right) \cup \left(N_x \times \lbrace \bot \rbrace \right)\) that is either finite with \(t = \left(n_e, n_1 \right)\!,~\left(n_1, n_2 \right)\!,\ldots ,~\left(n_k, n_x \right)\!,~\left(n_x, \bot \right)\) for some exit node \(n_x\in N_x\), or infinite with \(t = \left(n_e, n_1 \right)\!,~\left(n_1, n_2 \right)\!,\ldots .\) Partial edges \(\left(n,\bot \right)\) occur only at exit nodes.

Definition 3.6.

A clocked trace is a trace where every step is additionally annotated with a time stamp. We write if a trace step t has time stamp i. Given a trace \(t=\left(n_e, n_1 \right)\!,~\left(n_1, n_2 \right)\!,\ldots ,\) its clocked version is thus

Next, we assume there is a fixed set \(S\subseteq N\) of observable nodes.11

Definition 3.7.

Let \(S\subseteq N\); let a trace t be given. We define the S-observation \({ \hspace{0.0pt}t \vphantom{|} |_{S} }\) of t to be the sub-sequence of t containing only edges \(\left(n,n^{\prime }\right)\) with nS. Traces \(t_1, t_2\) are called S-equivalent if \({ \hspace{0.0pt}t_1 \vphantom{|} |_{S} }={ \hspace{0.0pt}t_2 \vphantom{|} |_{S} }\).

These definitions work for unclocked and clocked traces. S-observability means that we assume an attacker to observe exactly those choices made at nodes nS. Specifically, we assume that an attacker can observe neither the nodes in a subtrace between observable nodes, nor—for unclocked traces—the time spent between two observable nodes (i.e., the length of the subtrace between two observable nodes).

Now we consider traces caused by specific inputs. We write \(t_i\) for the (possibly infinite) trace caused by input i. As we want to abstract away from particular input formats or data objects, we use a nonstandard formalization of input: i is a map from CFG nodes to a (perhaps infinite) list of CFG successor nodes: \(i:N\rightarrow N^{*}\). An input i causes \(t_i\) as follows: If, e.g., an if node nN is visited for the kth time during the execution with input i, then the execution will continue with the kth element of \(i\left(n\right)\), which is a successor node (i.e., true or false path) of n. If n is only visited finitely often, then superfluous entries in \(i(n)\) are ignored.

This encoding has the effect that our CFGs are state-free: They contain CDs and nothing else. In particular the CFG does not contain program variables or program state—these are hidden in the i encoding. From a practical viewpoint this is, however, no restriction, and no weakening of the soundness property: We do not constrain possible i, and the soundness theorem below holds for all \(i,i^{\prime }\). Note, however, that for practical discovery of timing leaks, data dependencies are additionally needed; this is described in Section 3.4.

Next, we need the notion of S-equivalent inputs. For \(S\subseteq N\), \({ \hspace{0.0pt}i \vphantom{|} |_{S} }:S\rightarrow N^{*}\) is the restriction of the map i to nodes nS, thereby only determining the successor nodes chosen at condition nodes \(\in S\). Two inputs \(i,i^{\prime }\) are called S-equivalent, written \(i \sim _{S} i^{\prime }\), if \({ \hspace{0.0pt}i \vphantom{|} |_{S} }={ \hspace{0.0pt}i^{\prime } \vphantom{|} |_{S} }\). An attacker cannot distinguish S-equivalent inputs.

We will now explain why—in the absence of timing leaks—S-equivalent inputs demand S-equivalent traces. It is essential to consider clocked traces: Even if two unclocked traces are S-equivalent, their clocked versions may be different. This is the essence of time-sensitivity. For illustration consider Figure 6(a), with observable nodes \(S = \left\lbrace m, m_x\right\rbrace\). Regardless of the choice made at n, all inputs \(i,i^{\prime }\) starting in m have the same observable trace \[ { \hspace{0.0pt}t_i \vphantom{|} |_{S} } ~=~ \left(m, n \right),~\left(m_x, \bot \right) ~=~ { \hspace{0.0pt}t_{i^{\prime }} \vphantom{|} |_{S} }. \] Hence, \(t_i\) and \(t_{i^{\prime }}\) are always trace equivalent. Thus an attacker without clock cannot extract any secret information from observing traces. However, if equipped with a suitably precise clock, then an attacker will observe \(m_x\) after 5 steps for the input i that chooses \(n^{\prime }\) at n, but already after 3 steps for \(i^{\prime }\) that chooses \(n^{\prime \prime }\) at n, exposing a timing difference. This becomes obvious if we use the clocked versions of \(t_i\), \(t_{i^{\prime }}\), and then compare their S-observation:

Since the attacker cannot distinguish i and \(i^{\prime }\) (they only differ in the choices for the unobservable node n), this timing difference allows the attacker to gain additional information, leading to a timing leak. However, the program in Figure 6(b) has no timing leak: Even if we annotate each edge in the observable trace with its execution time, all inputs \(i,i^{\prime }\) starting in m have the same observable clocked trace

This discussion motivates the following definition of timing leaks:

Definition 3.8.

Let \(S\subseteq N\) be a set of observable (“low”) nodes. A program is free of timing leaks if for all inputs \(i,i^{\prime }\)

This definition is formally identical to classical noninterference definitions (cmp., e.g., Reference [31]) but is based on clocked traces.

To prevent a timing leak, it is necessary that all nodes that influence the timing of observable nodes \(\in S\) are observable itself. Otherwise, a secret node might influence the timing of an observable node. For example, Figure 6(a) contains—as described above—a timing leak if we assume \(S=\left\lbrace m, m_x\right\rbrace\). Indeed \(n \rightarrow _{\mathrm{tscd}} m_x\), but not nS. With \(S^{\prime }=S\cup \lbrace n\rbrace =\left\lbrace m, n, m_x\right\rbrace\), the timing leak disappears: While the timing of \(m_x\) still differs, i and \(i^{\prime }\) are now distinguishable for the attacker, so this timing difference does not give additional information.

We will now show how \(\rightarrow _{\mathrm{tscd}}\) can be used to check for timing leaks. In particular we demonstrate that for any observable \(M\subseteq S\), the time-sensitive backward slice \(B=(\rightarrow _{\mathrm{tscd}})^{*}(M)\) fulfills the condition of Definition 3.8. This implies that B is not too small, i.e., \(\rightarrow _{\mathrm{tscd}}\) is sound.

Before we state the theorem, consider what happens if B is too small. In that case, the \(\rightarrow _{\mathrm{tscd}}\) dependency would have “missing edges.” Then there could exist two inputs that agree on B, but lead to different traces: \(i \sim _{B} i^{\prime }\) but \({ \hspace{0.0pt}t_i \vphantom{\big |} |_{B} }\not= { \hspace{0.0pt}t_{i^{\prime }} \vphantom{\big |} |_{B} }\). Figure 8 presents one such example. For \(B=BS(\lbrace 6\rbrace)=\lbrace 1,6\rbrace\), we have \(i_1 \sim _{B} i_2\) and indeed . In contrast, the unsound “slice” \(B^{\prime } = \lbrace 6\rbrace\) leads to \(i_1 \sim _{B^{\prime }} i_3\) but . (Note that the only difference between the two slices is the timing of \(\left(6, \bot \right)\), so we have \({ \hspace{0.0pt}t_i \vphantom{\big |} |_{B^{\prime }} } = { \hspace{0.0pt}t_{i^{\prime }} \vphantom{\big |} |_{B^{\prime }} }\) for the unclocked traces. In fact, \(\lbrace 6\rbrace\) is a sound slice when ignoring timing and using \(\rightarrow _{\mathrm{ntscd}}\).) If, however, \(i \sim _{B} i^{\prime }\) always implies , then soundness is guaranteed.

Fig. 8.

Fig. 8. In the CFG on the left, let \( M = \lbrace 6\rbrace \) be the slicing criterion. Then \( B = BS\left(\lbrace 6\rbrace \right)=\lbrace 1,6\rbrace \) is the time-sensitive backward slice of M, because \( 1 \rightarrow _{\mathrm{tscd}} 6 \). \( B^{\prime } = \lbrace 6\rbrace \) is a slice that is too small. Right: 3 different inputs with their traces and observable behaviour regarding B and \( B^{\prime } \).

Theorem 3.3 (Soundness of \(\rightarrow _{\mathrm{tscd}}\))Let \(M \subseteq S\). Let \(B = \left(\rightarrow _{\mathrm{tscd}}\right)^{*}\left(M\right)\) be the timing-sensitive backward slice w.r.t M. Then, for any inputs \(i,i^{\prime }\) such that \(i \sim _{B} i^{\prime }\), we have

Corollary 3.1.

If \(BS(S)\subseteq S\), then Definition 3.8 holds, i.e., there is no timing leak.

As \(S\subseteq BS(S)\) always holds, the corollary’s premise is in fact \(S=BS(S)\). If the premise is not satisfied, i.e., for some \(x\in BS(S)\): \(x\not\in S\), then x—as explained above—is a timing leak.

Minimality of slicing now shows that \(B=BS\left(M\right)\) is as small as possible: Any set of nodes \(B^{\prime }\) that includes the slicing criterion M can only be secure if it is a superset of B.

Theorem 3.4 (Minimality of \(\rightarrow _{\mathrm{tscd}}\))Under the assumptions of Theorem 3.3, for any \(B^{\prime } \supseteq M\) with \(B^{\prime } \not\supseteq B\) there exist inputs \(i,i^{\prime }\) such that \(\hphantom{\lnot ~}i \sim _{B^{\prime }} i^{\prime }\), but

It should be noted that the proof for both theorems relies on the non-standard, state-free input encoding of \(i,i^{\prime }\), which was described above.

3.4 The Full Time-sensitive Backward Slice

Our nonstandard input encoding (which “factors away” all state information) is not practical for “real” programs. In such programs, time-sensitive influences through variables must be considered too. For this reason, discovery of timing leaks needs data dependencies in addition to control dependencies. Data dependencies have in fact already been used in the AES example. For completeness and better understanding, we will thus describe the full algorithm for discovering timing leaks. Note that in this article, we do not provide a modified soundness proof for the full algorithm, as it does not contribute to \(\rightarrow _{\mathrm{tscd}}\) “as such.”

We denote data dependencies by \(\rightarrow _{dd}\). \(x\rightarrow _{dd} y\) means that a variable v, which is defined (assigned) at x is used at y; provided there is a CFG path \(x\rightarrow ^{*} y\), and v is not redefined on this path [11]. We will not describe the construction of \(\rightarrow _{dd}\) in detail, but note that for full languages with functions, objects, multithreading, and so on, the computation of precise data dependencies is nontrivial and requires context-sensitive summary dependencies, precise points-to analysis, may-happen-in-parallel analysis, and much more (see, e.g., References [14, 23, 30]).

The full algorithm for discovering timing leaks then assumes \(\rightarrow _{dd}\), and proceeds as follows:

(1)

Compute \(\rightarrow _{\mathrm{tscd}}\). If \(x \rightarrow _{\mathrm{tscd}} y\), but not \(x\rightarrow _{cd}y\), then there may be a timing leak at y, but only if it can be influenced by secret data.

(2)

Using \(\rightarrow _{dd}\), the full time-sensitive backward slice is defined as \[ BS_{ts}(M)=\left(\rightarrow _{\mathrm{tscd}\cup \rightarrow _{dd}{}{}}\right)^{*}\left(M\right). \] This slice contains all CFG nodes that may influence M; other nodes that influence M cannot exist [6, 14, 18].

(3)

Now if \(x \rightarrow _{\mathrm{tscd}} y\), and \(BS_{ts}(\lbrace x\rbrace)\) contains any secret input or variables, then there is a timing leak at y: The execution time between x and y varies, depending on secret data.

This procedure is fully analogous to the slicing-based noninterference check used in JOANA (see [6, 14]; these papers include soundness proofs and other details about slicing-based IFC), but with \(\rightarrow _{\mathrm{tscd}}\) instead of \(\rightarrow _{cd}\). Note that in the current article, we consider only context-insensitive timing-dependencies (while JOANA uses context-sensitive, object-sensitive dependencies). A context-sensitive \(\rightarrow _{\mathrm{tscd}}\) is future work.

Skip 4TIMING SENSITIVITY FOR MICROARCHITECTURAL CFGS Section

4 TIMING SENSITIVITY FOR MICROARCHITECTURAL CFGS

In the abstract, we mentioned the infamous AES cache timing leaks that were discovered by Bernstein [4]. Some details of this attack were described in Section 3.1. We will now describe in more detail how such cache leaks can be discovered, respectively, prevented via time-sensitive CDs in microarchitectural CFGs. Basically, the algorithm from Section 3.4 is used, but the underlying CFG must be extended to model cache behaviour.

In the following, we describe this cache-modelling CFG extension in detail. The CFG edges are labeled with assignments and guards that refer to (cacheable) variables \(\mathtt {a,b,\ldots },\) and uncacheable registers \(\mathtt {r1,r2,\ldots }.\)

We assume a simple data cache of size four, with a least recently used eviction strategy. The (micro-architectural) cache-state hence consists of a list \(\left[x_1,x_2,x_3,x_4\right]\) of variables, with \(x_1\) being the most recently used, and \(x_4\) the next to be evicted. In Figure 9(b), we show—under an abstraction that considers cache state only—all possible executions of the control flow graph, assuming an empty initial cache. For example, the abstract node \(\left(9, \mathtt {\left[x,d,c,b\right]}\right)\) represents all those concrete configurations at control node 9 in which the concrete micro-architectural cache contains cached values for the variables \(\mathtt {\left[x,d,c,b\right]}\), in this order (with arbitrary concrete macro-architectural state).

Fig. 9.

Fig. 9. A CFG and its possible cache-aware abstract executions.

In the example, executions can reach the control node \(m=15\) at cache states represented by either \(\mathtt {\left[b,y,c,x\right]}\), or by \(\mathtt {\left[b,y,d,x\right]}\). Which of these (abstract) cache states is reached is determined by the macro-architectural choice made at \(n=9\). But it is easy to see that the execution time of the read of \(\mathtt {y}\) at node \(m=15\) does not depend on the choice made at \(n = 9\), since in both (classes of) executions that reach node \(m = 15\), the cache does contain the variable \(\mathtt {y}\), which is the only cacheable variable accessed by the edge \(15 \xrightarrow {\mathtt {r_2 := y}} 16\) at m.

For the read of variable \(\mathtt {b}\) at node \(m=14\), however, one class of executions reaches m in \(\left(14, \mathtt {\left[y,c,b,x\right]}\right)\) (containing \(\mathtt {b}\)), while another class of executions reaches m in \(\left(14, \mathtt {\left[y,d,x,c\right]}\right)\) (not containing \(\mathtt {b}\)). Whether the relevant variable \(\mathtt {b}\) is in the cache at \(m=14\) (and hence: The execution time of the read of \(\mathtt {b}\) at \(m=14\)) or not depends here on the choice made at \(n=9\).

Now consider the read of \(\mathtt {c}\) at node \(m=21\). Does its cache state depend on the choice made right before at \(n^{\prime }=16\)? There are four (abstract) cache states at \(m=21\). Two contain the variable \(\mathtt {c}\): \(\left(21, \mathtt {\left[b,y,c,x\right]}\right)\) and \(\left(21, \mathtt {\left[a,y,b,c\right]}\right)\). The other two do not contain \(\mathtt {c}\): \(\left(21, \mathtt {\left[a,y,b,d\right]}\right)\) and \(\left(21, \mathtt {\left[b,y,d,x\right]}\right)\). The cache states containing \(\mathtt {c}\) are reachable from configurations at control node \(n^{\prime } = 16\). At the same time, cache states not containing \(\mathtt {c}\) are also reachable from configurations at control node \(n^{\prime } = 16\). But in fact, whether \(\mathtt {c}\) is in cache at m does not depend on the choice made at \(n^{\prime }\). To see this, note that node \(n^{\prime } = 16\) can be reached at two different cache states. The first abstract configuration is \(\left(16, \mathtt {\left[y,b,c,x\right]}\right)\). But whenever \(m = 21\) is reached from this abstract configuration, \(\mathtt {c}\) is in the cache (either \(\left(21, \mathtt {\left[b,y,c,x\right]}\right)\) or \(\left(21, \mathtt {\left[a,y,b,c\right]}\right)\)). The second abstract configuration at which \(n^{\prime } = 16\) can be reached is \(\left(16, \mathtt {\left[y,b,d,x\right]}\right)\). But whenever \(m = 21\) is reached from that configuration, \(\mathtt {c}\) is not in the cache (\(\left(21, \mathtt {\left[a,y,b,d\right]}\right)\) or \(\left(21, \mathtt {\left[b,y,d,x\right]}\right)\)).

However, the cache status of \(\mathtt {c}\) at node \(m=21\) does depend on the choice made earlier at \(n=9\). In this example, this is necessarily so, since the node \(n=9\) is the only other macro-architectural conditional node in the control flow graph. But this is also directly evident by the structure of the graph in Figure 9(b).

Note that through a a small modification of the program, the cache status of \(\mathtt {c}\) at \(m=21\) could have been independent from the choice made earlier at \(n=9\). For example, had there been reads to two additional variables (e.g., \(\mathtt {e,f}\)) right before \(m = 21\), then all cache states at m would \({not}\) have contained \(\mathtt {c}\). This is because these two reads would have evicted \(\mathtt {c}\) even from \(\mathtt {\left[b,y,c,x\right]}\) (and \(\mathtt {\left[a,y,b,c\right]}\)).

In summary, the choice made at \(n=9\) does influence the relevant (micro-architectural) cache state at \(m \in \left\lbrace 21, 14\right\rbrace\). In fact, for this micro-architecture, these are the only micro-architectural dependencies in this CFG. The example indicates how a CFG G can be transformed into a cache-aware version. We will not present the formal definitions here (see Reference [16]) but just present the transformed CFG for the above example.

Figure 10 shows the micro-architectural-aware CFG \(G^{\prime }\) for Figure 9; together with an explicit timing cost model \(C^{\prime }\). A cache-miss is assumed to take 10 units of time, while a cache-hit takes 2 units.12 At node 14, the read from \(\mathtt {b}\) takes either 2 or 10 units of time, since \(\mathtt {b}\) there might either be in the cache, or not. 13 Hence in \(G^{\prime }\), node 14 has two artificial successors: The read from \(\mathtt {b}\) takes either 2 or 10 units of time, since \(\mathtt {b}\) there might either be in the cache, or not. However, node 15 still has only one successor, reached with timing cost \(3 = 2 + 1\) (cache access plus register access), since we found that there the variable \(\mathtt {y}\) is always in cache.

Fig. 10.

Fig. 10. Micro-Architecture Aware \( \mathrm{CFG} \) \( G^{\prime } \) for Figure 9.

In \(G^{\prime }\), we now have (as desired) that node 21 is in the backward slice of the exit node 3. Formally, \[ 21 \in \left(\rightarrow _{\mathrm{tscd}}^{G^{\prime }\left[C^{\prime }\right]} \right)^{*}\left(\lbrace 3\rbrace \right)\!. \] Together with the microarchitectural dependence from node 9 to node 21, we conclude that the decision at node 9 may influence the execution time of node 3.

Note that even if G is deterministic, \(G^{\prime }\) usually is not. This is no problem, because we can still use the micro-architectural dependencies \(\rightarrow _{\mu \hspace{-1.00006pt}\mathrm{d}}^{G}\) (and data dependencies \(\rightarrow _{dd}\)) from the original graph G, and only use \(G^{\prime }\) for timing-sensitive control dependence \(\rightarrow _{\mathrm{tscd}}^{G^{\prime }\left[C^{\prime }\right]}\).

For the AES code, the cache-sensitive graph \(G^{\prime }\) has been shown in Section 3.1, and we already described how cache leaks in AES have been discovered through time-sensitive backward slicing. More details can be found in Reference [16].

Skip 5ALGORITHMS Section

5 ALGORITHMS

Our algorithms are based on the fundamental insight that Cytron’s original algorithm for dominance frontiers can be generalized to CFGs with loops and multiple exit nodes and even to the computation of time-sensitive CD. We consider this “generic” algorithm our major contribution: Without it, the new \(\rightarrow _{\mathrm{tscd}}\) definition would be worthless in practice; and even Ranganath’s and Amtoft’s \(\rightarrow _{\mathrm{ntscd}}\)/\(\rightarrow _{\mathrm{nticd}}\) are more efficient to compute using the new algorithms.

5.1 New Algorithms for \(\sqsubseteq _{\mathrm{MAX}}\) and \(\sqsubseteq _{\mathrm{SINK}}\)

Let us begin with new algorithms for \(\rightarrow _{\mathrm{ntscd}}\) and \(\rightarrow _{\mathrm{nticd}}\). These will—in generalization of Cytron’s approach—be constructed as postdominance frontiers of \(\sqsubseteq _{\mathrm{MAX}}\) and \(\sqsubseteq _{\mathrm{SINK}}\). The efficient implementation of \(\sqsubseteq _{\mathrm{MAX}}\) and \(\sqsubseteq _{\mathrm{SINK}}\) needs some technical machinery, namely transitive reductions and pseudo-forests.

Both \(\sqsubseteq _{\mathrm{MAX}}\) and \(\sqsubseteq _{\mathrm{SINK}}\) will always be represented by their transitive reductions; allowing efficient construction algorithms. A transitive reduction \(\lt\) of a transitive relation \(\sqsubseteq\) is a minimal subset \(\lt\) of \(\sqsubseteq\) such that \((\lt)^{*}~=~ \sqsubseteq\). Thus \(\lt\) has a minimal number of edges but the same transitive closure as \(\sqsubseteq\). Efficient algorithms for transitive reductions have long been known [2]. But remember that \(\sqsubseteq _{\mathrm{MAX}}\) and \(\sqsubseteq _{\mathrm{SINK}}\) may contain cycles (i.e., are not antisymmetric), in contrast to the classical \(\sqsubseteq _{\mathrm{POST}}\). Hence their transitive reductions may also contain cycles. Therefore the transitive reductions of \(\sqsubseteq _{\mathrm{MAX}}\) and \(\sqsubseteq _{\mathrm{SINK}}\) are not forests (i.e., sets of trees) as for \(\sqsubseteq _{\mathrm{POST}}\), but so-called pseudo-forests.

Definition 5.1.

A pseudo-forest is a relation \(\lt\) such that for every node nN, \(m \lt n\) for at most one node m.

Thus, in a pseudo-forest every node has at most one parent node, but in contrast to ordinary forests, pseudo-forests may contain cycles. Summarizing this discussion, we obtain

Observation 5.1.

1. Both \(\sqsubseteq _{\mathrm{MAX}}\) and \(\sqsubseteq _{\mathrm{SINK}}\) are reflexive and transitive but not necessarily anti-symmetric.

2. Any transitive, reflexive reduction \({\lt }_{\mathrm{MAX}}\) of \(\sqsubseteq _{\mathrm{MAX}}\) is a pseudo-forest.

3. Any transitive, reflexive reduction \({\lt }_{\mathrm{SINK}}\) of \(\sqsubseteq _{\mathrm{SINK}}\) is a pseudo-forest.

Figure 11(b) shows a reduction \({\lt }_{\mathrm{MAX}}\) of \(\sqsubseteq _{\mathrm{MAX}}\) for the CFG in Figure 11(a). This pseudo-forest has five trees, with roots 1, 2, 3, \(\left\lbrace 6,7,8\right\rbrace\) and 10.14 Node 9 does not \(\sqsubseteq _{\mathrm{MAX}}\)-postdominate node 3, because the loop at 3 may not terminate. However, node 9 does \(\sqsubseteq _{\mathrm{SINK}}\)-postdominate node 3: a path looping forever at 3 is not a sink path, and any sink path starting at 3 must eventually reach the trivial sink at node 10.

Fig. 11.

Fig. 11. Nontermination-sensitive Postdominance.

We will now present new algorithms to compute \(\sqsubseteq _{\mathrm{MAX}}\) and \(\sqsubseteq _{\mathrm{SINK}}\). The representation of both \(\sqsubseteq _{\mathrm{MAX}}\) and \(\sqsubseteq _{\mathrm{SINK}}\) by pseudo-forests is crucial, as pseudo-forests admit efficient algorithms for their computation. Based on pseudo-forests, our algorithm for \(\sqsubseteq _{\mathrm{MAX}}\) is a standard fixpoint iteration. Beginning with the empty pseudo-forest, new edges are added to \({\lt }_{\mathrm{MAX}}\) according to Theorem 2.1 until a fixpoint is reached. Since \(\sqsubseteq _{\mathrm{MAX}}\) is efficiently represented by a pseudo-forest \({\lt }_{\mathrm{MAX}}\), it is straightforward to derive an efficient algorithm for the computation of \(\sqsubseteq _{\mathrm{MAX}}\), see Algorithm 2. In addition, we need an efficient implementation of set-intersection in the representation \(\lt\), i.e., a least common ancestor algorithm \(\mathrm{lca}_{\lt }\) for pseudo-forests; see Algorithm 1.

Algorithm 1 calculates the least common ancestor of \(n_0\) and \(m_0\) by alternately extending \(\lt\)-paths from \(n_0\) and \(m_0\) one by one. If the newly added node is already contained in the other path, then it is returned as the result of lca\((n_0, m_0)\): Since this is the first time the two paths overlap, this node is not only a common ancestor but also the least one. If one path cannot be extended (because its IMDOM is \(\bot\) or starts to contain a cycle), then only the other path is extended (procedure lin). When the other path cannot be extended anymore either, we do not have an lca, so we return \(\bot\).

Algorithm 2 works in two phases: First, we establish trivial IMDOM relations for nodes with only one successor. For the graph in Figure 12 (left), these would be IMDOM[5] = 7, IMDOM[7] = 8, IMDOM[8] = 9, and IMDOM[9] = 8.

Fig. 12.

Fig. 12. Two example CFGs.

Next, we calculate IMDOM for conditional nodes (nodes with more than one successor). We keep a queue of such nodes for which IMDOM has not been calculated. For each conditional node x, we try to calculate the lca of their successors. If this returns a node a \(\ne \bot\), then we set IMDOM[x] = a and remove x from the worklist; otherwise, it is put back at the end. The algorithm terminates once the worklist is empty or we have completed a full iteration through the worklist without a change to IMDOM. The variable oldest tracks the first node after the last change; once we visit it again, we are done.

In the case of the graph in Figure 12 (left), assume we iterate in order \({\scriptstyle \mathrm{COND}}_{G} =\\)[1, 2, 3, 4], which becomes our first workqueue. For x = 1, we calculate lca({2, 3, 4}). Let us suppose we try to calculate lca(2, 3) \(=\) lca([2], [3]) first. Since IMDOM[2] = \(\bot\), we immediately call lin[[2]]([3]), but since IMDOM[3] = \(\bot\) as well, we return \(\bot\) as lca(2, 3). But then lca({2, 3, 4}) = \(\bot\) as well. 1 is therefore put back into the queue, so we now have workqueue = [2, 3, 4, 1] and oldest = 1. For x = 2, when calculating lca(6, 7), we have IMDOM[6] = \(\bot\), so we immediately call lin[[6]]([7]). During the recursion in lin, we extend [7] to [7, 8] and [7, 8, 9] (since no new node is in [6]). The next step would be IMDOM[9] = 8. Since 8 \(\in\) [7, 8, 9] (which would lead to a loop), we return \(\bot\). 2 is therefore put back into the queue, so we now have workqueue = [3, 4, 1, 2] and oldest = 1. For x = 3, when calculating lca(5, 7), we have IMDOM[5] = 7 and 7 \(\in\) [7], so we return 7 as our lca. Since we have an lca, we update IMDOM[3] = 7, keep 3 out of the workqueue (so workqueue = [4, 1, 2]) and set oldest = \(\bot\). For x = 4, when calculating lca(9, 5), we extend both paths alternately until the path starting in 9 would enter a loop, then only the path starting in 5 is extended. Then we will find that 8 is our lca, since it is in both paths. In detail, lca([9], [5]) = lca([5], [9, 8]) = lca([9, 8], [5, 7]) = lin[[9, 8]]([5, 7]) = lin[[9, 8]]([5, 7, 8]) = 8. We update IMDOM[4] = 8, keep 4 out of the workqueue (so workqueue = [1, 2]) and keep oldest = \(\bot\). Now we are back to x = 1. When calculating lca(2, 3), we now have IMDOM[3] = 7, so we can extend [3] until we get [3, 7, 8, 9]. But still, no node is contained in [2], so we still have \(\bot\) as our lca. We put 1 back into the workqueue (so workqueue = [2, 1]) and set oldest = 1. After finding for x = 2 that lca(6, 7)\(= \bot\), we put 2 back into the workqueue (so workqueue = [1, 2]) and keep oldest = 1. But now our next element in the queue is our oldest, so we are done.

The computation of \(\sqsubseteq _{\mathrm{SINK}}\) is slightly more complicated. As it is a greatest fixpoint, in principle we must start with \(N\times N\) and reduce it according to the rules; until the greatest fixpoint is reached. But \(N\times N\) cannot be represented by a pseudo-forest. Hence we need to initialize the fixed point iteration with an approximation \(\sqsubseteq _0\) of \(\sqsubseteq _{\mathrm{SINK}}\) (i.e., \(\sqsubseteq _0 \ \supseteq \ \sqsubseteq _{\mathrm{SINK}}\)) that is representable by a pseudo-forest \(\lt _0\).

We can build \(\lt _0\) by interleaving a traversal of a preliminary pseudo forest \(\lt\) with \(\mathrm{lca}_{\lt }\) computations. Consider the preliminary \(\lt\) in Figure 13(b). We need to establish \(3\lt 1\), but find that \(\mathrm{lca}_{\lt }\left(\left\lbrace 2,3\right\rbrace \right) = \bot\) for the successors of 1. We would like to assume both \(3\lt 1\) and \(2\lt 1\), the latter of which would then be invalidated in the (downward) fixed point iteration. But then \(\lt\) no longer would be a pseudo forest. If we assumed just \(2\lt 1\), then we would obtain a \(\lt _0\) such that not: \(\lt _{0}^{*} ~\supseteq ~ \sqsubseteq _{\mathrm{SINK}}\), so we need to make the assumption \(3\lt 1\). This example illustrates how the fixpoint iteration must proceed. It is based on the following:

Fig. 13.

Fig. 13. Computing an initial approximation \( \lt _0 \).

Observation 5.2.

Let \({\lt }_{\mathrm{SINK}}\) be a transitive reduction of \(\sqsubseteq _{\mathrm{SINK}}\). Then whenever \(x {\lt }_{\mathrm{SINK}} y\) and any path starting in x is bound for a sink S (such S is necessarily unique), then any path starting in y is bound for S as well.

Here, “bound for S” means that the path cannot escape sink S. To illustrate the iteration for \(\sqsubseteq _{\mathrm{SINK}}\), consider Figure 13(b). For node 3 we have already established \(4 \lt ^{*} 3\) for the sink node \(4 \in S\), but we have not yet established \(4 \lt ^{*} 2\). This suggests that we must—whenever \(\mathrm{lca}_{\lt }\left(\lbrace \,y \; \vert \; x \rightarrow _{\hspace{1.42271pt}} y\,\rbrace \right) = \bot\)—choose some successor node y of x such that already \(s \lt ^{*} y\) for some sink node s. We call such nodes y processed, and maintain a set \(\mathsf {PROCD}\) of all such nodes. Algorithm 3 presents the computation of \({\lt }_{\mathrm{SINK}}\), the additional procedures performing the iteration are given in Figure 14.

Fig. 14.

Fig. 14. Upward and downward iteration for Algorithm 3.

Algorithm 3 first initializes ISDOM for sink nodes and nodes with one successor. Remember that any nontrivial sink \(S_i\) contains a \({\lt }_{\mathrm{SINK}}\) -cycle. For each sink \(S_i\), we therefore initialize ISDOM to be such a cycle in arbitrary order. We also choose a representative \(s_i\) for each sink \(S_i\) and mark all nodes in \(S_i\) as processed. For all nodes outside sinks with one successor, the initialization of ISDOM is identical to the one in Algorithm 2. Once a successor is processed, we mark all nodes that reach this node through ISDOM-chains as processed.

Next, we construct in \(SINK_{up}\) a preliminary ISDOM that fulfills ISDOM\(^{*} ~\supseteq ~ \sqsubseteq _{\mathrm{SINK}}\) but might be too optimistic: For nodes x, ISDOM[x] might exist even though it should be \(\bot\); or it might be a node that is too small to be a common ancestor of the successors of x (but the correct lca is an ancestor of ISDOM[x]). We choose such an ISDOM of x as soon as one of its successors is processed. When calculating the lca, we only consider the successors that have already been processed. If the resulting lca is \(\bot\), then we choose an arbitrary successor as lca. Now, we set ISDOM[x] to be this lca. We also set x and all nodes that reach x through ISDOM-chains as processed. This succeeds for any x with distance k to a sink at attempt k at the latest (this can be shown by induction on k), so this algorithm terminates.

Then, these spurious postdominances are eliminated during \(SINK_{down}\). For each conditional node x outside sinks the lca of its successors is calculated. If it is part of a sink \(S_i\), then its distinguished representative \(s_i\) is chosen instead. If it is different from the current ISDOM (either a different node or \(\bot\)), then ISDOM is updated and all nodes possibly affected by this change are put back in the worklist: These are all conditional nodes n having a successor y that reaches x through ISDOM-chains. This is done until the worklist is empty.

As an example, consider Figure 12 (left). In the initial phase, we set ISDOM[8] = 9 and ISDOM[9] = 8 for the non-trivial sink. For its representative, let us assume we choose 8. We mark all sink nodes 6, 8, and 9 as processed. Then, we handle non-condition nodes. We set ISDOM[4] = 9 and mark 4 as processed. After that, we set ISDOM[5] = 7 (but cannot mark it as processed, since 7 is not). Finally, we set ISDOM[7] = 8 and mark both 7 and 5 as processed.

In \(SINK_{up}\), 1 has a single processed successor, namely 4. Thus ISDOM[1] = 4, and 1 is processed. For 2, we have two processed successors, but lca(6,7) = \(\bot\). Let us suppose we choose ISDOM[2] = 7; 2 is also marked as processed. Finally, 3 has two processed successors and lca(5,7) = 7, so we set ISDOM[3] = 7 and mark 3 as processed. This finishes \(SINK_{up}\).

In \(SINK_{down}\), we first check x = 1. Since we still have ISDOM[2] = 7, lca({2,3,4}) = 8. This is also the representative of this sink, so we set ISDOM[1] = 8. For x = 2, we now find that ISDOM[2] = \(\bot\). This change puts 1 back into the worklist. For x = 3, no change occurs, since lca(5,7) = ISDOM[3] = 7. For x = 4, we have lca(9) = 9. The representative of this sink is 8, so we set ISDOM[4] = 8. We would also have to put 1 back into the worklist if it was not there already. For x = 1, the updated ISDOM[2] now means we find lca({2,3,4}) = \(\bot\), so we set ISDOM[2] = \(\bot\). This finishes the calculation of ISDOM.

5.2 Postdominance Frontiers in Graphs without Unique Exit

We will now derive algorithms for \(\rightarrow _{\mathrm{ntscd}}\) and \(\rightarrow _{\mathrm{nticd}}\), based on \(\sqsubseteq _{\mathrm{MAX}}\) and \(\sqsubseteq _{\mathrm{SINK}}\). In particular, we generalize Cytron’s idea to split up the postdominance frontier into an “up” and a “local” part, and to follow the tree structure (parent links) while iterating. The latter also works for pseudo-forests.

To describe this idea in detail, first remember that in graphs with unique exit node \(n_x\), standard postdominance \(\sqsubseteq _{\mathrm{POST}}\) is always a partial order, while in arbitrary graphs, \(\sqsubseteq _{\mathrm{MAX}}\) and \(\sqsubseteq _{\mathrm{SINK}}\) may lack anti-symmetry, and may thus contain cycles of nodes postdominating each other. In the following we therefore reconstruct Cytron’s algorithm with our generalized definition for postdominance frontiers. In particular, the following definitions replace Cytron’s definitions from Reference [10]: Instead of Cytron’s original \(\sqsubset _{\mathrm{POST}}\), we use our new \(~\textrm {1-}{\sqsubseteq }~\), and instead of Cytron’s original \(\mathrm{ipdom}_{\sqsubseteq _{\mathrm{POST}}}\), we use \(\mathrm{ipdom}_\sqsubseteq\). We will thus be able to define the generalized algorithm in a self-contained way.

Definition 5.2

(Immediate \(\sqsubseteq\)-Postdominance)

Given a binary relation \(\sqsubseteq\) on nodes, a node x is said to \(~\textrm {1-}{\sqsubseteq }\textrm {-postdominate}~\) z if there exists some node \(y\ne x\) such that \(x \sqsubseteq y \sqsubseteq z\). The set \(\mathrm{ipdom}_{\sqsubseteq }\left(n\right)\) is defined by \[ \mathrm{ipdom}_{\sqsubseteq }\left(n\right) = \left\lbrace m~\middle | \begin{array}{l@{}} \hphantom{\forall m^{\prime } \in N.~} m\ ~\textrm {1-}{\sqsubseteq }~n \\ \forall m^{\prime } \in N.~ m^{\prime }~\textrm {1-}{\sqsubseteq }~n \ \Rightarrow \ m^{\prime } \sqsubseteq m \\ \end{array} \right\rbrace . \]

In contrast to strict postdominance, \(x~\textrm {1-}{\sqsubseteq }~x\) might hold, namely if there is a cycle \(x \sqsubseteq y \sqsubseteq x\) for \(x\ne y\). \(\mathrm{ipdom}_{\sqsubseteq }\left(x\right)\) is the set of immediate postdominators: It contains the postdominators of x that all (other) postdominators of x postdominate.

As an example, consider the CFG in Figure 12 (left) with \(\sqsubseteq _{\mathrm{MAX}}\)-postdominance. We have \(\mathrm{ipdom}_{\sqsubseteq }\left(5\right)=\lbrace 7\rbrace\), since \(7~\textrm {1-}{\sqsubseteq }~5\) and each \(~\textrm {1-}{\sqsubseteq }~\)-postdominator of 5 also postdominates 7. \(8\notin \mathrm{ipdom}_{\sqsubseteq }\left(5\right)\), because \(7~\textrm {1-}{\sqsubseteq }~5\) but not \(7 \sqsubseteq 8\). For the cycle of 8 and 9, each of those \(~\textrm {1-}{\sqsubseteq }~\)-postdominates itself and the other one, so we have \(\mathrm{ipdom}_{\sqsubseteq }\left(8\right)=\mathrm{ipdom}_{\sqsubseteq }\left(9\right)=\lbrace 8,9\rbrace\).

Next we need a generalized notion of Cytron’s postdominance frontiers. Intuitively, the postdominance frontier contains all nodes that are one step away from having x as a postdominator.

Definition 5.3

(\(\sqsubseteq\)-Postdominance Frontiers)

\[ {\rm {pdf}}_{\sqsubseteq }\left(x\right) = \left\lbrace y~\middle | \begin{array}{r@{}} \lnot ~ x~\textrm {1-}{\sqsubseteq }~y \\ \text{for some}~s~\text{s.t.}~y \rightarrow _{\hspace{1.42271pt}} s: \quad x \sqsubseteq s \\ \end{array} \right\rbrace . \]

Consider again Figure 12 (left) with \(\sqsubseteq _{\mathrm{MAX}}\)-postdominance. We have \({\rm {pdf}}_{\sqsubseteq }\left(5\right)=\lbrace 3,4\rbrace\), since 5 neither postdominates 3 or 4, but postdominates a successor of those nodes (namely 5 itself). \(1\notin {\rm {pdf}}_{\sqsubseteq }\left(5\right)\), since 5 postdominates no successor of 1. For the node 7 we have \({\rm {pdf}}_{\sqsubseteq }\left(7\right)=\lbrace 1,2,4\rbrace\). Note that \(3\notin {\rm {pdf}}_{\sqsubseteq }\left(7\right)\), since 7 postdominates 3.

The following lemma generalizes Cytron’s insight that CD is essentially the same as postdominance frontiers:

Lemma 5.1.

For \(n\not=m\), we have \[ n \rightarrow _{\mathrm{ntscd}} m ~\iff ~ n \in {\rm {pdf}}_{\sqsubseteq _{\mathrm{MAX}}}\left(m\right) \] and \[ n \rightarrow _{\mathrm{nticd}} m ~\iff ~ n \in {\rm {pdf}}_{\sqsubseteq _{\mathrm{SINK}}}\left(m\right)\!. \]

Due to this lemma, we easily obtain \(\rightarrow _{\mathrm{ntscd}}\) and \(\rightarrow _{\mathrm{nticd}}\) once we have an algorithm for \({\rm {pdf}}_{\sqsubseteq }\). For the latter, we—following Cytron—partition \({\rm {pdf}}_{\sqsubseteq }\left(x\right)\) into two parts: those y contributed locally, and those y contributed by nodes z, which are immediately \(\sqsubseteq\)-postdominated by x (implying \(x \sqsubseteq z\)). Informally, the local part \({\rm {pdf}}^{\mathrm{local}}_{\sqsubseteq }\left(x\right)\) of \({\rm {pdf}}_{\sqsubseteq }\left(x\right)\) comprises all nodes from which one can get to x in one step, but which do not have x as a postdominator. However, if \(y\in {\rm {pdf}}_{\sqsubseteq }\left(z\right)\) and \(\mathrm{ipdom}_{\sqsubseteq }\left(z\right)\) is not the join point of all of y’s branching, then y is in the “upper” part \({\rm {pdf}}^{\mathrm{up}}_{\sqsubseteq }\left(z\right)\). This is formalized in

Definition 5.4

(\(\sqsubseteq\)-Postdominance Frontiers: localanduppart)

\[ {\rm {pdf}}^{\mathrm{local}}_{\sqsubseteq }\left(x\right) = \left\lbrace y~\middle | \lnot ~ x~\textrm {1-}{\sqsubseteq }~y,~ y \rightarrow _{\hspace{1.42271pt}} x \right\rbrace \] \[ {\rm {pdf}}^{\mathrm{up}}_{\sqsubseteq }\left(z\right) = \left\lbrace y \in {\rm {pdf}}_{\sqsubseteq }\left(z\right) ~\middle | \begin{array}{r@{}} \forall x \in \mathrm{ipdom}_{\sqsubseteq }\left(z\right).~ \lnot ~ x~\textrm {1-}{\sqsubseteq }~y \\ \end{array} \right\rbrace . \]

Under suitable conditions, \({\rm {pdf}}^{\mathrm{up}}_{\sqsubseteq }\) and \({\rm {pdf}}^{\mathrm{local}}_{\sqsubseteq }\) indeed partition \({\rm {pdf}}_{\sqsubseteq }\). This is made precise in the following

Observation 5.3.

Let \(\sqsubseteq\) be transitive and reflexive. Also, identify \(\mathrm{ipdom}_{\sqsubseteq }\) with the relation \(\left\lbrace \left(x, z\right) \;\middle |\; x \in \mathrm{ipdom}_{\sqsubseteq }\left(z\right) \right\rbrace\), and assume \(\mathrm{ipdom}_{\sqsubseteq }^{*}~=~\sqsubseteq\). Then \[ {\rm {pdf}}_{\sqsubseteq }\left(x\right) = {\rm {pdf}}^{\mathrm{local}}_{\sqsubseteq }\left(x\right) \quad \cup \quad \bigcup _{\left\lbrace z \;\middle |\; x \in \mathrm{ipdom}_{\sqsubseteq }\left(z\right) \right\rbrace } {\rm {pdf}}^{\mathrm{up}}_{\sqsubseteq }\left(z\right). \]

Fortunately, \(\sqsubseteq _{\mathrm{MAX}}\) and \(\sqsubseteq _{\mathrm{SINK}}\) are reflexive and transitive (but, as explained, not antisymmetric); thus the partitioning can be applied. For an example, consider again Figure 12 (left) with \(\sqsubseteq _{\mathrm{MAX}}\)-postdominance. We have \({\rm {pdf}}^{\mathrm{local}}_{\sqsubseteq }\left(5\right)=\lbrace 3,4\rbrace\). Since 5 only postdominates itself trivially, we have \(5\in \mathrm{ipdom}_{\sqsubseteq }\left(z\right)\) for no node z, and Observation 5.3 indeed gives \({\rm {pdf}}_{\sqsubseteq }\left(5\right)=\lbrace 3,4\rbrace\). We have \({\rm {pdf}}^{\mathrm{local}}_{\sqsubseteq }\left(7\right)=\lbrace 2\rbrace\). Since we have \(\left\lbrace z \;\middle |\; 7 \in \mathrm{ipdom}_{\sqsubseteq }\left(z\right) \right\rbrace =\lbrace 3,5\rbrace\), we need to calculate \({\rm {pdf}}^{\mathrm{up}}_{\sqsubseteq }\left(3\right)\) and \({\rm {pdf}}^{\mathrm{up}}_{\sqsubseteq }\left(5\right)\). For 5, we have already seen \({\rm {pdf}}_{\sqsubseteq }\left(5\right)=\lbrace 3,4\rbrace\). But \({\rm {pdf}}^{\mathrm{up}}_{\sqsubseteq }\left(5\right)\) contains only node 4, since 7 actually postdominates 3! Since \({\rm {pdf}}^{\mathrm{up}}_{\sqsubseteq }\left(3\right)=\lbrace 1\rbrace\), Observation 5.3 results in \({\rm {pdf}}_{\sqsubseteq }\left(7\right)=\lbrace 1,2,4\rbrace\), as expected.

The next definition provides properties that will enable a fixpoint computation of \({\rm {pdf}}^{\mathrm{local}}_{\sqsubseteq }\left(x\right)\) and \({\rm {pdf}}^{\mathrm{up}}_{\sqsubseteq }\left(z\right)\).

Definition 5.5.

\(\sqsubseteq\) is closed under \(\rightarrow _{\hspace{1.42271pt}}\), if it admits the rules

\(\sqsubseteq\) lacks joins if it admits the rules

Informally, the premise of the last rule is “split” at s (into v and z), and joined at x. The conclusion demands that this cannot happen unless v and z are immediate neighbours.

Lemma 5.2.

Both \(\sqsubseteq _{\mathrm{MAX}}\) and \(\sqsubseteq _{\mathrm{SINK}}\) are closed under \(\rightarrow\), and lack joins.

As promised, the following theorems provide, under the “lacks join” assumption for \(\sqsubseteq\), simplified formulae for \({\rm {pdf}}^{\mathrm{local}}_{\sqsubseteq }\left(x\right)\) and \({\rm {pdf}}^{\mathrm{up}}_{\sqsubseteq }\left(z\right)\).

Observation 5.4.

Let \(\sqsubseteq\) be transitive, and closed under \(\rightarrow _{\hspace{1.42271pt}}\). Then \[ {\rm {pdf}}^{\mathrm{local}}_{\sqsubseteq }\left(x\right) = \left\lbrace y~\middle | \lnot ~ x \in \mathrm{ipdom}_{\sqsubseteq }\left(y\right),~ y \rightarrow _{\hspace{1.42271pt}} x \right\rbrace . \]

Observation 5.5.

Let \(\sqsubseteq\) be transitive, reflexive, lacking joins, and closed under \(\rightarrow _{\hspace{1.42271pt}}\). Also assume \(\mathrm{ipdom}_{\sqsubseteq }^{*}\,=\,\sqsubseteq\). Then, given some z with \(x \in \mathrm{ipdom}_{\sqsubseteq }\left(z\right)\) \[ {\rm {pdf}}^{\mathrm{up}}_{\sqsubseteq }\left(z\right) = \left\lbrace y \in {\rm {pdf}}_{\sqsubseteq }\left(z\right) ~\middle | \begin{array}{r@{}} \lnot ~ x \in \mathrm{ipdom}_{\sqsubseteq }\left(y\right) \end{array} \right\rbrace . \]

As both \(\sqsubseteq _{\mathrm{MAX}}\) and \(\sqsubseteq _{\mathrm{SINK}}\) satisfy the assumptions of the last theorems, these theorems immediately lead to an efficient rule system for computing \({\rm {pdf}}_{\sqsubseteq }\left(x\right)\). The first rule initializes \({\rm {pdf}}_{\sqsubseteq }\left(x\right)\) to its “local” part; the second rule applies the formula for the “upper” part, until a fixpoint is reached. Of course, \(\mathrm{ipdom}_{\sqsubseteq }\) must be computed beforehand.

Definition 5.6.

The monotone rule system for computing \({\rm {pdf}}_{\sqsubseteq }\left(x\right)\) is given by

The smallest fixpoint of this rule system can be computed by a standard worklist algorithm. Additionally, we can exploit transitive reductions. Given any transitive reduction \(\lt\) of \(\sqsubseteq\),

(1)

compute the strongly connected components \(\mathsf {sccs}\) of the graph \(\left(N, \lt \right)\), in a corresponding topological order. These can either be provided by the algorithm computing \(\lt\), or by Tarjan’s algorithm [32].

(2)

compute \({\rm {pdf}}_{\sqsubseteq }\) by traversing the condensed graph in that order once.

This concludes the algorithm for generalized postdominance frontiers \({\rm {pdf}}_{\sqsubseteq }\left(x\right)\); and thus for \(\rightarrow _{\mathrm{ntscd}}\) and \(\rightarrow _{\mathrm{nticd}}\). For the actual computation, we propose the following optimization: By precomputing the set \(\mathsf {scc}_{\lt } = \lbrace \,y \; \vert \; \exists x^{\prime }\in \mathsf {scc}.\ x^{\prime }\lt y\,\rbrace\) for each \(\mathsf {scc}\), we can use this for both the tests on y, and for enumerating z.

To illustrate the fixpoint iteration for \({\rm {pdf}}_{\sqsubseteq }\left(x\right)\), consider once more the CFG in Figure 12 (left). The “local” rule gives us, e.g., \(1\in {\rm {pdf}}_{\sqsubseteq }\left(3\right)\), \(3\in {\rm {pdf}}_{\sqsubseteq }\left(5\right)\), \(4\in {\rm {pdf}}_{\sqsubseteq }\left(5\right)\) and \(2\in {\rm {pdf}}_{\sqsubseteq }\left(7\right)\). With the “up” rule we can now get \(4\in {\rm {pdf}}_{\sqsubseteq }\left(7\right)\) by instantiating the rule with \(x=7\), \(y=4\) and \(z=5\). Note that we indeed have shown \(4\in {\rm {pdf}}_{\sqsubseteq }\left(5\right)\) earlier and we have \(7\notin \mathrm{ipdom}_{\sqsubseteq }\left(4\right)\) as well as \(7\in \mathrm{ipdom}_{\sqsubseteq }\left(5\right)\). In contrast, if we try to use \(3\in {\rm {pdf}}_{\sqsubseteq }\left(5\right)\) to show \(3\in {\rm {pdf}}_{\sqsubseteq }\left(7\right)\) (which is false), then \(7\notin \mathrm{ipdom}_{\sqsubseteq }\left(3\right)\) would have to hold. But \(7\in \mathrm{ipdom}_{\sqsubseteq }\left(3\right)\), so the right rule is not applicable, and we are prevented from showing \(3\in {\rm {pdf}}_{\sqsubseteq }\left(7\right)\).

5.3 Timing-sensitive Postdominance Frontiers

To develop efficient algorithms for the computation of timing-sensitive postdominance \(\sqsubseteq _{\mathrm{TIME}}\) and timing-sensitive control-dependence \(\rightarrow _{\mathrm{tscd}}\), let us first recall that our algorithms for \(\sqsubseteq _{\mathrm{MAX}}\) and \(\rightarrow {ntscd}\) rely on the fact that \(\sqsubseteq _{\mathrm{MAX}}\) is transitive:

(1)

Transitivity of \(\sqsubseteq _{\mathrm{MAX}}\) allows us to efficiently compute and represent \(\sqsubseteq _{\mathrm{MAX}}\) in form of its transitive reduction \({\lt }_{\mathrm{MAX}}\). Here, \({\lt }_{\mathrm{MAX}}\) turned out to be a pseudo-forest.

(2)

Transitivity of \(\sqsubseteq _{\mathrm{MAX}}\), and the fact that \[ \mathrm{ipdom}^{*}_{\sqsubseteq _{\mathrm{MAX}}} ~=~\sqsubseteq _{\mathrm{MAX}} \] allows us to use Algorithm 4 to efficiently compute \(\rightarrow _{\mathrm{ntscd}}\) via \({\rm {pdf}}_{\sqsubseteq _{\mathrm{MAX}}}\).

Disregarding for now that \(\rightarrow _{\mathrm{tscd}}\) is defined in terms of the ternary relation \(n~\sqsubseteq _{\mathrm{TIME}}^{k}~m\), and not in terms of its binary “\(\exists k.~\)-closure” \(n~\sqsubseteq _{\mathrm{TIME}}~m\), let us investigate first if \(n~\sqsubseteq _{\mathrm{TIME}}~m\) is—in general—transitive. Consider the (irreducible) \(\mathrm{CFG}\) in Figure 15(a). Here, every maximal path starting in n first reaches \(m_1\) after two steps, hence \(m_1~\sqsubseteq _{\mathrm{TIME}}~n\). Also, every maximal path starting in \(m_1\) first reaches \(m_2\) after one step, hence \(m_2~\sqsubseteq _{\mathrm{TIME}}~m_1\). But it is for no number k of steps the case that \(m_2~\sqsubseteq _{\mathrm{TIME}}^{k}~n\); hence, \(\lnot ~ m_1~\sqsubseteq _{\mathrm{TIME}}~n\). In summary, \(\sqsubseteq _{\mathrm{TIME}}\) is not transitive.

Fig. 15.

Fig. 15. An irreducible graph with intransitive \( ~\sqsubseteq _{\mathrm{TIME}}~\!. \)

Fortunately, situations as in Figure 15 are the only ones in which \(\sqsubseteq _{\mathrm{TIME}}\) is not transitive:

Theorem 5.1.

Let G be any reducible \(\mathrm{CFG}\). Then \(\sqsubseteq _{\mathrm{TIME}}\) is transitive.

Theorem 5.2.

Let G be any \(\mathrm{CFG}\) with unique exit node \(n_x\). Then \(\sqsubseteq _{\mathrm{TIME}}\) is transitive.

In practice, many programs have reducible CFGs or a unique exit; then \(\sqsubseteq _{\mathrm{TIME}}\) is transitive by the above two theorems. Whenever \(\sqsubseteq _{\mathrm{TIME}}\) is transitive, we can use Algorithm 4 to compute \(\rightarrow _{\mathrm{tscd}}\). And if not, then in Reference [16] we present an algorithm for \(\rightarrow _{\mathrm{tscd}}\) that works even if \(\sqsubseteq _{\mathrm{TIME}}\) is not transitive. But it is much more complex and thus not described in this article. Note that even our transitive “restriction” is more general than the restriction to structured CFGs that is often required in literature on timing leaks, such as in, e.g., References [1, 17, 28].

Still, even under the \(\sqsubseteq _{\mathrm{TIME}}\) transitivity assumption, we are not done. Compared to the above \(\sqsubseteq _{\mathrm{MAX}}\) algorithm, we must deal with the ternary \(n~\sqsubseteq _{\mathrm{TIME}}^{k}~m\) instead of the binary \(\sqsubseteq _{\mathrm{MAX}}\). To this end, remember that for \(m \ne n\), \[ n \in {\rm {pdf}}_{\sqsubseteq _{\mathrm{MAX}}}\left(m\right) ~\Leftrightarrow ~ n \rightarrow _{\mathrm{ntscd}} m. \]

To obtain the analogous result for \(\rightarrow _{\mathrm{tscd}}\), we first need to “conservatively” redefine the notion \({\rm {pdf}}_{\sqsubseteq }\) of \(\sqsubseteq\)-postdominance to obtain a notion appropriate for non-transitive relations \(\sqsubseteq\). Remember that in Definition 5.3, we defined for any binary relation \(\sqsubseteq\): \[ {\rm {pdf}}_{\sqsubseteq }\left(m\right) = \left\lbrace n~\middle | \begin{array}{r@{}} \lnot ~ m~\textrm {1-}{\sqsubseteq }~n \\ \text{for some}~n^{\prime }~\text{s.t.}~n \rightarrow _{G\hspace{1.42271pt}} n^{\prime }: \quad m \sqsubseteq n^{\prime } \\ \end{array} \right\rbrace . \]

Syntactically, we will stick with this definition, but will modify the notion of 1-\(\sqsubseteq\)-postdominance. The new definition is

Definition 5.7

(1-\(\sqsubseteq\)-Postdominance, redefinition)

Given a relation \(\sqsubseteq \quad \subseteq \ N \times N\), a node xN is said to \(~\textrm {1-}{\sqsubseteq }\textrm {-postdominate}~\) z if \(x \sqsubseteq z\) and there exists some node \(y\ne x\) such that \[ x \sqsubseteq y \sqsubseteq z. \]

The only change is the new requirement \(x \sqsubseteq z\) , which of course was redundant up to this section, since any relation \(\sqsubseteq\) we considered (i.e., \(\sqsubseteq _{\mathrm{POST}}\), \(\sqsubseteq _{\mathrm{MAX}}\), and \(\sqsubseteq _{\mathrm{SINK}}\)) was transitive. Implicitly, this change also affects immediate \(\sqsubseteq\)-postdominance \(\mathrm{ipdom}_{\sqsubseteq }\)—see Definition 5.2.

Theorem 5.3.

Let \(n \ne m\in N\). Then \[ n \in {\rm {pdf}}_{\sqsubseteq _{\mathrm{TIME}}}\left(m\right) ~\Leftrightarrow ~ n \rightarrow _{\mathrm{tscd}} m. \]

Theorem 5.3 holds for arbitrary graphs, and establishes that indeed, timing-sensitive postdominance frontiers are essentially timing-sensitive control dependence.

But to use the generalized postdominance frontiers algorithm from Section 5.2 at least for transitive \(\sqsubseteq _{\mathrm{TIME}}\), we also need the two other two requirements of that algorithm. These two do, indeed, hold even for arbitrary graphs:

Observation 5.6.

Let \(\sqsubseteq ~=~ \sqsubseteq _{\mathrm{TIME}}\). Then \(\sqsubseteq\) is closed under \(\rightarrow _{G\hspace{1.42271pt}}\), and \[ {\rm {pdf}}^{\mathrm{local}}_{\sqsubseteq }\left(x\right) = \left\lbrace y~\middle | \begin{array}{r@{}} \lnot ~ x \in \mathrm{ipdom}_{\sqsubseteq }\left(y\right) \\ y \rightarrow _{\hspace{1.42271pt}} x \\ \end{array} \right\rbrace . \]

Observation 5.7.

Let \(\sqsubseteq ~=~ \sqsubseteq _{\mathrm{TIME}}\). Then \(\sqsubseteq\) lacks joins and is closed under \(\rightarrow _{G\hspace{1.42271pt}}\), and given some z with \(x \in \mathrm{ipdom}_{\sqsubseteq }\left(z\right)\): \[ {\rm {pdf}}^{\mathrm{up}}_{\sqsubseteq }\left(z, x\right) = \left\lbrace y \in {\rm {pdf}}_{\sqsubseteq }\left(z\right) ~\middle | \begin{array}{r@{}} \lnot ~ x \in \mathrm{ipdom}_{\sqsubseteq }\left(y\right) \end{array} \right\rbrace . \]

All that is required now is an algorithm to compute \(\sqsubseteq _{\mathrm{TIME}}\). For graphs that are reducible, or have a unique exit node, this can be done by modifying Algorithm 3 to work on \(\mathbb {N}\)-labeled pseudo-forests, i.e., pseudo forests \(\lt\) with edges \(n \lt ^k m\) indicating that m must first be reached from n after \(k \in \mathbb {N}\) steps. The result is a \(\mathbb {N}\)-labeled pseudo-forest \(\lt\) with \[ m~\sqsubseteq _{\mathrm{TIME}}~n ~\iff ~ \exists k_1,\ldots ,k_c. ~m \lt ^{k_c} \cdots \lt ^{k_1} n \] for some number \(c \ge 0\) of edges in \(\lt\). One possible implementation of the required least common ancestor computation in \(\mathbb {N}\)-labeled pseudo-forests is shown in Algorithm 5.

For an example, consider Figure 12 (right). Before the first call to lca, IDOM contains only trivial relations for nodes with exactly one successor, e.g., IDOM\([4]=(8,1)\). To calculate IDOM\([2]\), we need to call lca with its successors, namely lca\(((3,1),\ (6,1))\). But there, we find that IDOM\([3]\) is still empty, so the call returns \(\bot\).

When calculating IDOM\([3]\), we call lca\(((4,1),\ (5,1))\). We find that IDOM\([4]=(8,1)\), so we extend this \(\lt\)-path and call lca\(([(4,1),(8,2)],\ (5,1))\). There, since the left path is now longer, we swap the arguments and call lca\(((5,1),\ [(4,1),(8,2)])\). Now, we find that IDOM\([5]=(8,1)\), so we extend this path and call lca\(([(5,1),(8,2)],\ [(4,1),(8,2)])\). Now, since the final element of the left path, namely 8, is also contained in the right one with the same distance of 2, we finally can return \((8,2)\) as the lca and update IDOM\([3]=(8,2)\).

Now we can analyse IDOM\([2]\) again. Since IDOM\([3]\) has now an entry, we can extend the path \((3,1)\) to \([(3,1), (8,3)]\). After extending \((6,1)\) to \([(6,1), (7,2)]\) and then \([(6,1), (7,2), (8,3)]\), both paths contain 8 with the same distance 3, so we update IDOM\([3]\) to \((8,3)\).

On the contrary, if we try to calculate IDOM\([1]\) and call lca\(((2,1),\ (9,1))\), then the left path get extended to \([(2,1),(8,4)]\) and the right path to \([(9,1),(10,2),(2,3)]\). Now, both paths contain the same node 2, but with different distances 1 and 3. Therefore, the lca is \(\bot\).

Skip 6MEASUREMENTS Section

6 MEASUREMENTS

We evaluated the performance of our algorithms on (a) control flow graphs of Java methods, as generated by the JOANA system for various third party Java programs; (b) randomly generated graphs \(G = \left(N, E\right)\) usually with \(\left|{E}\right| = 2 \left|{N}\right|\), as generated by the standard generator from the JGraphT [26] library. In some cases, we additionally use ladder graphs,15 which are used to represent bad case behaviour.

All benchmarks in this section were made on a desktop computer with an Intel i7-6700 CPU at 3.40 GHz, and 64 GB RAM. We implemented the algorithms in Java, using OpenJDK Java 9 VM. All benchmarks were run using the Java Microbenchmark Harness JMH [9].

Unless explicitly stated otherwise, all data points represent the average over \(n+1\) runs of the benchmark, where n is at least the number of runs that can be finished within 1 s. For example, the data point at \(\left|{N}\right| = 21,\!076\), time \(= 18\) ms in Figure 16(a) stands for the average of at least \(\approx\)50 runs of the benchmark that finished within 1 s. However, the data point in at \(\left|{N}\right| = 65,\!000\), time \(= 88\)s in Figure 16(c) results from only one run of the benchmark.

Fig. 16.

Fig. 16. Computation of \( {\lt }_{\mathrm{MAX}} \). The orange line shows chaotic iteration performance, the blue line shows Algorithm 2.

The purpose of these benchmarks is to give a general idea of the scalability of the algorithms. For example, the benchmarks in the upper left and upper right of Figure 17 suggest that our new algorithm for the computation of nontermination-sensitive control dependence \(\rightarrow _{\mathrm{ntscd}}\) appears to scale almost linearly for “average” CFGs, while Ranganath’s original algorithm [29] clearly grows super-linearly for such graphs. The benchmarks can be summarized as follows:

Fig. 17.

Fig. 17. Computation of \( \rightarrow {ntscd} \).

(1)

For “average” CFGs, our algorithms for \(\rightarrow _{\mathrm{ntscd}}\), \(\rightarrow _{\mathrm{nticd}}\), and \(\rightarrow _{\mathrm{tscd}}\) offer performance “almost linear” in the size of the graph.

(2)

But for “bad case” CFGs, some algorithms perform decidedly super-linear, and become impractical for very large such graphs.

6.1 Nontermination Sensitive Postdominance

Algorithm 2 computes maximal path postdominance \(\sqsubseteq _{\mathrm{MAX}}\), represented as a pseudo-forest \({\lt }_{\mathrm{MAX}}\). This algorithm requires the computation of least common ancestors \(\mathrm{lca}_{\lt }\) in pseudo-forests \(\lt\), for which we use Algorithm 1.

Algorithm 2 repeatedly iterates in a fixed node order. Alternatively, one can implement a chaotic iteration, by reinserting into a workset those nodes affected by modification to the pseudo-forest. Both these variants do not specify an iteration order (e.g., Algorithm 2 does not specify the initial order of nodes in the workqueue). By default, the implementation orders the nodes reversed-topologically (as computed by an implementation of Kosaraju’s Algorithm for strongly connected components, with nodes in the same strongly connected component ordered arbitrarily).

For Java CFG and randomly generated graphs (neither necessarily with unique exit node), the chaotic iteration () and Algorithm 2 () behave similarly (Figure 16(a) and Figure 16(b)). Ladder graphs expose non-linear bad-case behavior (Figure 16(c)). This is even more pronounced when we deliberately choose a bad iteration order (Figure 16(d)).

6.2 Nontermination Insensitive Postdominance

Algorithm 3 computes sink path postdominance \(\sqsubseteq _{\mathrm{SINK}}\), represented as a pseudo-forest \({\lt }_{\mathrm{SINK}}\). Just as before, it uses Algorithm 1 for the computation of least common ancestors \(\mathrm{lca}_{\lt }\).

Algorithm 3 implements chaotic iteration. We also implemented a variant of Algorithm 3 in which the downward fixed point phase repeatedly iterates a workqueue of nodes in a fixed node order. The implementations order the nodes reversed-topologically. Unlike before, this ordering does not require an additional step, since the strongly connected component computation it can be obtained from is necessary anyway, in order to find control sinks.

Instead of computing least common ancestors \(\mathrm{lca}_{\lt }\) by chasing (pseudo-tree) pointers, it can also be computed by comparison of postorder numbers, as in Reference [8].

For Java CFGs (Figure 18(a)) the fixed-iteration order variant of Algorithm 3 () performs on par with the Algorithm 3 as stated (). For randomly generated graphs (Figure 18(b)) the variant () appears to perform a bit better than the original () for very large graphs, roughly on-par with the implementation based on postorder numbers ().

Fig. 18.

Fig. 18. Computation of \( {\lt }_{\mathrm{SINK}} \).

Using reversed-topological iteration order, ladder graphs (Figure 18(c)) expose non-linear bad-case behavior only for Algorithm 3 () and its variant (). Even with a bad iteration order, performance for these two algorithm is not much worse (Figure 18(d)). However, the postorder number based implementation () is affected heavily by iteration order.

The ladder graphs we use are unique-exit-node ladder graphs. This also allows us to directly compare with an implementation of the algorithm by Lengauer and Tarjan [24] ().

6.3 Generalized Postdominance Frontiers

When Algorithm 4 is instantiated with \({\lt }_{\mathrm{MAX}}\), this yields an algorithm for \(\rightarrow _{\mathrm{ntscd}}\). The benchmarks for \(\rightarrow _{\mathrm{ntscd}}\) include the computation time of both Algorithm 4 and \({\lt }_{\mathrm{MAX}}\) (). We compare with an implementation of Ranganath’s algorithm [29] (). For Java CFG and randomly generated graphs, the latter becomes impractical for moderately sized graphs, while Algorithm 4 performs well even for very large graphs (Figure 17, upper left and right). Ladder graphs expose non-linear bad-case behavior even for Algorithm 4 (Figure 17(c)). This cannot be circumvented, since in these ladder graphs, the size of the relation \(\rightarrow _{\mathrm{ntscd}}\) is quadratic in the number of nodes. Likewise, Algorithm 4 can be instantiated with \(\lt _{SINK}\). Performance of the resulting \({\rightarrow }_{nticd}\) is shown in Figure 19.

Fig. 19.

Fig. 19. Computation of \( \rightarrow _{\mathrm{nticd}} \) via Algorithm 4 based on Algorithm 3.

6.4 Timing-sensitive CD

Whenever \(~\sqsubseteq _{\mathrm{TIME}}~\) is transitive, we can use Algorithm 4 to compute timing-sensitive control dependence \(\rightarrow _{\mathrm{tscd}}\). We thus measure the computation time for \(\rightarrow _{\mathrm{tscd}}\) on graphs for which \(~\sqsubseteq _{\mathrm{TIME}}~\) is transitive. These are control flow graphs from Java programs in subfigures 20(a), randomly generated graphs 20(b), and ladder graphs (c). We use Algorithm 4, and obtain a transitive reduction \(\lt _{\mathrm{TIME}}\) of \(\sqsubseteq _{\mathrm{TIME}}\) via the modification of Algorithm 3 that uses the upwards iteration of Algorithm 5. The benchmarks for \(\rightarrow _{\mathrm{tscd}}\) in Figure 20 include the computation time of all sub-algorithms (). Ladder graphs expose non-linear bad-case behavior.

Fig. 20.

Fig. 20. Computation of \( \rightarrow {tscd} \).

Skip 7FUTURE WORK Section

7 FUTURE WORK

This article concentrated on the definition of \(\rightarrow _{\mathrm{tscd}}\) and on efficient algorithms. Ongoing work includes

  • provide Isabelle proofs for the last 7 “observations” in Section 5.

  • provide formal correctness proofs for the algorithms in Section 5.

  • implement and evaluate the \(\rightarrow _{\mathrm{tscd}}\) algorithm that can handle nontransitive \(~\sqsubseteq _{\mathrm{TIME}}~\), which was mentioned in Section 5.3.

  • provide a theoretical complexity analysis of the algorithms, and more measurements.

  • transform out timing leaks as in [1], but for arbitrary CFGs (based on \(\rightarrow _{\mathrm{tscd}}\)).

  • apply \(\rightarrow _{\mathrm{tscd}}\) to improve IFC and probabilistic noninterference; in particular improve precision of the so-called “RLSOD” algorithm [6, 7, 12] that is used in JOANA.

Initial work on some of these topics can be found in the first author’s dissertation [16]. A long-time goal is an interprocedural, context-sensitive extension of \(\rightarrow _{\mathrm{tscd}}\).

Skip 8CONCLUSION Section

8 CONCLUSION

Ranganath and Amtoft opened the door to control dependencies in nonterminating programs. Inspired by this work, we presented (1) new, efficient algorithms for Ranganath’s nontermination-(in)sensitive control dependencies; (2) definitions and algorithms for time-sensitive control dependencies; and (3) application of the latter to timing leaks in software security. Our algorithms are based on systematic generalizations of Cytron’s postdominance frontier algorithm. Important properties of the new algorithms have been proven using the Isabelle machine prover; and their performance has been studied. We believe that time-sensitive control dependencies will prove useful for many applications in program analysis, code optimization, and software security.

Skip Acknowledgments Section

Acknowledgments

Preliminary versions of parts of this article have been published in the first author’s dissertation [16].

Footnotes

  1. 1 We thank one reviewer for suggesting this example.

    Footnote
  2. 2 All examples and measurements in this article are based on CFGs that were produced using the JOANA system. JOANA is a system for IFC and can in particular check probabilistic noninterference for full Java with arbitrary threads [6, 13, 14].

    Footnote
  3. 3 In a strongly connected component (SCC) S, there is a path between all \(x,y\in S\). Every cycle is an SCC.

    Footnote
  4. 4 Lemmas and Theorems marked with have been formalized and proved in the machine prover Isabelle. The proof explanations and scripts can be found in the electronic appendix of this article.

    Footnote
  5. 5 We mention in passing that for graphs with unique exit node, replacing this condition with \(n \ne \mathit {exit}\) results in a similar rule system \(\mathsf {P}_{}\) on which the algorithm from Reference [8] is based. We will not describe \(\mathsf {P}_{}\) in detail but note that \(\sqsubseteq _{\mathrm{POST}}= \nu \mathsf {P}_{}\) [15].

    Footnote
  6. 6 A CFG is reducible if the forward edges form a directed acyclic graph, and in any backedge \(m\rightarrow n\), n dominates m. Structured programs have reducible CFGs; wild gotos typically lead to irreducible CFGs.

    Footnote
  7. 7 This implementation was presented in Reference [4]. It assumes that all accesses to the sbox array need constant time. But in fact access time is cache dependent.

    Footnote
  8. 8 Besides CDs, data dependencies are important for security analysis. This is described in Section 3.4. For the current AES example, the reader may assume all data dependencies are available as necessary.

    Footnote
  9. 9 These observable nodes are called “low” nodes in the literature on software security analysis (see, e.g., Reference [31]).

    Footnote
  10. 10 This kind of security analysis is called IFC, and is based on the technical notion of noninterference. We will describe technical details on the application of \(\rightarrow _{\mathrm{tscd}}\) for IFC in a separate article; here we present only the AES example and do not discuss technical details of noninterference.

    Footnote
  11. 11 The assumption of a fixed, static S, and batchlike execution is standard in IFC and noninterference. It can be generalised and made more realistic in various ways; which, however, is not a topic of this article. Likewise, technical details of noninterference will not be discussed in this article.

    Footnote
  12. 12 memory writes are assumed to always take 2 units of times, and register accesses take 1 unit of time.

    Footnote
  13. 13 In the timing cost model C, the cost \(11 = 10 + 1\) that stems from one uncached variable access plus one register access is split into two edges. We need to do this, because in our notion of graphs, there can be no multi-edges, and we require cost models C to be strictly positive.

    Footnote
  14. 14 In the figure, downarrows \(n\rightarrow m\) mean that \(m\lt n\).

    Footnote
  15. 15 Ladder graphs consist of two rising chains, one-to-one connected at every node. Just like a ladder.

    Footnote

REFERENCES

  1. [1] Agat Johan. 2000. Transforming out timing leaks. In Proceedings of the 27th ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages (POPL’00). ACM, New York, NY, 4053. https://doi.org/10.1145/325694.325702Google ScholarGoogle ScholarDigital LibraryDigital Library
  2. [2] Aho A. V., Garey M. R., and Ullman J. D.. 1972. The transitive reduction of a directed graph. SIAM J. Comput. 1 (2) (1972), 131137.Google ScholarGoogle ScholarDigital LibraryDigital Library
  3. [3] Amtoft Torben. 2008. Slicing for modern program structures: A theory for eliminating irrelevant loops. Inf. Process. Lett. 106, 2 (2008), 4551. https://doi.org/10.1016/j.ipl.2007.10.002Google ScholarGoogle ScholarDigital LibraryDigital Library
  4. [4] Bernstein Daniel J.. 2005. Cache-Timing Attacks on AES. Technical Report.Google ScholarGoogle Scholar
  5. [5] Binkley David W., Ceccato Mariano, Harman Mark, Ricca Filippo, and Tonella Paolo. 2006. Tool-Supported Refactoring of Existing Object-Oriented Code into Aspects. IEEE Trans. Softw. Eng. 32, 9 (2006), 698717.Google ScholarGoogle ScholarDigital LibraryDigital Library
  6. [6] Bischof Simon, Breitner Joachim, Graf Jürgen, Hecker Martin, Mohr Martin, and Snelting Gregor. 2018. Low-deterministic security for low-nondeterministic programs. J. Comput. Secur. 26, 3 (2018), 335366. https://doi.org/10.3233/JCS-17984Google ScholarGoogle ScholarDigital LibraryDigital Library
  7. [7] Breitner Joachim, Graf Jürgen, Hecker Martin, Mohr Martin, and Snelting Gregor. 2016. On improvements of low-deterministic security. In Principles of Security and Trust, Lecture Notes in Computer Science, Vol. 9635. Springer, Berlin, 6888. https://doi.org/10.1007/978-3-662-49635-0_4Google ScholarGoogle ScholarCross RefCross Ref
  8. [8] Cooper Keith D., Harvey Timothy J., and Kennedy Ken. 2001. A Simple, Fast Dominance Algorithm. Technical Report. Rice University.Google ScholarGoogle Scholar
  9. [9] Corporation Oracle. 2020. Code Tools: jmh. Retrieved from https://github.com/AlDanial/cloc.Google ScholarGoogle Scholar
  10. [10] Cytron Ron, Ferrante Jeanne, Rosen Barry K., Wegman Mark N., and Zadeck F. Kenneth. 1991. Efficiently computing static single assignment form and the control dependence graph. ACM Trans. Program. Lang. Syst. 13, 4 (Oct. 1991), 451490. https://doi.org/10.1145/115372.115320Google ScholarGoogle ScholarDigital LibraryDigital Library
  11. [11] Ferrante Jeanne, Ottenstein Karl J., and Warren Joe D.. 1987. The program dependence graph and its use in optimization. ACM Trans. Program. Lang. Syst. 9, 3 (Jul. 1987), 319349. https://doi.org/10.1145/24039.24041Google ScholarGoogle ScholarDigital LibraryDigital Library
  12. [12] Giffhorn Dennis and Snelting Gregor. 2015. A new algorithm for low-deterministic security. Int. J. Inf. Secur. 14, 3 (Apr. 2015), 263287.Google ScholarGoogle ScholarDigital LibraryDigital Library
  13. [13] Graf Jürgen, Hecker Martin, Mohr Martin, and Snelting Gregor. 2016. Tool demonstration: JOANA. In Principles of Security and Trust, Lecture Notes in Computer Science, Vol. 9635. Springer Berlin Heidelberg, 8993.Google ScholarGoogle ScholarCross RefCross Ref
  14. [14] Hammer Christian and Snelting Gregor. 2009. Flow-sensitive, context-sensitive, and object-sensitive information flow control based on program dependence graphs. Int. J. Inf. Secur. 8, 6 (01 Dec. 2009), 399422. https://doi.org/10.1007/s10207-009-0086-1Google ScholarGoogle ScholarDigital LibraryDigital Library
  15. [15] Hecht Matthew S. and Ullman Jeffrey D.. 1973. Analysis of a simple algorithm for global data flow problems. In Proceedings of the 1st Annual ACM SIGACT-SIGPLAN Symposium on Principles of Programming Languages (POPL’73). ACM, New York, NY, 207217. https://doi.org/10.1145/512927.512946Google ScholarGoogle ScholarDigital LibraryDigital Library
  16. [16] Hecker Martin. 2020. Timing Sensitive Dependency Analysis and its Application to Software Security. Ph.D. Dissertation. Karlsruher Institut für Technologie, Fakultät für Informatik.Google ScholarGoogle Scholar
  17. [17] Hedin Daniel and Sands David. 2005. Timing aware information flow security for a JavaCard-like bytecode. Electron. Notes Theor. Comput. Sci. 141, 1 (2005), 163182.Google ScholarGoogle ScholarDigital LibraryDigital Library
  18. [18] Horwitz Susan, Prins Jan, and Reps Thomas W.. 1988. On the Adequacy of Program Dependence Graphs for Representing Programs. In Proceedings of the Annual ACM SIGACT-SIGPLAN Symposium on Principles of Programming Languages (POPL’88). 146157.Google ScholarGoogle ScholarDigital LibraryDigital Library
  19. [19] Horwitz Susan, Reps Thomas, and Binkley David. 1990. Interprocedural slicing using dependence graphs. ACM Trans. Program. Lang. Syst. 12, 1 (Jan. 1990), 2660. https://doi.org/10.1145/77606.77608Google ScholarGoogle ScholarDigital LibraryDigital Library
  20. [20] Jones Neil, Gomard Carsten, and Sestoft Peter. 1993. Partial Evaluation and Automatic Program Generation. Prentice Hall.Google ScholarGoogle ScholarDigital LibraryDigital Library
  21. [21] Kashyap Vineeth, Wiedermann Ben, and Hardekopf Ben. 2011. Timing- and termination-sensitive secure information flow: Exploring a new approach. In Proceedings of the 32nd IEEE Symposium on Security and Privacy. 413428.Google ScholarGoogle ScholarDigital LibraryDigital Library
  22. [22] Kocher Paul, Genkin Daniel, Gruss Daniel, Haas Werner, Hamburg Mike, Lipp Moritz, Mangard Stefan, Prescher Thomas, Schwarz Michael, and Yarom Yuval. 2018. Spectre attacks: Exploiting speculative execution. arxiv:1801.01203. Retrieved from http://arxiv.org/abs/1801.01203.Google ScholarGoogle Scholar
  23. [23] Krinke Jens. 2003. Context-sensitive slicing of concurrent programs. In Proceedings of the Symposium on the Foundations of Software Engineering (FSE’03). ACM, 178187.Google ScholarGoogle ScholarDigital LibraryDigital Library
  24. [24] Lengauer Thomas and Tarjan Robert Endre. 1979. A fast algorithm for finding dominators in a flowgraph. ACM Trans. Program. Lang. Syst. 1, 1 (Jan. 1979), 121141.Google ScholarGoogle ScholarDigital LibraryDigital Library
  25. [25] Muchnik Steven. 1997. Advanced Compiler Design and Implementation. Morgan Kaufmann.Google ScholarGoogle Scholar
  26. [26] Naveh Barak and Popinet Stephane. 2003–2019. JGraphT: A Java Library of Graph Theory Data Structures and Algorithms. Retrieved from https://jgrapht.org/.Google ScholarGoogle Scholar
  27. [27] Podgurski A. and Clarke L. A.. 1990. A formal model of program dependences and its implications for software testing, debugging, and maintenance. IEEE Trans. Softw. Eng. 16, 9 (Sep. 1990), 965979.Google ScholarGoogle ScholarDigital LibraryDigital Library
  28. [28] Rafnsson Willard, Jia Limin, and Bauer Lujo. 2017. Timing-sensitive noninterference through composition. In Principles of Security and Trust,Lecture Notes in Computer Science, Maffei Matteo and Ryan Mark (Eds.), Vol. 10204. Springer, 325.Google ScholarGoogle Scholar
  29. [29] Ranganath Venkatesh Prasad, Amtoft Torben, Banerjee Anindya, Hatcliff John, and Dwyer Matthew B.. 2007. A new foundation for control dependence and slicing for modern program structures. ACM Trans. Program. Lang. Syst. 29, 5, Article 27 (Aug. 2007), 27–es. https://doi.org/10.1145/1275497.1275502Google ScholarGoogle ScholarDigital LibraryDigital Library
  30. [30] Reps Thomas, Horwitz Susan, Sagiv Mooly, and Rosay Genevieve. 1994. Speeding up slicing. In Proceedings of the Symposium on the Foundations of Software Engineering (FSE’94). ACM, New York, NY, 1120.Google ScholarGoogle ScholarDigital LibraryDigital Library
  31. [31] Sabelfeld Andrei and Sands David. 2000. Probabilistic Noninterference for Multi-Threaded Programs. In Proceedings of the 13th IEEE Computer Security Foundations Workshop (CSFW’00). 200214.Google ScholarGoogle ScholarDigital LibraryDigital Library
  32. [32] Tarjan Robert. 1972. Depth-First Search and Linear Graph Algorithms. SIAM J. Comput. 1, 2 (1972), 146160.Google ScholarGoogle ScholarDigital LibraryDigital Library
  33. [33] Wolfe Michael Joseph. 1995. High Performance Compilers for Parallel Computing. Addison-Wesley Longman Publishing Co., Inc., Boston, MA.Google ScholarGoogle ScholarDigital LibraryDigital Library

Index Terms

  1. On Time-sensitive Control Dependencies

        Recommendations

        Comments

        Login options

        Check if you have access through your login credentials or your institution to get full access on this article.

        Sign in

        Full Access

        • Published in

          cover image ACM Transactions on Programming Languages and Systems
          ACM Transactions on Programming Languages and Systems  Volume 44, Issue 1
          March 2022
          279 pages
          ISSN:0164-0925
          EISSN:1558-4593
          DOI:10.1145/3492457
          Issue’s Table of Contents

          Permission to make digital or hard copies of all or part of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation on the first page. Copyrights for components of this work owned by others than ACM must be honored. Abstracting with credit is permitted. To copy otherwise, or republish, to post on servers or to redistribute to lists, requires prior specific permission and/or a fee. Request permissions from [email protected].

          Publisher

          Association for Computing Machinery

          New York, NY, United States

          Publication History

          • Published: 9 December 2021
          • Revised: 1 August 2021
          • Accepted: 1 August 2021
          • Received: 1 July 2020
          Published in toplas Volume 44, Issue 1

          Permissions

          Request permissions about this article.

          Request Permissions

          Check for updates

          Qualifiers

          • research-article
          • Refereed
        • Article Metrics

          • Downloads (Last 12 months)378
          • Downloads (Last 6 weeks)23

          Other Metrics

        PDF Format

        View or Download as a PDF file.

        PDF

        eReader

        View online with eReader.

        eReader

        HTML Format

        View this article in HTML Format .

        View HTML Format
        About Cookies On This Site

        We use cookies to ensure that we give you the best experience on our website.

        Learn more

        Got it!