Reconciling noninterference and gradual typing Full Version with Definitions and Proofs

Arthur Azevedo de Amorim Matt Fredrikson Limin Jia Carnegie Mellon University Carnegie Mellon University Carnegie Mellon University Abstract let f x = One of the standard correctness criteria for gradual typing is let b (* : Bool *) = true in the dynamic gradual guarantee, which ensures that loosening let y = ref b in type annotations in a program does not affect its behavior in let z = ref b in arbitrary ways. Though natural, prior work has pointed out if x then y := false else (); that the guarantee does not hold of any gradual if !y then z := false else (); !z for information-flow control. Toro et al.’s GSLRef language, for example, had to abandon it to validate noninterference. We show that we can solve this conflict by avoiding a fea- f (true) ture of prior proposals: type-guided classification, or the use of type ascription to classify data. Gradual languages require Figure 1. Prototypical failure of the DGG due to NSU checks. run-time secrecy labels to enforce security dynamically; if The program throws an error when run, but successfully type ascription merely checks these labels without modifying terminates if we uncomment the type annotation Bool. them (that is, without classifying data), it cannot violate the dynamic gradual guarantee. We demonstrate this idea with for more than basic . It had to be abandoned in a GLIO, a gradual type system based on the LIO library that gradual variant of System F to enforce parametricity [33],1 enforces both the gradual guarantee and noninterference, and in the GSLRef language [32] to enforce noninterference. featuring higher-order functions, general references, coarse- Sadly, the guarantee does not hold in any existing gradual grained information-flow control, security and language for information-flow control (IFC)32 [ ]. first-class labels. We give the language a domain-theoretic The goal of this paper is to remedy the situation for IFClan- semantics, using Pitts’ framework of relational structures to guages without giving up on noninterference. The difficulty, prove noninterference and the dynamic gradual guarantee. we argue, stems from what we call type-guided classification: CCS Concepts: • Security and privacy → Information the ability to classify values through static type annotations. flow control;• Software and its engineering → Seman- This issue is illustrated in Figure 1, which shows a program in info info tics. 휆 [4], a typical language for dynamic IFC. Values in 휆 carry a confidentiality label that is checked and propagated Keywords: Gradual Typing, Noninterference during execution to prevent information leaks. Unannotated values such as true are marked with a default label (in 휆info, 1 Introduction Public), which can be overridden with < >. For example, the Gradual type systems allow incomplete type annotations for function f is given a Secret argument. combining the safety of static typing with the flexibility of For now, ignore the commented type (* ... *). If we dynamic languages. In the gradual 휆-calculus of Siek and ran this program in a typical language with no IFC checks, it Taha [26], for example, we can declare the argument of a would have the effect of leaking the secret input x through function 푓 as an integer but omit its return type. This causes the reference z, returning true when x = true and false the type checker to reject an expression such as 푓 (true) while when x = false. Dynamic IFC prevents this breach with accepting 푓 (0) + 1, understanding that the latter will trig- a discipline known as no-sensitive-upgrade (NSU) [4, 5, 30], ger a run-time error if 푓 (0) returns a string. Many language which forbids updates to public references when the control features have been adapted to gradual typing, including ref- flow is influenced by secrets. In f, the reference y is implicitly erences [28], polymorphism [2, 16, 20, 33], among others. labeled public because it is allocated in a public context and Unlike other approaches that mix static and dynamic typ- initialized with a public variable. This causes the NSU check ing, ascribing types in a gradual language should barely to fail and terminate execution. info affect a program’s behavior, a property known asthe dy- An extension of 휆 with gradual types could allow us namic gradual guarantee (DGG) [27]: the program might be to annotate b with the type in comments, declaring it as a rejected by the type checker or encounter more cast errors, secret boolean. What would this declaration mean? Current but its output should not change from 0 to 1. Albeit natural, 1Recent work has managed to lift this restriction using ideas similar to this isolation can be challenging for languages that strive ours [20]; cf. Section 7. Arthur Azevedo de Amorim, Matt Fredrikson, and Limin Jia

let b : Bool = true in labelOf b == S gradual IFC languages (GSLRef [32], ML-GS [11], etc.) inter- pret it as classification, thus setting b’s dynamic secrecy label let b : Bool

= true in labelOf b == S to S. This causes the program to terminate successfully: b’s let b = true in labelOf b == S label is propagated to y and z, the program accepts the two assignments (because x has the same secrecy as the refer- Figure 2. Failure of the DGG with first-class labels and type- ences), and returns true. Unfortunately, this behavior guided classification. The first two programs have no reason violates the DGG, because dynamic errors are not allowed to fail, and with type-guided classification they terminate to disappear when we provide type annotations. successfully with different results. The DGG would force the This scenario suggests two possibilities for repairing the third program must behave the same way as the first two, DGG: dropping the NSU discipline in favor of type-guided which is impossible. classification, or vice versa. The first option is problematic because it is hard to find other ways of enforcing noninter- ference. One possibility would be to modify the semantics of conditionals so that they raise the secrecy of all refer- annotations might need to be checked manually. We still ences that could be updated in either branch [24]. In Fig- need to investigate if GLIO could be embedded in Haskell ure 1, this would mean raising y’s label above x’s even when like LIO, but a standalone implementation should pose no the else branch is taken. Apart from the potential perfor- challenges. mance impact, implementing this solution in any realistic An important characteristic of gradual type systems is language would require a rich analysis to compute write how much support they provide for transitioning legacy sets, which would likely push us further towards a static programs to richer type disciplines. The literature on gradual type system. And even if we decided that this was worth it, IFC offers different answers to this question; ML-GS[11], for keeping type-guided classification would be problematic for example, requires references to be given an explicit secrecy another popular feature of IFC: first-class labels. label, and thus does not directly apply to legacy programs, Labels are first class if they can be manipulated program- while GSLRef [32] allows omitting all such annotations. By matically; for instance, we might write labelOf b == S to extending LIO, GLIO adopts a mixed stance in that regard. test whether b holds a secret. First-class labels are often On the one hand, LIO does require programs to provide term- adopted in practically minded IFC systems [30, 35] because level annotations for certain operations, including reference they enable rich data-dependent policies. Unfortunately, they allocation. On the other hand, LIO’s coarse-grained design can easily break the DGG with type-guided classification. obviates the need for tracking labels in most of the program; Consider Figure 2, for instance: if the DGG were true, the most values are protected by the PC label, a state component unannotated program would behave the same way as the used in NSU checks. two annotated ones, which is impossible because they re- In principle, it would be possible to allow missing label turn different results. Similar issues have been observed in annotations for references in GLIO by choosing a default languages with dynamic type tests [8, 27]: if programs can value for them, such as the current PC label. Unfortunately, test anything about a value’s type, they can discern between the benefits of this approach would be limited for gradual different static annotations. typing: in the presence of first-class labels, no analog of the Thus, to reconcile noninterference and gradual typing, DGG can hold when overriding these defaults. We do not we are led to the second option: abandoning type-guided know if the situation fundamentally changes if first-class classification. The effect of an annotation should be merely labels are absent, but missing reference annotations are not to check labels, not to modify them. For Figure 1, this would the only source of violations for the DGG: similar issues arise mean that b, y and z would still be dynamically labeled P in GSLRef even if all reference annotations are present, by despite the static annotation Bool, triggering an NSU adapting the counterexample of Figure 1 to its syntax. error without any harm to the gradual guarantee. Likewise, Our contributions, in sum, are as follows. We introduce the annotations in Figure 2 could lead to a cast error, but GLIO, a gradual language based on LIO with higher-order they would not change the result of the test. Modifying labels functions and storage, flow-insensitive references, coarse- should still be possible, but through a term-level operation grained IFC, security subtyping and public, first-class la- that is not covered by the DGG. bels. After an informal tour of the language in Section 2, We realize this idea with GLIO, a gradual language based we present its syntax and type system in Section 3, and on the LIO library [31]. LIO exposes an API for securely define its semantics in Section 4. We prove that GLIO satis- manipulating secret data, to which GLIO adds optional an- fies both termination- and error-insensitive noninterference notations for preventing security errors statically. Following (Section 5) and the gradual guarantee of Siek et al.[27] (Sec- the tradition of gradual typing, GLIO features a notion of con- tion 6). We discuss related work in Section 7 and conclude sistent subtyping to allow annotated and unannotated code in Section 8. Detailed proofs and definitions are included in to interoperate automatically, unlike prior work [9], where Appendix A. Reconciling noninterference and gradual typing

2 Overview f :: Lab Bool -> LIO Bool Before diving into technical details, we give a brief tour f x = do of GLIO. Traditionally, IFC languages have followed a fine- -- Alternative annotation: Lab[S] Bool grained discipline: every value carries a secrecy label, which b :: Lab Bool <- label P True is implicitly checked and propagated on every operation (stat- b' <- unlabel b y <- new P b' ically or dynamically). This category includes 휆info [4], Flow z <- new P b' Caml [22] and Jif [18], among others. By contrast, systems x' <- unlabel x such as DCC [1], LIO [31] and GLIO follow a coarse-grained if x' then set y False discipline: only certain values carry labels, and they must else return () be manipulated using special primitives. The two styles are y' <- get y equally expressive [23, 34], but coarse-grained systems are if y' then set z False easier to implement (since they track less information) and else return () offer a smoother migration path to legacy programs (since get z most of the code does not need to worry about IFC). Following LIO, GLIO places labeled values in a special type do { x <- label S True; f x } called Lab, and uses a monad LIO to express computations that handle secrets. Its most basic primitives are: Figure 3. Translation of the example of Figure 1 into GLIO label :: Label -> a -> LIO (Lab a) unlabel :: Lab a -> LIO a labLabel :: Lab a -> Label pcLabel :: LIO Label leads to the same result as before: an error. Since the behav- ior of the program did not change after refining the type, the The types shown here mimic those of the original LIO, DGG has not been violated. but we’ll soon see that they can be refined with secrecy The annotation did not break the DGG, but it wasalso annotations. The label and unlabel functions are used to not strong enough to catch the IFC error statically. Figure 4 wrap a value of type a with a secrecy label and to unwrap demonstrates how this could be done in GLIO with a fully it. To do this safely, the LIO monad encapsulates a state annotated version of the previous program. As in HLIO [9], component known as the PC label, as usual in dynamic IFC. the annotations on the LIO monad provide upper bounds on This label bounds the secrecy of all the values that havebeen the PC label at the beginning and at the end of the computa- unlabeled during the computation. Before assignments, the tion. The annotations on Ref are stricter than those for Lab: program performs an NSU check on this label to determine instead of an upper bound, they give the exact secrecy of the whether the operation is safe. The functions labLabel and contents the reference. This is to ensure safety: if the static pcLabel allow inspecting the label of a labeled value and label of a reference, S, were above its actual dynamic label, the current PC label. say P, the NSU check would still throw an error at run time, The behavior of these primitives is illustrated in Figure 3, which the type checker would not be able to prevent. which shows a loose translation of Figure 1 into GLIO. In To check unlabel, the type system propagates the static addition to the explicitly labeled values, the main difference label of its argument into the PC label. Since x could be a with respect to Figure 1 is the new operator, which takes a secret, the type system rejects the assignment to y, as it could secrecy label P as its argument. This translation is contrived lead to an illegal implicit flow. for a coarse-grained system because of the spurious wrap- Figure 5 presents a middle ground between dynamic and ping of the boolean b, but it is operationally closer to the static enforcement, using label introspection to test whether original example and gives an idea of how GLIO enforces the NSU check would fail. Unlike labeled values, dynamic the DGG. labels are themselves public, and can be inspected without The program runs the same way as before. Unlabeling b tainting the PC. The lub operator computes the join, or least amounts to a no-op: since its label is public, we do not need upper bound, of two labels, while canFlowTo checks if one to update the PC label. On the contrary, x is marked as secret, label is below another. If the test passes, the assignment is so unlabeling it has the effect of bumping the PC label to S. performed without triggering any errors. Otherwise, the pro- This change is detected by GLIO’s NSU check, which deems gram logs the unsafe condition so that more robust recovery the update to y unsafe and halts the program with an error. code can act later. Instead of Lab Bool, we could have given b the more pre- cise type Lab[S] Bool, which says that the dynamic secrecy Labeling and allocation. Figure 6 further details the role of the wrapped boolean is bounded by S. Since this label is of labels in values and references. The first program, refLab, P, which is below S, the assignment can be performed safely. stores the contents of a labeled value x in a fresh reference r. Importantly, this does not modify b’s label, and updating y In this example, the new reference is typed as Ref[S] Bool Arthur Azevedo de Amorim, Matt Fredrikson, and Limin Jia h :: Lab[S] Bool -> LIO[P,S] Bool labCast :: LIO (Lab[P] Bool) h x = do labCast = do -- PC label = P b :: Lab[P] Bool <- label P True b :: Lab[P] Bool <- label P True return (b :: Lab[S] Bool :: Lab Bool b' :: Bool <- unlabel b :: Lab[P] Bool) y :: Ref[P] Bool <- new P b' z :: Ref[P] Bool <- new P b' labClass :: LIO (Lab[P] Bool) x' :: Bool <- unlabel x labClass = do -- PC label = S b :: Lab[P] Bool <- label P True if x' b' <- unlabel b -- Assignment is rejected b'' <- label S b' then set y False return (b' :: Lab Bool :: Lab[P] Bool) else return () y <- get y refCast :: LIO (Ref[S] Bool) if y then set z False refCast = do else return () r :: Ref[P] Bool <- new P True get z return (r :: Ref Bool :: Ref[S] Bool) do { x <- label S True; g x } Figure 7. Casts in GLIO

Figure 4. A fully annotated version of Figure 3 that is re- For the allocation to succeed, the reference label must be jected at compile time above the PC label, which can be statically enforced in this case thanks to the PC annotations. maybeUpdate :: Ref Bool -> Lab Bool -> LIO () The function uses another primitive of GLIO, toLab, to maybeUpdate r x = do avoid raising the PC label too much and causing spurious lpc <- pcLabel NSU errors—a problem known in the literature as label creep. let lx = labLabel x The first argument of toLab is a label l that bounds the let lr = refLabel r confidentiality of the result,2 and its second argument is a if lpc `lub` lx `canFlowTo` lr then do computation f. If the final PC label after running f is below l, x' <- unlabel x toLab wraps the result in a value labeled with l and restores set r x' the PC label to its original value; otherwise, it throws an else set errorOccurred True error. In refLab, the annotations are enough to guarantee the absence of errors and indicate that the PC label is indeed Figure 5. Error prevention through label introspection restored at the end of execution. The second program, labRef, goes in the opposite direc- refLab :: Lab[S] Bool -> LIO[P,P] (Ref[S] Bool) tion: it uses toLab to wrap the contents of r into a labeled refLab x = do value of the same secrecy as r. r :: Ref[S] Bool <- new S true Fine-grained IFC often makes a distinction between the -- toLab :: Label -> LIO a -> LIO (Lab a) label of a reference, which protects its identity, and the label toLab S (do { x' <- unlabel x; set r x' }) of its contents. In GLIO, what is sometimes called the “label return r of the reference” refers actually to the label of its contents: the identity of the reference is always public with respect to labRef :: Ref Bool -> LIO[P,P] (Lab Bool) the PC label, and does not need to be protected with special labRef r = toLab (refLabel r) (get r) checks. This is illustrated in the third program, eqRef, which tests if two references are identical. This comparison does eqRef :: Ref Bool -> Ref Bool -> LIO[P,P] Bool not take their contents into account, which is why the PC eqRef r1 r2 = return (r1 == r2) label does not have to be tainted.

Figure 6. Labeling and dynamic allocation Casts and classification. GLIO includes a notion of con- sistent subtyping to allow annotated and unannotated code

2You may wonder why the first argument of toLab is needed, since we because the annotation is constant, but in general this ar- could have also used the final PC label to wrap the result. The problem is gument can be an arbitrarily complex expression, in which that labels in GLIO are public, and can be used to leak secrets [15]. By fixing case the reference would get the imprecise type Ref Bool. the final label from the onset, we avoid the issue. Reconciling noninterference and gradual typing to interoperate. For example, we may pass a value r of type arguments, and the earlier snippets should be translated into Lab Bool to refLab in Figure 6, and the language inserts a sequence of let definitions. The first term rows contain the appropriate dynamic checks to ensure safety. (In this usual constructs for manipulating booleans, functions, and case, the checks are guaranteed to succeed, assuming the the heap. The last rows are specific to IFC, and correspond argument’s static label S denotes maximum secrecy.) to the primitives of LIO [30]. Two syntactic forms, new and We can also trigger casts explicitly using type ascription, toLab, take either variables or label constants as arguments as shown in Figure 7. The first function, labCast, labels the to allow for more precise typing rules, as we’ll soon see. Type boolean True with P and sends it through a series of casts, ascription is syntax sugar defined in terms of let, and label indicated with the :: operator. The type system checks each is defined in terms of toLab. (Since we don’t use a separate cast to rule out obvious or potential errors, such as coercing monadic type, label and toLab are actually synonyms.) Bool to Unit or Lab[S] Bool to Lab[P] Bool. As usual in gradual languages, the missing annotations Once labCast reaches the last cast to Lab[P] Bool, it suc- in concrete syntax formally correspond to the gradual label cessfully returns True labeled as P, because the final label on ? ∈ 퐿̄ ≜ 퐿 ⊎ {?}, which represents a statically unknown label. the boolean stays the same across the casts—in other words, The language does not include product, sum, and recursive classification and type casts are decoupled. This contrasts types, but we foresee no difficulties in doing so—for recursive with previous work [11, 12], in particular with GSLRef [32], types in particular, GLIO already includes a higher-order which by design would trigger a run-time error, since it treats store, which forces us to handle similar technical challenges. the last cast as a declassification. This behavior can be repli- Figure 9 presents the type system. The label indices in cated in GLIO by replacing the first cast to Lab[S] Bool judgments Γ ⊢ ̄ ̄ 푒 ∶ 푇 correspond to the static annotations 푙1,푙2 with another call to label, as shown in the second program, on the LIO monad of Section 2: they constrain the PC label labClass. Classification succeeds, because S is more secret at the beginning and at the end of the execution of 푒. The than P, but the last cast fails for the same reason. rules reflect the behavior of the programs described earlier. Finally, refCast demonstrates the difference between la- For example, the variable rule does not change the label bels for Ref and Lab. The annotations on reference types fix annotation because variables are already protected by the the labels of their contents, so the final cast to Ref[S] Bool current PC label, and thus require no additional tainting. fails during execution even though S is more secret than A similar reasoning applies to the introspection primitives P. Note that this cast has to come after a cast to the impre- refLabel, labLabel and pcLabel. cise type Ref Bool: were it omitted, the type checker would The rule for let shows how the label indices are threaded reject the program, as such a coercion always fails. through as the computation unfolds. The consistent subtyp- ing assumption 푇 ′ ≼ 푇 allows weakening security annota- 3 Language tions or even omitting them entirely. Its definition, shown in Figure 10, resembles the subtyping discipline of Rajani Having built basic intuition, we are ready for a formal defi- and Garg [23], but adapted to the gradual setting using the nition. The development assumes a lattice of secrecy labels Abstracting Gradual Typing (AGT) framework [14]. In AGT, 푙 ∈ 퐿 ordered by ≼, comprising joins ⋎, meets ⋏, a bottom a gradual type 푇 is interpreted as a set 훾(푇 ) of fully an- element ⊥ and a top element ⊤. The higher a label, the more notated types, where each missing annotation is replaced confidential the values it classifies, with ⊥ denoting public by all possible completions. For example, 훾( ( )) is data and ⊤ denoting maximum secrecy. A simple choice for Lab? Bool {Lab (Bool) ∣ 푙 ∈ 퐿}. (Figure 20 gives the complete defi- 퐿 would be a lattice of labels {P, S} ordered by P ≼ S.A 푙 nition.) This allows us to lift arbitrary predicates on fully more interesting instance is 퐿 = 풫 (푃) ordered by the subset annotated types to gradual types: the inductive presentation relation, where 푃 = {Alice, Bob, …} is a set of principals that of Figure 10 is equivalent to saying that 푇 ≼ 푆 holds precisely own data, ⊥ = ∅, ⊤ = 푃, ⋏ = ∩ and ⋎ = ∪. when there exist 푇 ′ ∈ 훾(푇 ) and 푆′ ∈ 훾(푆) such that 푇 ′ ≼ 푆′, Figure 8 summarizes the syntax of terms and types. To for a suitable subtyping relation ≼ on fully annotated types. simplify the development, we modify the informal overview The ≼ relation on 퐿,̄ which extends the one on 퐿, can be recast of the previous section in two aspects. First, since our main in the same way, by posing 훾(?) = 퐿 and 훾(푙) = {푙}. technical challenges pertain to impure code, we conflate pure ̄ ̄ On multiple rules, the consistent ordering on gradual la- 푙1,푙2 functions and the LIO monad into a single type 푇 −−−→푆, bels is used to rule out IFC errors. For example, the side ̄ ̄ which intuitively corresponds to the type 푇 → LIO[푙1, 푙2] 푆 condition on the set rule subsumes the corresponding NSU seen earlier. Because of cast errors, “pure” code in our lan- check. Other rules, such as get and if, taint types and the PC guage still needs to be managed monadically, and this sim- label using partial consistent join operations ⋎ (Figure 11). plification allows us to model pure and impure code with The definition uses a consistent meet operation ⋏ and an a single monad (cf. Section 4). Second, to allow for a more intersection operation ∩ on types and gradual labels. These compact semantics later, we present the syntax in A-normal operations are not joins and meets in the usual sense, since form [13, 25]: most term formers only allow variables as Arthur Azevedo de Amorim, Matt Fredrikson, and Limin Jia

푙 ∈ 퐿 푙̄ ∈ 퐿̄ ≜ 퐿 ⊎ {?} Term ∋ 푒 ∶= 푥 ∣ let(푒1, 푥 ∶ 푇 .푒2) ∣ unit ∣ 푏 ∣ if(푥, 푒1, 푒0) ∣ fun(푥 ∶푙 ̄ 푇 .푒) standard 푏 ∈ {0, 1} ∣ app(푥, 푦) ∣ get(푥) ∣ set(푥, 푦) ∣ new(푐, 푦) ∣ eqRef(푥, 푦) 푐 ∈ 퐿 ⊎ {푥, 푦, 푧, …} ∣ refLabel(푥) ∣ labLabel(푥) ∣ pcLabel() IFC specific ⊕ ∈ {⋏, ⋎} ∣푙∣푥⊕푦∣푥≼푦∣ unlabel(푥) ∣ toLab(푐, 푒) Γ ∈ Var ⇀fin Type 푙 ̄ ,푙 ̄ ∋ 푇 , 푆 ∶= ∣ ∣ ∣ (푇 ) ∣ (푇 ) ∣ 푇 −−−→푆1 2 푒 ∷ 푇 ≜ let(푒, 푥 ∶ 푇 .…) Type Unit Bool Label Ref푙 ̄ Lab푙 ̄ label(푐, 푥) ≜ toLab(푐, 푥)

Figure 8. Syntax of terms and types

′ ′ Γ ⊢ ̄ ̄ 푒 ∶ 푇 Γ[푥 ↦ 푇 ] ⊢ ̄ ̄ 푒 ∶ 푆 푇 ≼ 푇 Γ(푥) = 푇 푙1,푙2 1 푙2,푙3 2 Γ ⊢ ̄ ̄ 푥 ∶ 푇 Γ ⊢ ̄ ̄ let(푒 , 푥 ∶ 푇 .푒 ) ∶ 푆 Γ ⊢ ̄ ̄ unit ∶ Unit Γ ⊢ ̄ ̄ 푏 ∶ Bool 푙,푙 푙1,푙3 1 2 푙,푙 푙,푙

Γ(푥) = Bool Γ ⊢ ̄ 1̄ 푒 ∶ 푇 Γ ⊢ ̄ 0̄ 푒 ∶ 푇 푙1,푙2 1 1 푙1,푙2 0 0 Γ(푥) = Ref푙(푇̄ ) Γ ⊢ ̄ 1̄ 0̄ if(푥, 푒 , 푒 ) ∶ 푇 ⋎ 푇 Γ ⊢ ̄ ̄ ̄ get(푥) ∶ 푇 푙1,푙2 ⋎푙2 1 0 1 0 푙1,푙1⋎푙 ̄ ̄ ̄ Γ(푥) = Ref푙(푇̄ 1) Γ(푦) = 푇2 푇2 ≼ 푇1 푙1 ≼ 푙 Γ(푦) = 푇 푙2 ≼ 푙1 Γ(푥) = Label Γ(푦) = 푇 Γ ⊢ ̄ ̄ set(푥, 푦) ∶ Unit Γ ⊢ ̄ ̄ new(푙 , 푦) ∶ Ref (푇 ) Γ ⊢ ̄ ̄ new(푥, 푦) ∶ Ref (푇 ) 푙1,푙1 푙2,푙2 1 푙1 푙2,푙2 ?

Γ(푥) = Ref ̄ (푇 ) Γ(푦) = Ref ̄ (푇 ) 푇 ≼ 푇 푇 ≼ 푇 Γ[푥 ↦ 푇 ] ⊢ ̄ ̄ 푒 ∶ 푆 푙1 1 푙2 2 1 2 2 1 푙1,푙2 ̄ ̄ Γ ⊢ ̄ ̄ eqRef(푥, 푦) ∶ Bool 푙1,푙2 푙,푙 Γ ⊢ ̄ ̄ fun(푥 ∶ ̄ 푇 .푒) ∶ 푇 −−−→푆 푙,푙 푙1

̄ ̄ 푙2,푙3 ̄ ̄ Γ(푓 ) = 푇1 −−−→푆 Γ(푥) = 푇2 푇2 ≼ 푇1 푙1 ≼ 푙2 Γ(푥) = Ref푙(푇̄ ) Γ(푥) = Lab푙(푇̄ ) Γ ⊢ ̄ ̄ app(푓 , 푥) ∶ 푆 Γ ⊢ ′̄ ′̄ refLabel(푥) ∶ Label Γ ⊢ ′̄ ′̄ labLabel(푥) ∶ Label 푙1,푙3 푙 ,푙 푙 ,푙

Γ(푥) = Γ(푦) = Label Γ(푥) = Γ(푦) = Label Γ(푥) = Lab푙′̄ (푇 ) Γ ⊢푙,̄푙 ̄ pcLabel() ∶ Label Γ ⊢푙,̄푙 ̄ 푙 ∶ Label Γ ⊢푙,̄푙 ̄ 푥 ≼ 푦 ∶ Bool Γ ⊢푙,̄푙 ̄ 푥 ⊕ 푦 ∶ Label Γ ⊢푙,̄푙⋎̄ 푙′̄ unlabel(푥) ∶ 푇

Γ ⊢ ̄ ̄ 푒 ∶ 푇 푙 ̄ ≼ 푙 ⋎ 푙 ̄ Γ(푥) = Label Γ ⊢ ̄ ̄ 푒 ∶ 푇 푙2,푙3 3 1 2 푙2,푙3 Γ ⊢ ̄ ̄ toLab(푙 , 푒) ∶ Lab (푇 ) Γ ⊢ ̄ ̄ toLab(푥, 푒) ∶ Lab (푇 ) 푙2,푙2 1 푙1 푙2,푙2 ?

Figure 9. Typing rules the consistent orders are not transitive, and thus not actual system uses it in the result type. When this label is chosen orders; nevertheless, we can show dynamically, the result type is labeled with ?. ̄ ̄ ̄ ̄ ̄ The rule for toLab is slightly more permissive than the 푙1 ⋏ 푙2 ≼ 푙푖 ≼ 푙1 ⋎ 푙2 and 푇1 ⋏ 푇2 ≼ 푇푖 ≼ 푇1 ⋎ 푇2 corresponding dynamic checks in LIO [31], which would ̄ ̄ ̄ for 푖 ∈ {1, 2}, whenever the result of these operations is translate as 푙3 ≼ 푙1 instead of 푙3 ≼ 푙1 ⋎ 푙2. Intuitively, our defined. Note that when all labels are ?, 푇 ≼ 푆 is equivalent variant is sound because the result of toLab is protected ̄ to 푇 = 푆, so consistent joins become trivial and the type by both the ascribed label 푙1 and the initial PC label 푙2. In system reduces to a simplified version of LIO. Section 4, we will see that toLab takes the PC label into The two variants of new and toLab use different typing account during execution too. rules because the secrecy of their results is determined by their label argument. When this label is statically known (that is, in the new(푙, −) and toLab(푙, −) variants), the type Reconciling noninterference and gradual typing

푙1 ≼ 푙2 ∶ 퐿 푇 ∈ {Unit, Bool, Label} ⟦Unit⟧ ≅ 1 ⟦Bool⟧ ≅ 2 ⟦Label⟧ ≅ 퐿 ̄ ̄ 푙 ≼ ? ? ≼ 푙 푙1 ≼ 푙2 ∶ 퐿̄ 푇 ≼ 푇 ⟦Ref푙(푇̄ )⟧ ≅ Ref푙 ̄ ⟦Lab푙(푇̄ )⟧ ≅ Lab푙(⟦푇̄ ⟧)

푙 ̄ ≼ 푙 ̄ 푙 ̄ ≼ 푙 ̄ 푇 ≼ 푇 푇 ≼ 푇 ̄ ̄ 1 2 2 1 1 2 2 1 푙1,푙2 cont ⟦푇 −−−→푆⟧ ≅ ⟦푇 ⟧ −−−−→ LIO ̄ ̄ (⟦푆⟧) Ref ̄ (푇 ) ≼ Ref ̄ (푇 ) 푙1,푙2 푙1 1 푙2 2 ̄ ̄ 푙1 ≼ 푙2 푇1 ≼ 푇2 ̄ Ref푙 ̄ ≜ {(푟푛, 푟stamp, 푟label) ∈ ℕ × 퐿 × 훾(푙) ∣ 푟stamp ≼ 푟label} Lab ̄ (푇 ) ≼ Lab ̄ (푇 ) 푙1 1 푙2 2 Lab (푋)̄ ≜ {푥@푙 ∣ 푥 ∈ 푋, 푙 ∈ ↓푙}̄ ′̄ ̄ ̄ ′̄ ′ ′ 푙 푙1 ≼ 푙1 푙2 ≼ 푙2 푇1 ≼ 푇1 푇2 ≼ 푇2 ̄ ̄ ′̄ ′̄ cont 푙1,푙2 푙1,푙2 ̄ ̄ ′ ′ LIO ̄ ̄ (푋) ≜ {푓 ∶ Mem ×↓푙1 −−−−→ Error(Mem ×푋 × ↓푙2)⊥ ∣ 푇1 −−−→푇2 ≼ 푇1 −−−→푇2 푙1,푙2 ∀푚1, 푙1, 푥, 푚2, 푙2. 푓 (푚1, 푙1) = (푚2, 푥, 푙2) ⇒ 푙1 ≼ 푙2 ∧ valid(푙1, 푚1, 푚2)} Figure 10. Consistent subtyping ↓푙̄ ≜ {푙′ ∈ 퐿 ∣ 푙′ ≼ 푙}̄ Error(푋) ≜ 푋 + {error} 푙̄ ⊕ ? = ? ⊕ 푙̄ ≜ ? Mem ≜ (푇 ∶ Type∘) × Ref ⇀ ⟦푇 ⟧ 푙̄ ∩ ? = ? ∩ 푙̄ ≜ 푙 ̄ ? fin ∘ ∘ 푙1 ⊕ 푙2 ≜ 푙1 ⊕ 푙2 Type ≜ {푇 ∈ Type ∣ 푇 = 푇 } ̄ ̄ ̄ 푙 ∩ 푙 ≜ 푙 푇 ∘ ≜ Unit ⊕ Unit ≜ Unit 푇 with all labels replaced by ? (cf. Figure 21) Unit ∩ Unit ≜ Unit valid(푙1, 푚1, 푚2) ≜ ∀(푇 , 푟) ∈ dom(푚 ). Bool ⊕ Bool ≜ Bool 2 푙1 ≼ 푟label ∧ (푙1 ⋠ 푟stamp ⇒ (푇 , 푟) ∈ dom(푚1)) Bool ∩ Bool ≜ Bool Label ⊕ Label ≜ Label Figure 12. Interpretation of types and related constructions Label ∩ Label ≜ Label on CPOs. To simplify notation, we’ll treat the isomorphisms Ref ̄ (푇 ) ⊕ Ref ̄ (푇 ) ≜ Ref ̄ ̄ (푇 ∩ 푇 ) defining ⟦푇 ⟧ as equations. 푙1 1 푙2 2 푙1∩푙2 1 2 Ref ̄ (푇 ) ∩ Ref ̄ (푇 ) ≜ Ref ̄ ̄ (푇 ∩ 푇 ) 푙1 1 푙2 2 푙1∩푙2 1 2 Lab ̄ (푇 ) ⊕ Lab ̄ (푇 ) ≜ Lab ̄ ̄ (푇 ⊕ 푇 ) 푙1 1 푙2 2 푙1⊕푙2 1 2 Lab ̄ (푇 ) ∩ Lab ̄ (푇 ) ≜ Lab ̄ ̄ (푇 ∩ 푇 ) 4 Semantics 푙1 1 푙2 2 푙1∩푙2 1 2 Each type 푇 in GLIO corresponds to a set ⟦푇 ⟧ (Figure 12). As ̄ ̄ 푙′̄ ,푙′̄ 푙1,푙2 ′ 1 2 ′ the heap can store arbitrary values, ⟦푇 ⟧ contains negative 푇1 −−−→푇2 ⊕ 푇1 −−−→푇2 recursive occurrences, which requires some care to handle. 푙 ̄ ⊝푙′̄ ,푙 ̄ ⊕푙′̄ ′ 1 1 2 2 ′ To solve this issue, we define ⟦푇 ⟧ as a CPO rather than ≜ (푇1 ⊝ 푇1 ) −−−−−−−−−→(푇2 ⊕ 푇2 ) ̄ ̄ ′̄ ′̄ a plain set, by solving a domain equation [29]. We briefly 푙1,푙2 푙1,푙2 (푇1 −−−→푇2) ∩ (푆1 −−−→푆2) review basic notions needed to cover the main contributions, and postpone a detailed description of the construction to ̄ ′̄ ̄ ′̄ 푙1∩푙1,푙2∩푙2 Appendix A for the interested readers. ≜ (푇1 ∩ 푆1) −−−−−−−−−→(푇2 ∩ 푆2) First, by CPO we mean a partially ordered set where all increasing chains 푥0 ⊑ 푥1 ⊑ ⋯ have a least upper bound Figure 11. Gradual meets, gradual joins and intersections for cont ⨆ 푥 . The notation 푋 −−−−→푌 refers to the CPO of contin- labels and types. Most combinations of types yield undefined 푖∈ℕ 푖 results. Here, ⊕ stands for either ⋎ or ⋏, and ⊝ stands for the uous functions between 푋 and 푌—that is, monotone func- (⨆ ) ⨆ other operation. tions 푓 ∶ 푋 → 푌 such that 푓 푖 푥푖 = 푖 푓 (푥푖), ordered pointwise. The lifted CPO 푋⊥ extends the CPO 푋 with a least element ⊥, which represents nontermination. We use equality, or the discrete order, on CPOs such as Ref푙,̄ Type, 퐿 and its subsets. Error(푋) is ordered pointwise. The order 푚1 ⊑ 푚2 on Mem holds when dom(푚1) = dom(푚2) and ∀푇 , 푟. 푚1(푇 , 푟) ⊑ 푚2(푇 , 푟). Arthur Azevedo de Amorim, Matt Fredrikson, and Limin Jia

cont ⟦Γ ⊢ ̄ ̄ 푒 ∶ 푇 ⟧ ∶ ⟦Γ⟧ −−−−→ LIO ̄ ̄ (⟦푇 ⟧) ⟦Γ⟧ ≜ ∏ ⟦Γ(푥)⟧ 푙1,푙2 푙1,푙2 푥∈dom(Γ)

′ 푣 ← ⟦푒1⟧(푠); ′ ′ ′ ⟦푥⟧(푠) ≜ return(푠(푥)) ⟦let(푒1 ∶ 푇 , 푥 ∶ 푇 .푒2)⟧(푠) ≜ do { 푣 ← ⟦푇 ≼ 푇 ⟧(푣 ); ⟦unit⟧(푠) ≜ return(1) ⟦푒2⟧(푠[푥 ↦ 푣])

푏 ≜ 푠(푥) ⎧ ⎪ 푣 ← ⟦푒푏⟧(푠); ⟦푏⟧(푠) ≜ return(푏) ⟦Γ ⊢ ̄ 1̄ 0̄ if(푥, 푒1, 푒0) ∶ 푇1 ⋎ 푇0⟧(푠) ≜ do 푏 1 0 푙1,푙2 ⋎푙2 ⎨ ⟦푙 ̄ ≼ 푙 ̄ ⋎ 푙 ̄ ⟧; ⎪ 2 2 2 ⎩ ⟦푇푏 ≼ 푇1 ⋎ 푇0⟧(푣)

∘ 푣 ← get_,_,푇(푠(푥)); 푣 ← ⟦푇2 ≼ 푇2⟧(푠(푦)); ⟦get(푥 ∶ Ref푙(푇̄ ))⟧(푠) ≜ do { ∘ ⟦set(푥 ∶ Ref푙(푇̄ 1), 푦 ∶ 푇2)⟧(푠) ≜ do { ′ ⟦푇 ≼ 푇 ⟧(푣) set_,_,푇2(푠(푥), 푣 )

푣 ← ⟦푇 ≼ 푇 ∘⟧(푠(푦)); 푣 ← ⟦푇 ≼ 푇 ∘⟧(푠(푦)); ⟦new(푙1, 푦 ∶ 푇 )⟧(푠) ≜ do { ⟦new(푥, 푦 ∶ 푇 )⟧(푠) ≜ do { new푙1,_,푇(푙1, 푣) new?,_,푇(푠(푥), 푣)

⟦eqRef(푥, 푦)⟧(푠) ≜ return(푠(푥) = 푠(푦)) ⟦fun(푥 ∶ ̄ 푇 .푒)⟧(푠) ≜ return(휆푣.⟦푒⟧(푠[푥 ↦ 푣])) 푙1

̄ ̄ 푣 ← ⟦푇2 ≼ 푇1⟧(푠(푥)); 푙2,푙3 ⟦Γ ⊢ ̄ ̄ app(푓 ∶ 푇 −−−→푆, 푥 ∶ 푇 ) ∶ 푆⟧ ≜ do { ⟦푙 ̄ ≼ 푙 ̄ ⟧; ⟦refLabel(푥)⟧(푠) ≜ return(푠(푥) ) 푙1,푙3 1 2 1 2 label 푠(푓 )(푣)

_@푙 ≜ 푠(푥); ⟦labLabel(푥)⟧(푠) ≜ do { ⟦pcLabel()⟧(푠)(푚, 푙) ≜ (∅, 푙, 푙) ⟦푙⟧(푠) ≜ return(푙) return(푙)

⟦푥 ≼ 푦⟧(푠) ≜ return(푠(푥) ≼ 푠(푦)) ⟦푥 ⊕ 푦⟧(푠) ≜ return(푠(푥) ⊕ 푠(푦)) ⟦unlabel(푥)⟧(푠) ≜ unlabel(푠(푥))

⟦toLab(푙1, 푒)⟧(푠) ≜ toLab푙1,_,_,_(푙1, ⟦푒⟧(푠)) ⟦toLab(푥, 푒)⟧(푠) ≜ toLab?,_,_,_(푠(푥), ⟦푒⟧(푠))

Figure 13. Semantics of typing derivations. The types of some variables and expressions are included for clarity, even though they do not appear in the syntax of terms. Conversely, some of the indices of get, set, new and toLab have been left out, but they can be inferred from the annotations in the corresponding judgments.

Let us explain these definitions before moving on to the The CPO LIO ̄ ̄ (푋) corresponds to the computation types 푙1,푙2 semantics of terms. The CPOs Lab푙(푋)̄ contain elements of 푋 of LIO [30] and HLIO [9]. Its elements are functions that take ̄ protected by a dynamic label 푙; as explained in Section 2, this as inputs a memory (Mem) and a PC label (↓푙1), and that can label is bounded by the annotation 푙,̄ not necessarily equal to either run forever (⊥), produce an error, or return memory ̄ it. A reference 푟 = (푟푛, 푟stamp, 푟label) carries two labels: 푟stamp updates (Mem), a result (푋), and a new PC label (↓푙2). (Re- corresponds to the PC label at the moment of allocation, and turning updates instead of the final memory is unorthodox, 푟label corresponds to the secrecy of its contents. As noted but it simplifies the domain equations, as discussed inAp- in Section 2, 푟label must exactly match the static annotation pendix A.2.) The post-condition on the PC label means that it on the reference’s type, if one is provided. The stamp is not goes up to track inspected secrets. The post-condition valid, important for program behavior, but it simplifies the proof explained next, ensures that memory updates do not leak of noninterference, for reasons that will soon become clear. secrets. We depart from Haskell by following call-by-value rather A memory 푚 ∈ Mem is a function with finite domain than call-by-need: functions take forced values as their ar- that maps a type 푇 and a reference 푟 to a value 푣 ∈ ⟦푇 ⟧. guments, rather than elements of a lifted CPO 푋⊥. This is We assume that 푇 has no label annotations, because our merely for organizational purposes: call-by-value allows us semantics doesn’t track this information for stored values to segregate divergence as an effect inside LIO, rather than (we discuss a more efficient approach below). The predi- including it explicitly in the denotation of each type. cate valid(푙1, 푚1, 푚2) describes which memory updates are Reconciling noninterference and gradual typing

unlabel ̄ ̄ ∶ Lab ̄ (푋) → LIO ̄ ̄ ̄ (푋) 푙1,푙2,푋 푙2 푙1,푙1⋎푙2 unlabel ̄ ̄ (푥@푙 )(푚, 푙 ) ≜ (∅, 푥, 푙 ⋎ 푙 ) 푙1,푙2,푋 2 1 1 2 ∘ get ̄ ̄ ∶ Ref ̄ → LIO ̄ ̄ ̄ (⟦푇 ⟧) 푙1,푙2,푇 푙2 푙1,푙1⋎푙2 ∘ (∅, 푣, 푙1 ⋎ 푟label) if 푚(푇 , 푟) = 푣 get ̄ ̄ (푟)(푚, 푙1) ≜ { 푙1,푙2,푇 error if (푇 ∘, 푟) ∉ dom(푚) ∘ set ̄ ̄ ∶ Ref ̄ ×⟦푇 ⟧ → LIO ̄ ̄ (1) 푙1,푙2,푇 푙1 푙2,푙2 ∘ ∘ ([푇 , 푟 ↦ 푣], 1, 푙2) if 푙2 ≼ 푟label and (푇 , 푟) ∈ dom(푚) set ̄ ̄ (푟, 푣)(푚, 푙2) ≜ { 푙1,푙2,푇 error otherwise ∘ new ̄ ̄ ∶ 훾(푙 ̄ ) × ⟦푇 ⟧ → LIO ̄ ̄ (Ref ̄ ) 푙1,푙2,푇 1 푙2,푙2 푙1 ∘ ([푟 ↦ 푣], 푟, 푙2) if 푙2 ≼ 푙1 and 푟 = (푇 , (푛, 푙2, 푙1)), with ⎪⎧ 푛 ≜ min{푛 ∣ (푇 ∘, (푛, 푙 , 푙 )) ∉ (푚)} new ̄ ̄ (푙1, 푣)(푚, 푙2) ≜ 2 1 dom 푙1,푙2,푇 ⎨ ⎪ ⎩error otherwise toLab ̄ ̄ ̄ ∶ 훾(푙 ̄ ) × LIO ̄ ̄ (푋) → LIO ̄ ̄ (Lab ̄ (푋)) 푙1,푙2,푙3,푋 1 푙2,푙3 푙2,푙2 푙1 (푚′, 푣@푙 , 푙 ) if 푓 (푚, 푙 ) = (푚′, 푣, 푙 ) and 푙 ≼ 푙 ⋎ 푙 ⎧ 1 2 2 3 3 1 2 ⎪ ⎪ ′ error if 푓 (푚, 푙2) = (푚 , 푣, 푙3) and 푙3 ⋠ 푙1 ⋎ 푙2 toLab푙 ̄ ,푙 ̄ ,푙 ̄ ,푋(푙1, 푓 )(푚, 푙2) ≜ 1 2 3 ⎨ or 푓 (푚, 푙2) = error ⎪ ⎩⊥ if 푓 (푚, 푙2) = ⊥

Figure 14. Semantics of typing derivations (continued)

cont return푙,푋̄ ∶ 푋 −−−−→ LIO푙,̄푙(푋)̄ return(푥)(푚, 푙) ≜ (∅, 푥, 푙) cont cont bind ̄ ̄ ̄ ∶ LIO ̄ ̄ (푋) × (푋 −−−−→ LIO ̄ ̄ (푌 )) −−−−→ LIO ̄ ̄ (푌 ) 푙1,푙2,푙3,푋,푌 푙1,푙2 푙2,푙3 푙1,푙3 (푚′ ⃗⊎ 푚″, 푦, 푙″) if 푘(푚, 푙) = (푚′, 푥, 푙′) and ⎧ ⎪ 푓 (푥)(푚 ⃗⊎ 푚′, 푙′) = (푚″, 푦, 푙″) ⎪ bind(푘, 푓 )(푚, 푙) ≜ error if 푘(푚, 푙) = (푚′, 푥, 푙′) and ⎨ ⎪ 푓 (푥)(푚 ⃗⊎ 푚′, 푙′) = error or 푘(푚, 푙) = error ⎪ ⎩⊥ otherwise 푚′(푟) if 푟 ∈ dom(푚′) (푚 ⃗⊎ 푚′)(푟) ≜ { 푚(푟) otherwise

Figure 15. Monadic operations of LIO allowed under the PC label 푙1: new and updated locations Levy [17], but the issue is orthogonal to our purposes, and we must pass the NSU check for 푙1 (푙1 ≼ 푟label), and stamps must stick to the current formulation for simplicity. Note, however, reflect their allocation context, which, as hinted earlier, isa that some memory-related errors are ruled out by the shape technical device to simplify the noninterference proof. of the memory. For instance, if we try to read 푚(Bool, 푟) and The definition of LIO does not preclude computations that that location is defined, we know that it contains indeed a access undefined locations in memory, because its elements boolean, which we can access directly. take all possible memories as their input. It would be possible With the interpretation of types at hand, we are ready for to rule out these errors with a Kripke semantics in the style of the semantics of typed terms, shown in Figures 13 and 14. We Arthur Azevedo de Amorim, Matt Fredrikson, and Limin Jia

cont ⟦푇 ≼ 푆⟧푙 ̄ ∶ ⟦푇 ⟧ −−−−→ LIO푙,̄푙(⟦푆⟧)̄ (for 푇 ≼ 푆) ⟦푇 ≼ 푇 ⟧ ≜ return (for 푇 ∈ {Unit, Bool, Label}) ̄ return(푛, 푙1, 푙2) if 푙2 ∈ 훾(푙2) ⟦Ref ̄ (푇 ) ≼ Ref ̄ (푆)⟧(푛, 푙1, 푙2) ≜ { 푙1 푙2 휆(−). error otherwise ′ ⎧ 푣 ← ⟦푇1 ≼ 푇2⟧(푣); ̄ do { ′ if 푙 ∈ ↓푙2 ⟦Lab ̄ (푇1) ≼ Lab ̄ (푇2)⟧(푣@푙) ≜ return(푣 @푙) 푙1 푙2 ⎨ ⎩휆(−). error otherwise 푥 ← ⟦푇 ′ ≼ 푇 ⟧(푥′); ⎧ ′̄ ̄ ̄ ̄ ′̄ ′̄ ⎪ ⟦푙1 ≼ 푙1⟧; 푙1,푙2 푙1,푙2 ⟦푇 −−−→푆 ≼ 푇 ′ −−−→푆′⟧(푓 ) ≜ return 휆푥′.do 푦 ← 푓 (푥); ⎨ ̄ ′̄ ⎪ ⟦푙2 ≼ 푙2⟧; ⎩ ⟦푆 ≼ 푆′⟧(푦);

⟦푙 ̄ ≼ 푙 ̄ ⟧ ∶ LIO ̄ ̄ (1) (for 푙 ̄ ≼ 푙 ̄ ) 1 2 푙1,푙2 1 2 ̄ ̄ ̄ (∅, 1, 푙1) if 푙1 ∈ ↓푙2 ⟦푙1 ≼ 푙2⟧(푚, 푙1) ≜ { error otherwise

Figure 16. Label and type coercion equip LIO with the structure of a parameterized monad [3] The examples of Section 2 have already exercised the most (Figure 15), which we use to interpret the Haskell-like do interesting aspects of the semantics, except for one: stamps. notation in the definitions. Notice how bind applies updates Consider the following program 푒, written in informal syntax to the initial memory before invoking its continuation, in for clarity (recall that S stands for ⊤). accordance with our treatment of state. Figure 16 defines the toLab S $ do interpretation of subtyping coercions. As explained earlier, b' <- unlabel b coercing a value into Lab or Ref types never changes its if b' then do { new S True; return () } label, only checks it, which will be important for the gradual else return () } guarantee. Similarly, the coercions triggered by casting or new S True applying a function never modify the PC label. The behavior of basic ML operations is standard, except We can produce a typing judgment [푏 ↦ Lab?(Bool)] ⊢⊥,⊥ for coercions and the NSU checks in and . To read a 푒 ∶ Ref⊤(Bool), which corresponds to a function ⟦푒⟧ of type set new cont reference, we cast its contents to ensure that the labels on the Lab?(2) −−−−→ LIO⊥,⊥(Ref⊤). By running this program on two type are respected; conversely, when updating it reference, different inputs and an empty memory, we obtain successful we use a cast to forget the labels. (Note that 푇 ≼ 푇 ∘ and 푇 ∘ ≼ executions 푇 hold for every 푇.) A more efficient approach would beto use monotonic references [28], whose types are guaranteed to ⟦푒⟧(1@⊤)(∅, ⊥) = ([푟0 ↦ 1, 푟1 ↦ 1], 푟1, ⊥) be bounded in precision by the type of their contents during ⟦푒⟧(0@⊤)(∅, ⊥) = ([푟1 ↦ 1], 푟1, ⊥), execution. This property ensures that accesses to a reference of fully annotated type can be performed directly, without where 푟0 = (Bool, (0, ⊤, ⊤)) is allocated inside the conditional, any casts. We believe that monotonic references could be and 푟1 = (Bool, (0, ⊥, ⊤)) is allocated at the end. incorporated in GLIO without compromising our results, but Although the secret 푏 caused 푒 to perform different alloca- arguing about their correctness requires an intricate stateful tions, the result is the same: the stamps allow us to perform invariant, and we keep our scheme for simplicity. Note that the allocations in high-secrecy contexts without impacting in the case of base types, the casts reduce to the identity, references allocated in low-secrecy contexts. This technique, because they have no labels to be checked. due to Azevedo de Amorim et al.[5], simplifies the proof of The IFC operations are modeled after their analogues in noninterference because we can match references in related executions up to equality. Without stamps, noninterference LIO [30], but toLab includes the initial PC label 푙2 in its side condition, as anticipated by its typing rule. Note how unlabel would still hold, but the values returned in each execution and get taint the PC label to track the secrecy of the result. would not necessarily be equal, requiring a more complex argument to relate syntactically different references [7]. Reconciling noninterference and gradual typing

CPO Relation Definition 1, 2, 퐿, Ref푙 ̄ 푥 ≈푙 푦 푥 = 푦 Lab푙(푋)̄ 푥1@푙1 ≋푙 푥2@푙2 ∀푖 ∈ {1, 2}. 푙푖 ≼ 푙 ⇒ (푥1 ≈푙 푥2 ∧ 푙1 = 푙2) 푥1@푙1 ≈푙 푥2@푙2 푥1@푙1 ≋푙 푥2@푙2 ∧ 푙1 = 푙2 cont 푋 −−−−→푌 푓 ≈푙 푔 ∀푥 ≈푙 푦, 푓 (푥) ≈푙 푔(푦) ′ ′ ′ LIO푙 ̄ ,푙 ̄ (푋) 푓 ≈푙 푔 ∀푚1 ≈푙 푚2, 푙 , 푚1, 푚2, 푥1, 푥2, 푙1, 푙2. 1 2 ′ ′ ′ ′ 푓 (푚1, 푙 ) = (푚1, 푥1, 푙1) ∧ 푔(푚2, 푙 ) = (푚2, 푥2, 푙2) ′ ′ ⇒ 푚1 ⃗⊎ 푚1 ≈푙 푚2 ⃗⊎ 푚2 ∧ 푥1@푙1 ≋푙 푥2@푙2 Mem 푚1 ≈푙 푚2 dom푙(푚1) = dom푙(푚2) ∧ ∀(푇 , 푟) ∈ dom(푚1) ∩ dom(푚2). 푚1(푇 , 푟)@푟label ≈푙 푚2(푇 , 푟)@푟label ⟦Γ⟧ 푠1 ≈푙 푠2 ∀푥 ∈ dom(Γ). 푠1(푥) ≈푙 푠2(푥)

dom푙(푚) ≜ {(푇 , 푟) ∈ dom(푚) ∣ 푟stamp ≼ 푙}

Figure 17. Notions of indistinguishability on CPOs. The definitions assume that the CPOs 푋 and 푌 carry such notions as well.

5 Noninterference Sketch. By induction on the typing derivation of 푒. The se- With the semantics pinned down, we are ready for our first mantics of the language is defined by using the monadic in- main result: showing that GLIO satisfies termination- and terface of Figure 15 to compose the operations in Figures 14 error-insensitive noninterference. Informally, an attacker and 16. Thus, we just have to show that indistinguishability cannot tell the difference between two successful runs ofa is preserved by these operations and under composition. The program that differ only on their secret inputs. To formalize details are discussed in Appendix A.3.  this claim, we follow Abadi et al.’s work on DCC [1] and 6 Gradual guarantees define a family of relations (≈푙)푙∈퐿 that characterize what elements of ⟦푇 ⟧ are indistinguishable to an observer bounded The main novelty of GLIO is that it satisfies the dynamic grad- by 푙 (Figure 17).3 The definition is again circular, but itcanbe ual guarantee [27]: making label annotations more precise solved with Pitts’ framework of relational structures [6, 21], can only introduce dynamic type errors, without otherwise as explained in Appendix A.3. changing the behavior of the program. For base types and references, being indistinguishable Theorem 6.1 (Dynamic Gradual Guarantee, Simple). Sup- simply means being equal. There are two notions of indis- ′ ′ ′ pose that 푒 ⊲ 푒 with ⊢⊥,푙 ̄ 푒 ∶ 푇 and ⊢⊥,푙 ̄ 푒 ∶ 푇 . tinguishability for Lab푙(푋)̄ : weak (≋푙) and strong (≈푙). Weak 2 2 indistinguishability is only an auxiliary notion used to define • If ⟦푒⟧(∅)(∅, ⊥) = ⊥, then ⟦푒′⟧(∅)(∅, ⊥) = ⊥. ′ ′ indistinguishability for computations (LIO ̄ ̄ (푋)). We use • If ⟦푒⟧(∅)(∅, ⊥) = (푚, 푣, 푙), then there exist 푚 and 푣 푙1,푙2 ′ ′ ′ two notions because GLIO guarantees that the label of a such that ⟦푒 ⟧(∅)(∅, ⊥) = (푚 , 푣 , 푙). labeled value reveals nothing about the value, whereas the The premise 푒 ⊲ 푒′, defined on Figure 18, says that 푒′ is PC label at the end of a computation might reveal something obtained from 푒 by replacing some labels on type annota- about its result. An observer bounded by 푙 can distinguish tions with ?. The conclusion says that 푒 and 푒′ must behave two memories if they differ either in their sets of low-stamp similarly, except when 푒 throws an error, in which case 푒′ locations, dom푙, or in two values stored at a low location. can do whatever it wants. In particular, 푒′ can only fail if 푒 Our goal is to prove ⟦푒⟧ ≈푙 ⟦푒⟧ for every well-typed pro- does. gram 푒. This implies that programs do not leak secrets; for ⊥,⊥ GLIO also satisfies the static gradual guarantee, which example, if 푙 = ⊥ and 푒 ∶ Lab?(Bool) −−−→ Bool, we find says that removing label annotations from a term does not that ⟦푒⟧(1@⊤)(∅, ⊥) and ⟦푒⟧(0@⊤)(∅, ⊥) output the same break type checking. boolean if both terminate successfully. ′ ̄ ′̄ Theorem 6.2 (Static Gradual Guarantee). If Γ ⊲ Γ , 푙1 ⊲ 푙1, ′ ′̄ ̄ ′ Theorem 5.1 (Noninterference). If Γ ⊢푙 ̄ ,푙 ̄ 푒 ∶ 푇, we have 푒 ⊲ 푒 , and Γ ⊢푙 ̄ ,푙 ̄ 푒 ∶ 푇, there exist 푙2 ⊳ 푙2 and 푇 ⊳ 푇 such 1 2 ′ ′ 1 2 ′ that Γ ⊢ ′̄ ′̄ 푒 ∶ 푇 . cont 푙1,푙2 ⟦푒⟧ ≈푙 ⟦푒⟧ ∶ ⟦Γ⟧ −−−−→ LIO ̄ ̄ (⟦푇 ⟧). 푙1,푙2 The proof of this result is a straightforward induction on the typing derivation. Theorem 6.1, on the other hand, 3It would be natural to expect indistinguishability to be decreasing with respect to 푙: the more power the attacker has, the more can be distinguished. requires more care, as the statement is not strong enough to However, this property is not required to prove noninterference, as evi- be established directly by induction. We use a generalization denced by similar proofs in the literature [1, 23]. similar to prior formulations of the DGG [19, 20]. Arthur Azevedo de Amorim, Matt Fredrikson, and Limin Jia

Labels that the various operations in the semantics preserve ⊲, 푙 ∈ 퐿 푙 ∈ 퐿 and then argue by composition. This is where it is impor- 푙 ⊲ ? 푙 ⊲ 푙 tant to ensure that casts do not modify labels: to prove the correctness of operations with casts, we must ensure that Types ⟦푇 ≼ 푆⟧ ⊲ ⟦푇 ′ ≼ 푆′⟧ when 푇 ⊲ 푇 ′ and 푆 ⊲ 푆′. If the choice of 푆 or 푆′ had an impact on labels in the results, these two 푇 ∈ {Unit, Bool, Label} 푙 ̄ ⊲ 푙 ̄ 푇 ⊲ 푇 1 2 1 2 functions could not be related. 푇 ⊲ 푇 Ref ̄ (푇 ) ⊲ Ref ̄ (푇 ) 푙1 1 푙2 2 ̄ ̄ 푙1 ⊲ 푙2 푇1 ⊲ 푇2 7 Related work Lab ̄ (푇 ) ⊲ Lab ̄ (푇 ) Gradual Typing and IFC. One of our main inspirations 푙1 1 푙2 2 comes from GSLRef [32], a gradual language for fine-grained ̄ ′̄ ̄ ′̄ IFC. GSL suggests an intriguing tension between gradual 푙1 ⊲ 푙1 푙2 ⊲ 푙2 푇1 ⊲ 푆1 푇2 ⊲ 푆2 Ref ̄ ̄ ′̄ ′̄ typing and noninterference. In principle, it could have vali- 푙1,푙2 푙1,푙2 푇1 −−−→푇2 ⊲ 푆1 −−−→푆2 dated the dynamic gradual guarantee by construction, as it is derived from the AGT methodology [32]. However, a direct Environments application of AGT violated noninterference, just like the dom(Γ1) = dom(Γ2) ∀푥. Γ1(푥) ⊲ Γ2(푥) example in Figure 1 does if we remove the NSU check from info Γ ⊲ Γ 휆 . The solution of GSLRef, unfortunately, was to include 1 2 an analog of the NSU check that breaks the dynamic gradual Terms guarantee. As hinted in the Introduction, we can witness this failure by adapting the example in Figure 1. The reasons, 푒 ⊲ 푒′ 푇 ⊲ 푇 ′ 푒 ⊲ 푒′ 1 1 2 2 however, differ slightly from what we’ve seen earlier. 푒 ⊲ 푒 let(푒 , 푥 ∶ 푇 . 푒 ) ⊲ let(푒′, 푥 ∶ 푇 ′. 푒′) 1 2 1 2 Unlike most dynamic IFC systems, GSLRef does not de- scribe run-time secrecy with single labels, but with intervals ′ ′ 푒1 ⊲ 푒1 푒2 ⊲ 푒2 of plausible labels. As the program runs, these intervals are ′ ′ if(푥, 푒1, 푒2) ⊲ if(푥, 푒1, 푒2) refined to rule out labels that invalidate security checks; if they become empty, an error is signaled. This represen- 푙̄ ⊲ 푙′̄ 푇 ⊲ 푇 ′ 푒 ⊲ 푒′ tation, inherited from AGT, allows omitting label annota- ′ ′ tions entirely from terms and types—a convenient feature fun(푥 ∶ ̄ 푇 . 푒) ⊲ fun(푥 ∶ ′̄ 푇 푒 ) 푙 푙 for retrofitting IFC to existing programs. Because of the inter- 푒 ⊲ 푒′ 푒 ⊲ 푒′ vals, the checks used by GSLRef to enforce noninterference ′ ′ are more complex than the classic NSU; nevertheless, the toLab(푙, 푒) ⊲ toLab(푙, 푒 ) toLab(푥, 푒) ⊲ toLab(푥, 푒 ) gradual guarantee still breaks in the program of Figure 1, because the cast induced by the annotation on b ends up Figure 18. Syntactic dynamism relations modifying the intervals tracked by the program, and thus the result of the NSU analogue. Rather than adopting GSL intervals, GLIO resorts to Theorem 6.3 (Dynamic Gradual Guarantee, General). If Ref ′ ′ ′ ′ ̄ ′̄ classic IFC labels and NSU checks. We believe that this choice Γ ⊢ ̄ ̄ 푒 ∶ 푇, Γ ⊢ ′̄ ′̄ 푒 ∶ 푇 , Γ ⊲ Γ , 푙푖 ⊲ 푙 (∀푖 ∈ {1, 2}), 푙1,푙2 푙1,푙2 푖 simplifies the use of first-class labels in a gradual setting,as ′ ′ ′ cont 푒 ⊲ 푒 and 푇 ⊲ 푇 , then ⟦푒⟧ ⊲ ⟦푒 ⟧ ∶ ⟦Γ⟧ −−−−→ LIO ̄ ̄ (⟦푇 ⟧) ⊲ labelOf b == S 푙1,푙2 it is unclear what the semantics of a test ′ cont ′ should be if labelOf b returns a set of plausible labels rather ⟦Γ ⟧ −−−−→ LIO ′̄ ′̄ (⟦푇 ⟧). 푙1,푙2 than a single label—for instance, the gradual guarantee would The error approximation relations ⟦푒⟧ ⊲ ⟦푒′⟧ in the con- force this result to be consistent for all possible program clusion are defined on Figure 19. Like indistinguishability annotations. Moreover, we can recover some of the benefits in Section 5, they are constructed using Pitts’ work [6, 21] of label intervals because most values are unlabeled in our (cf. Appendix A.4). A technical subtlety is that the relations coarse-grained discipline, and because we could easily use a are heterogeneous: loosening a type 푇 in a term to 푆 requires default label when allocating references (e.g. the PC label). relating of elements of ⟦푇 ⟧ and ⟦푆⟧. Most clauses of the defi- As far as we know, GSLRef was the first work to con- nition simply lift error approximation pointwise, except for sider the dynamic gradual guarantee for an IFC language. LIO, which exhibits the same asymmetry between 푒 and 푒′ ML-GS [11] is an earlier design that predates the guarantee, in Theorem 6.1. which it can violate by rewriting the program of Figure 1 to The proof of Theorem 6.3, detailed in Appendix A.4, fol- classify data through type casts. Other languages use differ- lows the same strategy used for noninterference: we show ent interpretations of gradual typing from the one adopted Reconciling noninterference and gradual typing

CPOs Relation Definition 1, 2, 퐿, Ref푙 ̄ 푥 ⊲ 푦 푥 = 푦 Lab푙(푋)̄ 푥1@푙1 ⊲ 푥2@푙2 푥1 ⊲ 푥2 ∧ 푙1 = 푙2 cont 푋 −−−−→푌 푓 ⊲ 푔 ∀푥 ⊲ 푦. 푓 (푥) ⊲ 푔(푦) LIO푙 ̄ ,푙 ̄ (푋) 푓 ⊲ 푔 ∀푚1 ⊲ 푚2, 푙. (푓 (푚1, 푙) = ⊥ ⇒ 푔(푚2, 푙) = ⊥) ∧ 1 2 ′ ′ ′ ′ ′ ∀푚1, 푥1, 푙 . 푓 (푚1, 푙) = (푚1, 푥1, 푙 ) ′ ′ ′ ′ ′ ⇒ ∃푚2, 푥2. 푔(푚2, 푙) = (푚2, 푥2, 푙 ) ∧ 푚1 ⊲ 푚2 ∧ 푥1 ⊲ 푥2 Mem 푚1 ⊲ 푚2 dom(푚1) = dom(푚2) ∧ ∀푟 ∈ dom(푚1). 푚1(푟) ⊲ 푚2(푟) ⟦Γ⟧ 푠1 ⊲ 푠2 ∀푥 ∈ dom(Γ), 푠1(푥) ⊲ 푠2(푥)

Figure 19. Error approximation on CPOs. The relations are heterogeneous, and the left column should be formally understood ′ as describing pairs of CPOs (e.g. the second row defines a relation (⊲푙,̄푙′̄ ,푋,푋 ′) ⊆ Lab푙(푋)̄ × Lab푙′̄ (푋 ) in terms of another relation ′ (⊲푋,푋 ′) ⊆ 푋 × 푋 ). We will write 푥 ⊲ 푦 ∶ 푋 ⊲ 푌 to indicate the CPOs involved in the relation. here (which goes back to the criteria of Siek et al.[27]), mak- write in System F, we would have to write ing it hard to provide analogues of the gradual guarantee, because removing annotations might require adding casts unseal푋(푒{푋 ≅ Int}(seal푋 1)) + 1 to please the type checker. This behavior appears in the lan- ν guage of Disney and Flanagan [10], which interprets missing for the program to be accepted. PolyG satisfies both the labels in types as maximum secrecy, and in LJGS [12]. DGG and parametricity; crucially, its DGG does not apply to programs that remove occurrences of seal and unseal, since those live at the term level. Our abandon of type-guided Dependent Types and IFC. Moving further away from classification is similar: run-time labels are chosen atthe gradual typing, we find designs that use dependent types to term level, and modifying them falls out of the scope of the make static IFC more flexible, deferring label checks to execu- DGG. This suggests that future tensions with the DGG might tion time. This category includes the HLIO Haskell library [9] be handled by performing at the term level decisions that in and Jif [18, 35]. Instead of making the checking of dynamic se- fully static systems are usually left implicit at the type level. curity levels automatic and guided by the structure of types, these systems require programmers to manually check the 8 Conclusion safety of operations that involve dynamic labels. Thanks to first-class labels, our language allows programmers to per- We presented GLIO, a gradual IFC type system based on the form these tests manually, as in the maybeUpdate function LIO library [30] that features higher-order functions, gen- in Figure 5. However, because of the lack of dependent types, eral references, coarse-grained IFC, security subtyping and our type system cannot use the information learned from first-class labels. In addition to noninterference, our type sys- these tests to rule out errors statically. Bridging the gap be- tem validates the dynamic gradual guarantee, an important tween these two kinds of analyses is an interesting avenue correctness criterion for gradual typing. To avoid pitfalls en- for future work. countered in previous work, we decoupled type annotations from data classification, which our language expresses with typical operations from coarse-grained dynamic IFC. Gradual Types and Parametricity. Until recently, the interaction between polymorphism and gradual typing ex- hibited problems similar to the ones we saw for IFC: there Acknowledgments had been several proposals of languages that combine the The authors would like to thank Éric Tanter, Matías Toro, two features [2, 16, 33], but none of them were able to estab- Justin Hsu and the anonymous reviewers for fruitful dis- lish both the dynamic gradual guarantee and parametricity. cussions and suggestions. This work was supported by NSF Indeed, Toro et al.[33] conjectured both properties to be award 1704542. fundamentally incompatible. To solve this issue, New et al.[20] proposed PolyGν, a poly- References ν morphic calculus based on term-level sealing. In PolyG , if [1] Martín Abadi, Anindya Banerjee, Nevin Heintze, and Jon G. Riecke. we instantiate a polymorphic term 푒 ∶ ∀휈푋. 푋 → 푋 with Int, 1999. A Core Calculus of Dependency. In POPL. ACM, 147–160. the result is not of type Int → Int, but rather of type 푋 → 푋, [2] Amal Ahmed, Dustin Jamner, Jeremy G. Siek, and Philip Wadler. where 푋 is a fresh sealed type generated during execution. 2017. Theorems for free for free: parametricity, with and without types. PACMPL 1, ICFP (2017), 39:1–39:28. To actually use the instantiated function, the sealed type 푋 https://doi.org/10.1145/ 3110283 comes with two conversion functions seal푋 ∶ Int → 푋 and [3] Robert Atkey. 2009. Parameterised notions of computation. J. Funct. unseal푋 ∶ 푋 → Int; thus, instead of 푒 [Int] 1+1, as we would Program. 19, 3-4 (2009), 335–376. Arthur Azevedo de Amorim, Matt Fredrikson, and Limin Jia

[4] Thomas H. Austin and Cormac Flanagan. 2009. Efficient Purely- [21] Andrew M. Pitts. 1996. Relational Properties of Domains. Inf. Comput. dynamic Information Flow Analysis. In Proceedings of the ACM SIG- 127, 2 (1996), 66–90. PLAN Fourth Workshop on Programming Languages and Analysis for [22] François Pottier and Vincent Simonet. 2003. Information flow inference Security (Dublin, Ireland) (PLAS ’09). ACM, New York, NY, USA, 113– for ML. ACM Trans. Program. Lang. Syst. 25, 1 (2003), 117–158. 124. https://doi.org/10.1145/1554339.1554353 [23] Vineet Rajani and Deepak Garg. 2018. Types for Information Flow Con- [5] Arthur Azevedo de Amorim, Nathan Collins, André DeHon, Delphine trol: Labeling Granularity and Semantic Models. In 31st IEEE Computer Demange, Catalin Hritcu, David Pichardie, Benjamin C. Pierce, Randy Security Foundations Symposium, CSF 2018, Oxford, United Kingdom, Pollack, and Andrew Tolmach. 2016. A verified information-flow July 9-12, 2018. 233–246. https://doi.org/10.1109/CSF.2018.00024 architecture. Journal of Computer Security 24, 6 (2016), 689–734. https: [24] Alejandro Russo and Andrei Sabelfeld. 2010. Dynamic vs. Static Flow- //doi.org/10.3233/JCS-15784 Sensitive Security Analysis. In Proceedings of the 23rd IEEE Computer [6] Arthur Azevedo de Amorim, Marco Gaboardi, Justin Hsu, Shin-ya Security Foundations Symposium, CSF 2010, Edinburgh, United Kingdom, Katsumata, and Ikram Cherigui. 2017. A semantic account of metric July 17-19, 2010. 186–199. https://doi.org/10.1109/CSF.2010.20 preservation. In Proceedings of the 44th ACM SIGPLAN Symposium on [25] Amr Sabry and Matthias Felleisen. 1993. Reasoning about Programs Principles of Programming Languages, POPL 2017, Paris, France, January in Continuation-Passing Style. Lisp and Symbolic Computation 6, 3-4 18-20, 2017. 545–556. http://dl.acm.org/citation.cfm?id=3009890 (1993), 289–360. [7] Anindya Banerjee and David A. Naumann. 2005. Stack-based access [26] Jeremy G. Siek and Walid Taha. 2006. Gradual Typing for Func- control and secure information flow. J. Funct. Program. 15, 2 (2005), tional Languages. In IN SCHEME AND FUNCTIONAL PROGRAMMING 131–177. WORKSHOP. 81–92. [8] John Tang Boyland. 2014. The problem of structural type tests ina [27] Jeremy G. Siek, Michael M. Vitousek, Matteo Cimini, and John Tang gradual-typed language. Foundations of Object-Oriented Langauges Boyland. 2015. Refined Criteria for Gradual Typing. In SNAPL (LIPIcs), (2014). Vol. 32. Schloss Dagstuhl - Leibniz-Zentrum fuer Informatik, 274–293. [9] Pablo Buiras, Dimitrios Vytiniotis, and Alejandro Russo. 2015. HLIO: [28] Jeremy G. Siek, Michael M. Vitousek, Matteo Cimini, Sam Tobin- mixing static and dynamic typing for information-flow control in Hochstadt, and Ronald Garcia. 2015. Monotonic References for Ef- Haskell. In Proceedings of the 20th ACM SIGPLAN International Con- ficient Gradual Typing. In Programming Languages and Systems - ference on Functional Programming, ICFP 2015, Vancouver, BC, Canada, 24th European Symposium on Programming, ESOP 2015, Held as Part September 1-3, 2015. 289–301. https://doi.org/10.1145/2784731. of the European Joint Conferences on Theory and Practice of Soft- 2784758 ware, ETAPS 2015, London, UK, April 11-18, 2015. Proceedings. 432–456. [10] Tim Disney and Cormac Flanagan. 2011. Gradual Information Flow https://doi.org/10.1007/978-3-662-46669-8_18 Typing. In Proceedings of the International Workshop on Scripts to Pro- [29] Michael B. Smyth and Gordon D. Plotkin. 1982. The Category-Theoretic grams. Solution of Recursive Domain Equations. SIAM J. Comput. 11, 4 (1982), [11] Luminous Fennell and Peter Thiemann. 2013. Gradual Security Typing 761–783. with References. In CSF. IEEE Computer Society, 224–239. [30] Deian Stefan, David Mazières, John C. Mitchell, and Alejandro Russo. [12] Luminous Fennell and Peter Thiemann. 2016. LJGS: Gradual Secu- 2017. Flexible dynamic information flow control in the presence of rity Types for Object-Oriented Languages. In ECOOP (LIPIcs), Vol. 56. exceptions. J. Funct. Program. 27 (2017), e5. https://doi.org/10. Schloss Dagstuhl - Leibniz-Zentrum fuer Informatik, 9:1–9:26. 1017/S0956796816000241 [13] Cormac Flanagan, Amr Sabry, Bruce F. Duba, and Matthias Felleisen. [31] Deian Stefan, Alejandro Russo, John C. Mitchell, and David Mazières. 1993. The Essence of Compiling with Continuations. In Proceedings 2011. Flexible dynamic information flow control in Haskell. In Haskell. of the ACM SIGPLAN’93 Conference on Programming Language Design ACM, 95–106. and Implementation (PLDI), Albuquerque, New Mexico, USA, June 23-25, [32] Matías Toro, Ronald Garcia, and Éric Tanter. 2018. Type-Driven Grad- 1993. 237–247. https://doi.org/10.1145/155090.155113 ual Security with References. ACM Trans. Program. Lang. Syst. 40, 4 [14] Ronald Garcia, Alison M. Clark, and Éric Tanter. 2016. Abstracting grad- (2018), 16:1–16:55. https://dl.acm.org/citation.cfm?id=3229061 ual typing. In Proceedings of the 43rd Annual ACM SIGPLAN-SIGACT [33] Matías Toro, Elizabeth Labrada, and Éric Tanter. 2019. Gradual para- Symposium on Principles of Programming Languages, POPL 2016, St. metricity, revisited. PACMPL 3, POPL (2019), 17:1–17:30. https: Petersburg, FL, USA, January 20 - 22, 2016, Rastislav Bodík and Ru- //dl.acm.org/citation.cfm?id=3290330 pak Majumdar (Eds.). ACM, 429–442. https://doi.org/10.1145/ [34] Marco Vassena, Alejandro Russo, Deepak Garg, Vineet Rajani, and 2837614.2837670 Deian Stefan. 2019. From fine- to coarse-grained dynamic information [15] Catalin Hritcu, Michael Greenberg, Ben Karel, Benjamin C. Pierce, and flow control and back. PACMPL 3, POPL (2019), 76:1–76:31. Greg Morrisett. 2013. All Your IFCException Are Belong to Us.In IEEE [35] Lantian Zheng and Andrew C. Myers. 2007. Dynamic security labels Symposium on Security and Privacy. IEEE Computer Society, 3–17. and static information flow control. Int. J. Inf. Sec. 6, 2-3 (2007), 67–84. [16] Yuu Igarashi, Taro Sekiyama, and Atsushi Igarashi. 2017. On poly- morphic gradual typing. PACMPL 1, ICFP (2017), 40:1–40:29. https: //doi.org/10.1145/3110284 [17] Paul Blain Levy. 2002. Possible World Semantics for General Storage in Call-By-Value. In CSL (Lecture Notes in Computer Science), Vol. 2471. A Detailed proofs and definitions Springer, 232–246. We detail here definitions and proofs related to the type [18] Andrew C. Myers. 1999. JFlow: Practical Mostly-Static Information system, the semantics of types (Section 4), noninterference Flow Control. In POPL. ACM, 228–241. (Section 5) and the dynamic gradual guarantee (Section 6). [19] Max S. New and Amal Ahmed. 2018. Graduality from embedding- projection pairs. PACMPL 2, ICFP (2018), 73:1–73:30. https://doi. org/10.1145/3236768 [20] Max S. New, Dustin Jamner, and Amal Ahmed. 2020. Graduality and A.1 Auxiliary Definitions parametricity: together again for the first time. Proc. ACM Program. Figure 20 defines the concretization functions 훾 that inter- Lang. 4, POPL (2020), 46:1–46:32. https://doi.org/10.1145/3371114 pret gradual types as sets of annotated types. To define the memory in GLIO, we use a type erasure operation 푇 ∘, which Reconciling noninterference and gradual typing

cont 훾 ∶ 퐿̄ → 풫 (퐿) form 푋 −−−−→푌⊥ equipped with Kleisli composition. We con- Type struct an object 퐷 ∈ CPO equipped with an isomor- 훾(푙) ≜ {푙} ⊥ phism fold ∶ 퐹(퐷, 퐷) ≅ 퐷 by showing that the morphisms 훾(?) ≜ 퐿 Type of CPO⊥ form a CPO with a least element and that the action of 퐹 on morphisms is continuous, among other prop- 훾 ∶ Type → 풫 (Type) erties. We define the interpretation of types by setting 훾(Unit) ≜ {Unit} ⟦푇 ⟧ ≜ 퐷(푇 ) 훾(Bool) ≜ {Bool} LIO푙 ̄ ,푙 ̄ (푋) ≜ LIOF푙 ̄ ,푙 ̄ (퐷, 퐷, 푋) 훾(Label) ≜ {Label} 1 2 1 2 Mem ≜ MemF(퐷), ′ ̄ ′ 훾(Ref푙(푇̄ )) ≜ {Ref푙(푇 ) ∣ 푙 ∈ 훾(푙), 푇 ∈ 훾(푇 )} ′ ̄ ′ which yields the identities of Figure 12. 훾(Lab (푇̄ )) ≜ {Lab푙(푇 ) ∣ 푙 ∈ 훾(푙), 푇 ∈ 훾(푇 )} 푙 You may recall that our semantics treats the result in that 푙 ̄ ,푙 ̄ 푙 ,푙 훾 (푇 −−−→푆1 2 ) ≜ {푇 ′ −−−→푆1 2 ′ ∣ computations in LIO as memory updates rather than the final memory. This choice simplifies the definition of LIOF ′ ̄ 푇 ∈ 훾(푇 ), 푙1 ∈ 훾(푙1), because its action on morphisms is obtained by composing ̄ ′ cont 푙2 ∈ 훾(푙2), 푆 ∈ 훾(푆)} the actions of simpler pieces: (−) −−−−→(−)⊥, MemF, etc. If instead we interpreted the result as being the final memory, Figure 20. Concretization for gradual labels and types we would have to modify LIOF to require that the contents of certain memory locations remain unchanged in the result, which would be inconvenient because the standard action (−)∘ ∶ Type → Type of the functor that maps (푋 −, 푋 +, 푌 ) to Unit∘ ≜ Unit − cont + ∘ MemF(푋 ) × ↓푙 ̄ −−−−→ Error(MemF(푋 ) × 푌 × ↓푙 ̄ ) Bool ≜ Bool 1 2 ⊥ ∘ Label ≜ Label does not preserve this property. ∘ ∘ Ref푙(푇̄ ) ≜ Ref?(푇 ) ∘ ∘ A.3 Proving noninterference Lab푙(푇̄ ) ≜ Lab?(푇 ) To define the indistinguishability relations (≈ ) of Section 5, 푙 ̄ ,푙 ̄ ?,? 푙 (푇 −−−→푆)1 2 ∘ ≜ 푇 ∘ −−→푆∘ we apply the method of Pitts [21], following the formulation of Azevedo de Amorim et al.[6]. We define a CLat∧-fibration Type Figure 21. Label erasure 푞 ∶ Ind → CPO⊥ by a change of base: Ind AdmType ×퐿 replaces all label annotations in 푇 by ?. Its definition is pro- ⌟ 푞 Type ×퐿 vided in Figure 21. As shown in the following result, erasure, 푝 precision and consistent subtyping are naturally related: Type 푓 Type ×퐿 CPO⊥ CPO⊥ Lemma A.1. Label erasure satisfies the following properties where 푝 ∶ Adm → CPO is the CLat -fibration of subsets for all 푇 , 푆 ∈ : ⊥ ∧ Type of CPOs that are closed under limits of chains (so-called ad- ∘ ∘ ∘ • (푇 ) = 푇 . missible subsets), and 푓 (푋)(푇 , 푙) ≜ 푋(푇 ) × 푋(푇 ). This means ∘ ∘ • If 푇 ⊲ 푆, then 푇 ⊲ 푆 . In particular, 푆 ⊲ 푆 . that each object of can be seen as a pair (푋, 푅), where ∘ ∘ ∘ ∘ Ind • If 푇 ⊲ 푆 , then 푇 = 푆 . Type 푋 ∈ CPO and (푅(푇 , 푙) ⊆ 푋(푇 ) × 푋(푇 )) is • If 푇 ≼ 푆, then 푇 ∘ = 푆∘. ⊥ 푇 ∈Type,푙∈퐿 a family of relations closed under limits of chains. More- A.2 Defining the interpretation domains over, 푞 is admissible, in the sense that Ind is canonically a Type ×퐿 The CPOs used to interpret types are defined by solvinga CPO-category derived from Adm , and this structure ̂≈ domain equation with the method of Smyth and Plotkin [29]. is preserved by 푞. We can lift 퐹 to a functor 퐹 on Ind: We express the domain equation using a mixed-variance 표푝 퐹̂≈ Type Ind × Ind Ind functor 퐹 on the CPO-category CPO⊥ , whose action on 푞표푝×푞 푞 objects is shown on Figure 22. Here, CPO⊥ denotes the Kleisli category of the lifting monad (−) on CPO—that is, objects 표푝 ⊥ ( Type) Type 퐹 Type are CPOs, and morphisms are continuous functions of the CPO⊥ × CPO⊥ CPO⊥ Arthur Azevedo de Amorim, Matt Fredrikson, and Limin Jia

Type 표푝 Type Type 퐹 ∶ (CPO⊥ ) × CPO⊥ → CPO⊥ 퐹(푋 −, 푋 +)(Unit) ≜ 1 퐹(푋 −, 푋 +)(Bool) ≜ 2 퐹(푋 −, 푋 +)(Label) ≜ 퐿 − + 퐹(푋 , 푋 )(Ref푙(푇̄ )) ≜ Ref푙 ̄ − + + 퐹(푋 , 푋 )(Lab푙(푇̄ )) ≜ Lab푙(푋̄ (푇 )) ̄ ̄ − + 푙1,푙2 − cont − + + 퐹(푋 , 푋 ) (푇 −−−→푆) ≜ 푋 (푇 ) −−−−→ LIOF ̄ ̄ (푋 , 푋 , 푋 (푆)) 푙1,푙2

Type 표푝 Type LIOF ̄ ̄ ∶ (CPO ) × CPO × CPO → CPO 푙1,푙2 ⊥ ⊥ ⊥ ⊥

− + − cont + LIOF ̄ ̄ (푋 , 푋 , 푌 ) ≜ {푓 ∶ MemF(푋 ) × ↓푙 ̄ −−−−→ Error(MemF(푋 ) × 푌 × ↓푙 ̄ ) ∣ 푙1,푙2 1 2 ⊥ ∀푚1, 푙1, 푥, 푚2, 푙2. 푓 (푚1, 푙1) = (푚2, 푥, 푙2) ⇒ 푙1 ≼ 푙2 ∧ valid(푙1, 푚1, 푚2)}

Type valid(푙1, 푚1, 푚2) ≜ MemF ∶ CPO⊥ → CPO⊥ ∀(푇 , 푟) ∈ dom(푚2). 푙 ≼ 푟 ∧ (푙 ⋠ 푟 ⇒ (푇 , 푟) ∈ dom(푚 )) ∘ 1 label 1 stamp 1 MemF(푋) ≜ (푇 ∶ Type ) × Ref? ⇀fin 푋(푇 )

Figure 22. Functors used to interpret types whose action on objects is given by Lemma A.2. For all 푓 , 푔 ∈ LIO ̄ ̄ , suppose that 푙1,푙2 ̂≈ − − + + ′ ′ ′ ′ 퐹 ((푋 , 푅 ), (푋 , 푅 ))(푇 , 푙) 푓 (푚1, 푙1) = (푚1, 푥1, 푙1) and 푔(푚2, 푙2) = (푚2, 푥2, 푙2). ≜ (퐹(푋 −, 푋 +)(푇 ), 퐹̂≈(푅−, 푅+)(푇 , 푙)), ′ ′ 푅 If 푚1 ≈푙 푚2 and 푙푖 ⋠ 푙 for all 푖, then 푚1 ⃗⊎ 푚1 ≈푙 푚2 ⃗⊎ 푚2 and ′ ′ ̂≈ 푥1@푙1 ≋푙 푥2@푙2. where the relations 퐹푅 are defined in Figure 23. The existence ̂≈ ′ ′ of this lifting means in particular that 퐹푅 depends covariantly Proof. Note that 푙푖 ⋠ 푙, since 푙푖 ≼ 푙푖 for all 푖 by the definition + − ′ ′ on 푅 and contravariantly on 푅 and that it is admissible. of LIO. Hence, 푥1@푙1 ≋푙 푥2@푙2 vacuously. It remains to show ′ ′ Roughly, the last condition holds because the predicates that 푚1 ⃗⊎ 푚1 ≈푙 푚2 ⃗⊎ 푚2. ′ ′ involved in the definition either mention discrete CPOs, for We first prove that dom푙(푚1 ⃗⊎푚1) = dom푙(푚2 ⃗⊎푚2). Since ′ which all sets are admissible, or relations that are assumed dom푙(푚1) = dom푙(푚2) and for all 푖 we have dom푙(푚푖 ⃗⊎ 푚푖 ) = ′ to be admissible. dom푙(푚푖) ∪ dom푙(푚푖 ), it suffices to show By the aforementioned results, we can construct a family ′ ≈ dom푙(푚 ) ⊆ dom푙(푚푖) of relations (푅퐷(푇 , 푙) ⊆ 퐷(푇 ) × 퐷(푇 ))푇 ∈Type,푙∈퐿 such that 푖 ≈ for all 푖. If (푇 , 푟) ∈ dom(푚′) and 푟 ≼ 푙, we must have (fold푇(푥), fold푇(푦)) ∈ 푅퐷(푇 , 푙) 푖 stamp ≈ 푙푖 ⋠ 푟stamp, since 푙푖 ≼ 푟stamp would imply the contradiction ⇔ (푥, 푦) ∈ 퐹̂ (푅퐷, 푅퐷)(푇 , 푙). 푅 푙푖 ≼ 푙. In this case, the definition of LIO guarantees that Given a type 푇 and elements 푥, 푦 ∈ ⟦푇 ⟧, we pose 푥 ≈푙 푦 if (푇 , 푟) ∈ dom(푚푖), and hence (푇 , 푟) ∈ dom푙(푚푖). ≈ To conclude, we must show (푥, 푦) ∈ 푅퐷(푇 , 푙), and define similar notations for the auxil- iary relations 퐺≈ of Figure 23. Modulo the isomorphisms, fold (푚 ⃗⊎ 푚′)(푇 , 푟)@푟 ≈ (푚 ⃗⊎ 푚′)(푇 , 푟)@푟 this mostly matches the definitions given in Figure 17, except 1 1 label 푙 2 2 label for a slight gap between the definition of ≈푙 for LIO in Fig- for all 푇 and for all 푟, whenever both sides are defined. If ure 17 and the relations 퐺LIO of Figure 23: the conclusion of 푟label ⋠ 푙, this is trivial. Otherwise, we must have (푚푖 ⃗⊎ ′ ′ the latter includes the input memories 푚1 and 푚2, which are 푚푖 )(푇 , 푟) = 푚푖(푇 , 푟) for all 푖: if 푟label ≼ 푙 and 푟 ∈ dom(푚푖 ), absent in the former. Nevertheless, we can show that the two the definition of LIO applied to 푓 implies that 푙1 ≼ 푟label, formulations are equivalent. We begin with the following hence 푙1 ≼ 푙, a contradiction. We conclude because 푚1 ≈푙 auxiliary result, which says that indistinguishability is trivial 푚2.  when the initial PC label is high. Reconciling noninterference and gradual typing

̂≈ − + ′ 퐹푅 (푅 , 푅 )(푇 , 푙) ≜ {(푥, 푥) ∈ 푋(푇 ) × 푋(푇 )} (푇 = Unit, Bool, Label, Ref푙(푇̄ )) ̂≈ − + ′ ′ ≈ + 퐹푅 (푅 , 푅 )(Lab푙(푇̄ ), 푙) ≜ {(푥1@푙 , 푥2@푙 ) ∈ 퐺Lab(푅 (푇 , 푙), 푙)} ≈ 퐺Lab(푅, 푙) ≜ {(푥1@푙1, 푥2@푙2) ∣ ∀푖 ∈ {1, 2}. 푙푖 ≼ 푙 ⇒ ((푥1, 푥2) ∈ 푅 ∧ 푙1 = 푙2)} 푙 ̄ ,푙 ̄ ̂≈ − + 1 2 − ≈ − + 퐹푅 (푅 , 푅 )(푇 −−−→푆, 푙) ≜ {(푓 , 푔) ∣ ∀(푥, 푦) ∈ 푅 (푇 , 푙). (푓 (푥), 푔(푦)) ∈ 퐺LIO(푅 , 푅 , 푙)} ≈ − + ′ ′ ′ 퐺LIO(푅 , 푅 , 푙) ≜ {(푓 , 푔) ∣ ∀푚1, 푚2, 푙 ≼ 푙, 푚1, 푚2, 푥1, 푥2, 푙1, 푙2. ≈ − dom푙(푚1) = dom푙(푚2) ∧ (푚1, 푚2) ∈ 퐺Mem(푅 , 푙) ′ ′ ′ ′ ∧ 푓 (푚1, 푙 ) = (푚1, 푥1, 푙1) ∧ 푔(푚2, 푙 ) = (푚2, 푥2, 푙2) ⇒ ′ ′ dom푙(푚1 ⃗⊎ 푚1) = dom푙(푚2 ⃗⊎ 푚2) ′ ′ ≈ + ≈ + ∧ (푚1, 푚2) ∈ 퐺Mem(푅 , 푙) ∧ (푥1@푙1, 푥2@푙2) ∈ 퐺Lab(푅 , 푙)} ≈ 퐺Mem(푅, 푙) ≜ {(푚1, 푚2) ∣ ∀(푇 , 푟) ∈ dom(푚1) ∩ dom(푚2). ≈ (푚1(푇 , 푟)@푟label, 푚2(푇 , 푟)@푟label) ∈ 퐺Lab(푅(푇 , 푙), 푙)}

≈ Figure 23. Relational lifting of 퐹 for indistinguishability, along auxiliary definitions. Note that the 푅 parameter of 퐺Lab is a single relation, and not a family of relations.

Lemma A.3. Given 푓 , 푔 ∈ LIO ̄ ̄ (푋), we have 푓 ≈ 푔 in the We are now ready to proceed with the proof of noninter- 푙1,푙2 푙 ≈ ≈ ≈ ference. We begin with a few auxiliary lemmas about the sense of Figure 17 if and only if (푓 , 푔) ∈ 퐺LIO(푅퐷, 푅퐷, 푙); that is, when 푓 and 푔 satisfy indistinguishability relation. ′ ′ ′ Lemma A.4. Let ≡ denote one of ≈ or ≋ . ∀푚1 ≈푙 푚2, 푙 ≼ 푙, 푚1, 푚2, 푥1, 푥2, 푙1, 푙2. 푙 푙 푙 ′ ′ ′ ′ 푓 (푚 , 푙′) = (푚′, 푥 , 푙 ) ∧ 푔(푚 , 푙′) = (푚′, 푥 , 푙 ) ⇒ 1. 푥@푙 ≈푙 푦@푙 ⇔ 푥@푙 ≋푙 푦@푙 1 1 1 1 2 2 2 2 ′ ′ ′ ′ ′ 2. If 푥 ≈푙 푦, then 푥@푙 ≡푙 푦@푙 for any 푙 . dom푙(푚1 ⃗⊎ 푚1) = dom푙(푚2 ⃗⊎ 푚2) ′ ′ 3. If 푥@푙푥 ≡푙 푦@푙푦, then 푥@(푙푥 ⋎ 푙 ) ≡푙 푦@(푙푦 ⋎ 푙 ). ′ ′ ≈ ≈ ∧ (푚1, 푚2) ∈ 퐺Mem(푅퐷, 푙) 4. If 푥@푙푥 ≋푙 푦@푙푦, then either 푙푥 = 푙푦 ≼ 푙 and 푥 ≈푙 푦 or ∧ 푥1@푙1 ≋푙 푥2@푙2. 푙푥 ⋠ 푙 and 푙푦 ⋠ 푙. ′ ≈ ≈ ≈ Proof. 1. By definition, the first relation is just 푥@푙 ≋푙 Proof. Write 푓 ≡푙 푔 for (푓 , 푔) ∈ 퐺LIO(푅퐷, 푅퐷, 푙) and 푚1 ≡푙 ≈ ≈ 푦@푙′ ∧ 푙′ = 푙′. 푚2 for (푚1, 푚2) ∈ 퐺 (푅퐷, 푙). Note that 푚1 ≈푙 푚2 ⇔ Mem 2. By the previous item, it suffices to show 푥@푙′ ≋ 푦@푙′. dom푙(푚1) = dom푙(푚2) ∧ 푚1 ≡푙 푚2. 푙 Unfolding definitions, this means showing that 푙′ ≼ 푙 (⇒) When all the premises of 푓 ≡푙 푔 are satisfied, we ′ implies 푥 ≈ 푦 and 푙′ = 푙′, which follows from the can apply the hypothesis 푓 ≈푙 푔 to conclude 푚1 ⃗⊎ 푚1 ≈푙 푙 ′ ′ ′ assumption. 푚2⃗⊎푚2 and 푥1@푙1 ≋푙 푥2@푙2. It suffices to show that 푚1 ≡푙 푚2. ′ ′ 3. First, suppose that ≡ is ≋ . Assume that one of 푙 ⋎ 푙′ Suppose that we have (푇 , 푟) ∈ dom(푚1) ∩ dom(푚2). This 푙 푙 푥 ′ ′ or 푙 ⋎ 푙′ is below 푙. This implies that one of 푙 or 푙 is implies (푇 , 푟) ∈ dom(푚1 ⃗⊎ 푚1) ∩ dom(푚2 ⃗⊎ 푚2), which yields, 푦 푥 푦 thanks to the above hypothesis, below 푙. From the assumption 푥@푙푥 ≋푙 푦@푙푦, we find that 푥 ≈푙 푦 and 푙푥 = 푙푦. We conclude by appealing to ′ 푚1(푇 , 푟)@푟label the previous item. ′ Next, suppose that ≡ is ≈ . By definition, we have = (푚1 ⃗⊎ 푚1)(푇 , 푟)@푟label 푙 푙 ′ 푥@푙푥 ≋푙 푦@푙푦 and 푙푥 = 푙푦. The previous sub-proof ≈푙 (푚2 ⃗⊎ 푚2)(푇 , 푟)@푟label ′ ′ shows 푥@(푙푥 ⋎푙 ) ≋푙 푦@(푙푦 ⋎푙 ), which implies 푥@(푙푥 ⋎ ′ ′ ′ = 푚2(푇 , 푟)@푟label. 푙 ) ≈푙 푦@(푙푦 ⋎ 푙 ) by definition. 4. Either 푙푥 ≼ 푙 ∨ 푙푦 ≼ 푙 or 푙푥 ⋠ 푙 ∧ 푙푦 ⋠ 푙. In the latter case, we are done. In the former case, the definition of ≋푙 (⇐) Suppose we have values that satisfy the premises of implies 푥 ≈푙 푦 and 푙푥 = 푙푦, allowing us to conclude. ′ 푓 ≈푙 푔. There are two cases to consider. If 푙 ⋠ 푙, it suffices  to apply Lemma A.2. Otherwise, if 푙′ ≼ 푙, we can apply the ′ Lemma A.5. Indistinguishability on memories satisfies the hypothesis 푓 ≡푙 푔 and conclude dom푙(푚1 ⃗⊎ 푚1) = dom푙(푚2 ⃗⊎ ′ ′ ′ following properties. 푚2), 푚1 ≡푙 푚2 and 푥1@푙1 ≋푙 푥2@푙2. We conclude by noting ′ ′ that ≡푙 is stable under ⃗⊎, so that 푚1 ⃗⊎ 푚1 ≡푙 푚2 ⃗⊎ 푚2 and thus 1. ∅ ≈푙 ∅ ∶ Mem ′ 푚1 ⃗⊎ 푚1 ≈푙 푚2 ⃗⊎ 푚2.  2. If 푣1 ≈푙 푣2, then [푇 , 푟 ↦ 푣1] ≈푙 [푇 , 푟 ↦ 푣2] Arthur Azevedo de Amorim, Matt Fredrikson, and Limin Jia

′ ′ ̄ ‴ ‴ 3. If 푚1 ≈푙 푚2 ∶ Mem and 푚1 ≈푙 푚2 ∶ Mem, then with 푚1 ≈푙 푚2 and 푙1 ∈ ↓푙1. We have to show that 푚1 ≈푙 푚2 ′ ′ ″ ″ ″ ″ 푚1 ⃗⊎ 푚1 ≈푙 푚2 ⃗⊎ 푚2 ∶ Mem and 푣1 @푙1 ≋푙 푣2 @푙2 . By the definition of bind, there are ′ ″ ′ ′ 푚푖 , 푚푖 , 푣푖 and 푙푖 for 푖 ∈ {1, 2} such that Proof. 1. Trivial; the domains are empty, so there are no ′ ′ ′ ′ ′ ′ ″ ″ ″ locations to relate. 푓푖(푚푖, 푙1) = (푚푖 , 푣푖 , 푙푖 ) 푔푖(푣푖 )(푚푖 ⃗⊎ 푚푖 , 푙푖 ) = (푚푖 , 푣푖 , 푙푖 ) 2. Since the domains on both sides are equal to {(푇 , 푟)}, ‴ ′ ″ 푚푖 = 푚푖 ⃗⊎ 푚푖 . we just have to show that 푣1@푟label ≈푙 푣2@푟label. This ′ ′ ′ ′ follows from the assumption and from Lemma A.4. The hypothesis on 푓푖 implies 푚1 ⃗⊎푚1 ≈푙 푚2 ⃗⊎푚2, and 푣1@푙1 ≋푙 ″ ′ ′ ′ 3. Let 푚푖 = 푚푖 ⃗⊎ 푚푖 for 푖 ∈ {1, 2}. We first need to 푣2@푙2. By Lemma A.4, there are two cases to consider. If ″ ′ ′ ′ ′ show that the public domains are equal: dom푙(푚1 ) = 푙1 = 푙2 ≼ 푙, we know that 푣1 ≈푙 푣2. By the hypothesis on the ″ ′ ′ ‴ ‴ dom푙(푚2 ). This follows because 푔푖, we find that 푔1(푣1) ≈푙 푔2(푣2), implying 푚1 ≈푙 푚2 and ″ ″ ″ ″ ′ 푣1 @푙1 ≋푙 푣2 @푙2 and concluding this case. Otherwise, 푙푖 ⋠ 푙 dom (푚″) 푙 1 for all 푖, and we conclude with Lemma A.2.  = dom (푚 ) ∪ dom (푚′) 푙 1 푙 1 We now show that the primitives used to define the se- ′ = dom푙(푚2) ∪ dom푙(푚2) (by assumption) mantics also preserve indistinguishability. ″ = dom푙(푚2 ). ̄ ̄ Lemma A.7 (Label cast noninterference). If 푙1 ≼ 푙2, we have ⟦푙 ̄ ≼ 푙 ̄ ⟧ ≈ ⟦푙 ̄ ≼ 푙 ̄ ⟧ ∶ LIO ̄ ̄ (1). Now, suppose that we have some 푇 and some 푟 such 1 2 푙 1 2 푙1,푙2 ″ ″ that (푇 , 푟) ∈ dom(푚1 ) ∩ dom(푚2 ). We need to show ′ ′ ′ Proof. Suppose that we have 푚1 ≈푙 푚2, 푙 , 푚1, 푚2, 푙1 and 푙2 ″ ″ such that 푚1 (푇 , 푟)@푟label ≈푙 푚2 (푇 , 푟)@푟label. ̄ ̄ ′ ′ ⟦푙1 ≼ 푙2⟧(푚1, 푙 ) = (푚1, 1, 푙1) Thus, assume 푟label ≼ 푙. The definition of references im- ̄ ̄ ′ ′ plies that 푟stamp ≼ 푟label, so 푟stamp ≼ 푙 as well. The hy- ⟦푙1 ≼ 푙2⟧(푚2, 푙 ) = (푚2, 1, 푙2). ′ potheses imply dom푙(푚1) = dom푙(푚2) and dom푙(푚1) = ′ ′ ′ We need to show that 푚1 ⃗⊎ 푚1 ≈푙 푚2 ⃗⊎ 푚2 and 1@푙1 ≋푙 1@푙2. dom푙(푚 ), and therefore 2 The last point follows by Lemma A.4, since 1 ≈푙 1 ∶ 1 by ̄ ̄ (푇 , 푟) ∈ dom(푚 ) ⇔ (푇 , 푟) ∈ dom(푚 ) definition. As for the first point, the definition of ⟦푙1 ≼ 푙2⟧ 1 2 ′ ′ ′ ′ ̄ ′ ′ implies 푚1 = 푚2 = ∅, 푙1 = 푙2 = 푙 and 푙 ∈ ↓푙2, and we (푇 , 푟) ∈ dom(푚1) ⇔ (푇 , 푟) ∈ dom(푚2). conclude with the assumption 푚1 ≈푙 푚2.  ″ ″ Since (푇 , 푟) ∈ dom(푚1 ) and (푇 , 푟) ∈ dom(푚2 ), there Lemma A.8 (Cast noninterference). If 푇 ≼ 푆, then ⟦푇 ≼ are two cases to consider. ′ ′ 푆⟧ ≈푙 ⟦푇 ≼ 푆⟧ for all 푙. • (푇 , 푟) ∈ dom(푚1) and (푇 , 푟) ∈ dom(푚2). In this case, ″ ′ for every 푖 ∈ {1, 2} we have 푚푖 (푇 , 푟) = 푚푖 (푇 , 푟), and Proof. We must show that applying a cast to indistinguish- ′ ′ we conclude by using the assumption 푚1 ≈푙 푚2. able values yields indistinguishable results. We proceed by • (푇 , 푟) ∈ dom(푚1) and (푇 , 푟) ∈ dom(푚2) while (푇 , 푟) ∉ induction on the derivation of 푇 ≼ 푆. The cases of Unit, Bool, ′ ′ dom(푚1) and (푇 , 푟) ∉ dom(푚2). In this case, for ev- Label and function types follow by composition, Lemma A.7, ″ ery 푖 ∈ {1, 2} we have 푚푖 (푇 , 푟) = 푚푖(푇 , 푟), and we and the induction hypotheses. For 푓 = ⟦Lab ̄ (푇 ) ≼ Lab ̄ (푇 )⟧, let 푣 @푙 ≈ 푣 @푙 be in- conclude by using the assumption 푚1 ≈푙 푚2. 푙1 1 푙2 2 1 1 푙 2 1  distinguishable values. Assume that 푓 (푣1@푙1) and 푓 (푣2@푙1) succeed, otherwise the result is trivial. It must be the case that ′ ′ Lemma A.6. We have there are values 푣1 = ⟦푇1 ≼ 푇2⟧(푣1) and 푣2 = ⟦푇1 ≼ 푇2⟧(푣2), so that 푓 (푣 @푙 ) = return(푣′@푙 ) for all 푖 ∈ {1, 2}. We con- 1. return ≈푙 return ∶ 푋 → LIO푙,̄푙(푋)̄ 푖 1 푖 1 2. bind ≈ bind ∶ LIO ̄ ̄ (푋) × (푋 → LIO ̄ ̄ (푌 )) → clude by combining Lemma A.6 with the induction hypothe- 푙 푙1,푙2 푙2,푙3 sis on 푇1 and 푇2. The case of reference types is similar, but LIO푙 ̄ ,푙 ̄ (푌 ) 1 3 without the need to analyze the inner cast.  Proof. For the first point, unfolding definitions, we have to ′ ̄ Lemma A.9. Each primitive 푓 ∶ 푋 in Figure 14 satisfies show that, whenever 푥1 ≈푙 푥2, 푚1 ≈푙 푚2 and 푙 ∈ ↓푙, we have ′ ′ 푓 ≈푙 푓 ∶ 푋. 푚1 ≈푙 푚2 (which was assumed) and 푥1@푙 ≋푙 푥2@푙 (which follows from Lemma A.4). Proof. Case unlabel. Suppose we are given labeled values ′ ′ For the second point, suppose that we have 푓1 ≈푙 푓2 ∶ 푣1@푙 ≈푙 푣2@푙 , memories 푚1 ≈푙 푚2 and a label 푙1. Unfolding LIO푙 ̄ ,푙 ̄ (푋) and 푔1 ≈푙 푔2 ∶ 푋 → LIO푙 ̄ ,푙 ̄ (푌 ). We must show definitions, we have to show that 푚1 ≈푙 푚2 (obvious) and 1 2 2 3 ′ ′ that bind(푓 , 푔 ) ≈ bind(푓 , 푔 ) ∶ LIO ̄ ̄ (푌 ). Unfolding 푣1@(푙 ⋎ 푙1) ≋푙 푣2@(푙 ⋎ 푙1) (which follows from Lemma A.4). 1 1 푙 2 2 푙1,푙3 what this means, suppose that Case get푙 ̄ ,푙 ̄ ,푇. Suppose we are given a reference 푟, mem- ‴ ″ ″ 1 2 bind(푓푖, 푔푖)(푚푖, 푙1) = (푚푖 , 푣푖 , 푙푖 ) (푖 ∈ {1, 2}), ories 푚1 ≈푙 푚2, and a PC label 푙1. We can assume that Reconciling noninterference and gradual typing

∘ 푚푖(푇 , 푟) = 푣푖 for some 푣푖, otherwise get returns an error and Thus, we have to show ⟦푒⟧(푠1[푥 ↦ 푣1]) ≈푙 ⟦푒⟧(푠2[푥 ↦ 푣2]) the result is trivial. We have to show that 푣1@(푙1 ⋎ 푟label) ≋푙 for all arguments 푣1 ≈푙 푣2. This follows because 푠1[푥 ↦ 푣2@(푙1 ⋎ 푟label). By Lemma A.4, it suffices to show that 푣1] ≈푙 푠2[푥 ↦ 푣2], and by the definition of indistinguishabil- 푣1@푟label ≈푙 푣2@푟label, which follows from the hypothesis ity for functions. on the memories. Case app. By composition, it suffices to show that the last Case set ̄ ̄ . Suppose we are given a reference 푟, values 푙1,푙2,푇 clause of the semantics of app respects indistinguishability. 푣1 ≈푙 푣2, memories 푚1 ≈푙 푚2 and a PC label 푙1. We can ∘ Unfolding what this means, we have to show that 푠1(푓 )(푣1) ≈푙 assume that 푙 ≼ 푟 and (푇 , 푟) ∈ (푚 ) for all 푖, other- ̄ ̄ 1 label dom 푖 푙1,푙2 wise set returns an error and the result is trivial. We have to 푠2(푓 )(푣2) whenever 푠1 ≈푙 푠2 ∶ ⟦Γ⟧, Γ(푓 ) = 푇 −−−→ 푆 and show 1@푙1 ≋푙 1@푙1, which is trivial, and 푣1 ≈푙 푣2 ∶ ⟦푇 ⟧. This follows by the definition of indistin- 푙 ̄ ,푙 ̄ ∘ ∘ 1 2 푚1 ⃗⊎ [푇 , 푟 ↦ 푣1] ≈푙 푚2 ⃗⊎ [푇 , 푟 ↦ 푣2], guishability for ⟦푇 −−−→푆⟧.  which follows from Lemma A.5. ∘ A.4 Proving the gradual guarantees Note that the side conditions 푙1 ≼ 푟label and (푇 , 푟) ∈ The construction of the error approximation relations is sim- dom(푚푖) are not invoked to show noninterference for this case. Instead, they are needed to ensure that set returns ilar to indistinguishability, but takes place in the admissible Type an element of LIO, whose properties guarantee that bind CLat∧-fibration 푟 ∶ Appr → CPO⊥ defined as follows. Type respects indistinguishability. An object of Appr is a pair (푋, 푅) where 푋 ∈ CPO⊥ and (푅(푇 ⊲ 푆) ⊆ 푋(푇 ) × 푋(푆))푇 ⊲푆 is a family of chain-complete Case new ̄ ̄ . Let 푣 ≈ 푣 be values, 푚 ≈ 푚 be memo- 푙1,푙2,푇 1 푙 2 1 푙 2 relations. A morphism of type (푋, 푅) → (푌 , 푈 ) is a family ries, 푙1 be a PC label, and 푙2 be a label for the new reference. of partial functions (푓푇 ∶ 푋(푇 ) → 푌 (푇 )⊥)푇 ∈Type such that, Assume that 푙1 ≼ 푙2, otherwise the two sides raise an error for every (푥푇, 푥푆) ∈ 푅(푇 ⊲ 푆), either 푓푇(푥푇) = 푓푆(푥푆) = ⊥ and the result is trivial. The hypotheses on 푚1 and 푚2 imply ∘ or 푓푇(푥푇) = 푦푌 ∈ 푌 (푇 ), 푓푆(푥푆) = 푦푆 ∈ 푌 (푆) and (푦푇, 푦푆) ∈ that min{푛 ∣ (푇 , (푛, 푙1, 푙2)) ∉ dom(푚푖)} is the same for 푖 = 1 푈 (푇 ⊲ 푆). The 푟 functor simply projects the 푋 component and 푖 = 2. Call this number 푛, and set 푟 = (푛, 푙1, 푙2). The results ∘ and acts as the identity on morphisms. of each execution are of the form ([푇 , 푟 ↦ 푣푖], 푟, 푙1), and ̂⊲ ∘ ∘ We lift 퐹 to a functor 퐹 on Appr: we have to show that 푚1 ⃗⊎ [푇 , 푟 ↦ 푣1] ≈푙 푚2 ⃗⊎ [푇 , 푟 ↦ 푣2] 표푝 퐹̂⊲ and 푟@푙1 ≋푙 푟@푙1. The first point follows by Lemma A.5. As Appr × Appr Appr for the second point, it holds by Lemma A.4, since 푟 ≈푙 푟 표푝 푞 holds trivially. 푞 ×푞 Type 표푝 Type 퐹 Type Case toLab ̄ ̄ ̄ . Suppose that we are given 푙 ∈ 훾(푙 ̄ ), (CPO⊥ ) × CPO⊥ CPO⊥ 푙1,푙2,푙3 1 1 푓 ≈ 푓 ∶ LIO ̄ ̄ (푋), 푚 ≈ 푚 . By the definition of toLab, 1 푙 2 푙2,푙3 1 푙 2 whose definition is given in Figure 19, following similar ′ ′ ′ we can suppose that 푓푖(푚푖, 푙2) = (푚푖 , 푣푖, 푙푖 ) and 푙푖 ≼ 푙1 ⋎ 푙2 conventions as in Appendix A.3. This allows us to construct ′ ′ for some 푚푖 , 푣푖 and 푙푖 , with 푖 ∈ {1, 2}. We have to show that (푅⊲(푇 ⊲ 푆) ⊆ 퐷(푇 ) × 퐷(푆)) such that ′ ′ 퐷 푚1 ⃗⊎ 푚 ≈푙 푚2 ⃗⊎ 푚 and 푣1@푙1@푙2 ≋푙 푣2@푙1@푙2. By the 1 2 ⊲ hypothesis on the 푓푖, we know that the first condition holds, (fold푇(푥), fold푆(푦)) ∈ 푅퐷(푇 ⊲ 푆) ′ ′ ⊲ ⊲ ⊲ and also that 푣1@푙1 ≋푙 푣2@푙2. If 푙2 ≼ 푙 and 푙1 ≼ 푙, we know ⇔ (푥, 푦) ∈ 퐹 (푅 , 푅 )(푇 ⊲ 푆) ′ ′ 푅 퐷 퐷 that 푙1 and 푙2 are below 푙 as well. Hence, 푣1 ≈푙 푣2, and we which we take as the definition of the error approximation conclude by applying Lemma A.4.  relations of Figure 19. Taken together, these lemmas lead to our main result. Having defined error approximation, we are ready to prove Theorem 5.1 (Noninterference). If Γ ⊢ ̄ ̄ 푒 ∶ 푇, we have the gradual guarantees. We begin with a few auxiliary results 푙1,푙2 that show that loosening the labels in a program does not cont ⟦푒⟧ ≈ ⟦푒⟧ ∶ ⟦Γ⟧ −−−−→ LIO ̄ ̄ (⟦푇 ⟧). interfere with subtyping or joins. 푙 푙1,푙2 ̄ ̄ Proof. By induction on the typing derivation of 푒, combining Lemma A.10 (Dynamism and subtyping). If 푙1 ⊲ 푙2, then ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ the previous preservation results. We detail some cases here. 푙1 ≼ 푙 implies 푙2 ≼ 푙 and 푙 ≼ 푙1 implies 푙 ≼ 푙2. If 푇1 ⊲ 푇2, then 푇1 ≼ 푆 implies 푇2 ≼ 푆 and 푆 ≼ 푇1 implies 푆 ≼ 푇2. In particular, Case pcLabel. Suppose we are given memories 푚1 ≈푙 푚2 since all relations are reflexive, ⊲ and ⊳ are contained in ≼. and a PC label 푙1. By Lemmas A.4 and A.5, we know ∅ ≈푙 ∅ and 푙1@푙1 ≋푙 푙1@푙1, which concludes this case. In light of this lemma, we will write ⟦푇 ⊲ 푆⟧ (or ⟦푇 ⊳ 푆⟧) instead of ⟦푇 ≼ 푆⟧ when 푇 ⊲ 푆 (or 푇 ⊳ 푆) holds. We will Case fun. It suffices to show that 휆푣.⟦푒⟧(푠1[푥 ↦ 푣]) ≈푙 adopt a similar convention for label casts. 휆푣.⟦푒⟧(푠2[푥 ↦ 푣]) assuming that ⟦푒⟧ ≈푙 ⟦푒⟧ and 푠1 ≈푙 푠2. Arthur Azevedo de Amorim, Matt Fredrikson, and Limin Jia

̂⊲ − + 퐹푅 (푅 , 푅 )(푇 ⊲ 푇 ) ≜ {(푥, 푥) ∈ 푋(푇 ) × 푋(푇 )} (푇 = Unit, Bool, Label) ̂⊲ − + ′ 퐹푅 (푅 , 푅 )(Ref푙(푇̄ ) ⊲ Ref푙′̄ (푇 )) ≜ {(푥, 푥) ∣ 푥 ∈ 푋(Ref푙(푇̄ ))} ̂⊲ − + ′ ′ ′ + ′ 퐹푅 (푅 , 푅 )(Lab푙(푇̄ ) ⊲ Lab푙′̄ (푇 )) ≜ {(푥@푙, 푥 @푙) ∣ (푥, 푥 ) ∈ 푅 (푇 ⊲ 푇 )} 푙 ̄ ,푙 ̄ 푙′̄ ,푙′̄ ̂⊲ − + 1 2 ′ 1 2 ′ ′ ′ − ′ ′ ⊲ − 퐹푅 (푅 , 푅 )(푇1 −−−→푇2 ⊲ 푇1 −−−→푇2 ) ≜ {(푓 , 푓 ) ∣ ∀(푥1, 푥1) ∈ 푅 (푇1 ⊲ 푇1 ), (푚1, 푚1) ∈ 퐺Mem(푅 ), 푙1. ′ ′ ′ (푓 (푥1)(푚1, 푙1) = ⊥ ⇒ 푓 (푥1)(푚1, 푙1) = ⊥) ∧ ∀푥2, 푚2, 푙2. 푓 (푥1)(푚1, 푙1) = (푚2, 푥2, 푙2) ⇒ ′ ′ ′ ′ ′ ′ ′ ∃푥2, 푚2. 푓 (푥1)(푚1, 푙1) = (푚2, 푥2, 푙2) ′ + ′ ′ ⊲ + ∧ (푥2, 푥2) ∈ 푅 (푇2 ⊲ 푇2 ) ∧ (푚2, 푚2) ∈ 퐺Mem(푅 )} ⊲ 퐺Mem(푅) ≜ {(푚1, 푚2) ∣ dom(푚1) = dom(푚2) ∧ ∀(푇 , 푟) ∈ dom(푚1).(푚1(푇 , 푟), 푚2(푇 , 푟)) ∈ 푅(푇 ⊲ 푇 )}

′ Figure 24. Lifting of the functor 퐹 for error approximation. The clause for Ref assumes that 푋(Ref푙(푇̄ )) ⊆ 푋(Ref푙′̄ (푇 )) when 푙̄ ⊲ 푙′̄ . Strictly speaking, this is not valid for the entire domain of definition of the functor 퐹, but we can show that 퐹 does preserve this property, so there is no harm in assuming it holds.

Lemma A.11 (Dynamism, joins and meets). Let ⊕ ∈ {⋎, ⋏}. First, suppose that bind(푓1, 푔1)(푚1, 푙) = ⊥. There are two ̄ ′̄ ̄ ′̄ ̄ ̄ ′̄ ′̄ ′ ′ If 푙1 ⊲ 푙1 and 푙2 ⊲ 푙2, then 푙1 ⊕푙2 ⊲ 푙1 ⊕푙2. If 푇 ⊲ 푇 , 푆 ⊲ 푆 , and cases to consider. If 푓1(푚1, 푙) = ⊥, we have 푓2(푚2, 푙) = ⊥ by ′ ′ ′ ′ 푇 ⊕푆 is well-defined, then so is 푇 ⊕푆 ; moreover, 푇 ⊕푆 ⊲ 푇 ⊕푆 . the assumption on the 푓푖, and thus bind(푓2, 푔2)(푚2, 푙) also ′ Lemma A.12. If 푙̄ ⊲ 푙′̄ , then 훾(푙)̄ ⊆ 훾(푙′̄ ) and ↓푙̄ ⊆ ↓푙′̄ . diverges. Otherwise, it must be the case that there exist 푚1, 푥 and 푙′ such that 푓 (푚 , 푙) = (푚′, 푥 , 푙′) and 푔 (푥 )(푚 ⃗⊎ ′ ̄ ′̄ 1 1 1 1 1 1 1 1 Theorem 6.2 (Static Gradual Guarantee). If Γ ⊲ Γ , 푙1 ⊲ 푙1, 푚′, 푙′) = ⊥. By the hypothesis on the 푓 , we find 푚′ and ′ ′ ′ 1 1 푖 2 푒 ⊲ 푒 , and Γ ⊢ ̄ ̄ 푒 ∶ 푇, there exist 푙 ̄ ⊳ 푙 ̄ and 푇 ⊳ 푇 such ′ ′ ′ ′ ′ 푙1,푙2 2 2 푥2 such that 푓2(푚2, 푙) = (푚 , 푥2, 푙 ), 푚 ⊲ 푚 and 푥1 ⊲ 푥 . ′ ′ ′ 2 1 2 2 that Γ ⊢ ′̄ ′̄ 푒 ∶ 푇 . ′ ′ 푙1,푙2 By Lemma A.13, we find that 푚1 ⃗⊎ 푚1 ⊲ 푚2 ⃗⊎ 푚2. By the ′ ′ Proof. By induction on the typing derivation, using Lem- hypothesis on 푔푖, we find that 푔2(푥2)(푚2 ⃗⊎ 푚2, 푙 ) = ⊥, which mas A.10 to A.12. concludes this case.  ‴ ′ ″ Now, suppose that bind(푓1, 푔1)(푚1, 푙) = (푚1 , 푥1, 푙 ). By Next, we cover a few properties of the error approximation ′ ′ ″ the definition of bind, we find 푚1, 푥1, 푙 and 푚1 such that relation. 푓 (푚 , 푙) = (푚′, 푥 , 푙′) 푔 (푥 )(푚 ⃗⊎ 푚′, 푙′) = (푚″, 푥′, 푙″) Lemma A.13. 1. ∅ ⊲ ∅ 1 1 1 1 1 1 1 1 1 1 ′ ′ ′ ′ 2. If 푚1 ⊲ 푚 and 푚2 ⊲ 푚 , then 푚1 ⃗⊎ 푚2 ⊲ 푚 ⃗⊎ 푚 . ‴ ′ ″ 1 2 1 2 푚1 = 푚1 ⃗⊎ 푚1 . 3. If 푇 ⊲ 푆 and 푥 ⊲ 푦 ∶ 푇 ⊲ 푆, then [푇 ∘, 푟 ↦ 푥] ⊲ ∘ [푆 , 푟 ↦ 푦]. Once again, the hypothesis on the 푓푖 and 푔푖 combined with ′ ′ ″ ″ ̄ ′̄ ′ ′ Lemma A.13 allow us to find 푚2 ⊳ 푚1, 푥2 ⊳ 푥1, 푚2 ⊳ 푚1 Lemma A.14. If 푙푖 ⊲ 푙푖 for 푖 ∈ {1, 2, 3}, 푇 ⊲ 푇 and 푆 ⊲ 푆 , ′ ′ then and 푥2 ⊳ 푥1 such that ′ ′ ′ ′ ″ ′ ″ 1. return ̄ ⊲ return ′̄ ′ 푙1,⟦푇 ⟧ 푙1,⟦푇 ⟧ 푓2(푚2, 푙) = (푚2, 푥2, 푙 ) 푔2(푥2)(푚2 ⃗⊎ 푚2, 푙 ) = (푚2 , 푥2, 푙 ), 2. bind푙 ̄ ,푙 ̄ ,푙 ̄ ,⟦푇 ⟧,⟦푆⟧ ⊲ bind푙′̄ ,푙′̄ ,푙′̄ ,⟦푇 ′⟧,⟦푆′⟧ 1 2 3 1 2 3 which allows us to conclude.  Proof. For return, suppose that we have values 푣 ⊲ 푣′, mem- ′ ̄ ′̄ ̄ ories 푚 ⊲ 푚 and a label 푙. We must show that ∅ ⊲ ∅ (trivial) Lemma A.15. Suppose we have gradual labels 푙1, 푙1, 푙2 and and 푣 ⊲ 푣′ (which follows from the assumption). ′̄ ̄ ′̄ ̄ ̄ ′̄ ′̄ 푙2 such that 푙푖 ⊲ 푙푖 for all 푖 ∈ {1, 2} and 푙1 ≼ 푙2 (and thus 푙1 ≼ 푙2 For , suppose that we have computations ̄ ̄ ′̄ ′̄ bind by Lemma A.10). Then ⟦푙1 ≼ 푙2⟧ ⊲ ⟦푙1 ≼ 푙2⟧. ′ 푓1 ⊲ 푓2 ∶ LIO푙 ̄ ,푙 ̄ (⟦푇 ⟧) ⊲ LIO푙′̄ ,푙′̄ (⟦푇 ⟧), ̄ ′̄ 1 2 1 2 Proof. Suppose that we are given a label 푙1 ∈ ↓푙1 ⊆ ↓푙1 and ′ ̄ ̄ ̄ functions two memories 푚 ⊲ 푚 . If 푙1 ∉ ↓푙2, we have ⟦푙1 ≼ 푙2⟧(푚, 푙1) = cont cont ̄ ′ ′ error, and the result is trivial. Otherwise, we find 푙1 ∈ ↓푙2 ⊆ 푔1 ⊲ 푔2 ∶ ⟦푇 ⟧ −−−−→ LIO ̄ ̄ (⟦푆⟧) ⊲ ⟦푇 ⟧ −−−−→ LIO ′̄ ′̄ (⟦푆 ⟧), 푙2,푙3 푙2,푙3 ′̄ ↓푙2, and we can conclude because both executions result in memories 푚 ⊲ 푚 , and a label 푙. We must show that 1 2 (∅, 1, 푙1).  bind(푓1, 푔1)(푚1, 푙) ⊲ bind(푓2, 푔2)(푚2, 푙). Reconciling noninterference and gradual typing

′ ̄ ′̄ ′ Lemma A.16. Suppose that we have gradual types 푇1, 푇1 , 푇2 Case get. Given 푙푖 ⊲ 푙푖 for all 푖 ∈ {1, 2} and 푇 ⊲ 푇 we must ′ ′ and 푇2 such that 푇푖 ⊲ 푇푖 for all 푖 ∈ {1, 2} and 푇1 ≼ 푇2 (and show ′ ′ ′ ′ thus 푇1 ≼ 푇2 by Lemma A.10). Then ⟦푇1 ≼ 푇2⟧ ⊲ ⟦푇1 ≼ 푇2 ⟧. get ̄ ̄ ⊲ get ′̄ ′̄ ′ 푙1,푙2,푇 푙1,푙2,푇 Proof. By unfolding definitions, we must show that related cont ∘ cont ∘ ∶ Ref ̄ −−−−→ LIO ̄ ̄ ̄ ⟦푇 ⟧ ⊲ Ref ′̄ −−−−→ LIO ′̄ ′̄ ′̄ ⟦푇 ⟧. values are mapped to related results. We proceed by induc- 푙2 푙1,푙1⋎푙2 푙2 푙1,푙1⋎푙2 tion on 푇1 and inversion on the derivations relating the (Recall that (푇 ′)∘ = 푇 ∘; cf. Lemma A.1.) types. The cases of Unit, Bool and Label are trivial, since ̄ ′̄ Suppose that we are given a label 푙1 ∈ ↓푙1 ⊆ ↓푙1, along they reduce to return. The case of function types follows elements by composition, the induction hypotheses, and by applying ′ 푟 ⊲ 푟 ∶ Ref ̄ ⊲ Ref ′̄ 푚 ⊲ 푚 ∶ Mem ⊲ Mem . Lemma A.15. 푙2 푙2 1 1 It remains to show the result for 푇1 = Ref푙 ̄ (푆1) and 푇1 = ∘ 1 If (푇 , 푟) ∉ dom(푚1) = dom(푚2), both executions return Lab ̄ (푆1). We focus on the second case, since the first one is ∘ 푙1 error and the result is trivial. Otherwise, (푇 , 푟) ∈ dom(푚1) = similar. The remaining types are of the form dom(푚2), and the executions return ′ ′ ′ ′ 푇1 = Lab푙′̄ (푆1) 푇2 = Lab푙 ̄ (푆2) 푇2 = Lab푙′̄ (푆2), ∘ ′ ∘ 1 2 2 (∅, 푚1(푇 , 푟), 푙1 ⋎ 푟label) and (∅, 푚1(푇 , 푟), 푙1 ⋎ 푟label). ′ ′ ̄ ′̄ ̄ ′̄ with 푆1 ⊲ 푆1, 푆2 ⊲ 푆2, 푙1 ⊲ 푙1 and 푙2 ⊲ 푙2. Suppose that we are ∘ ′ ∘ ′ We conclude using 푚1(푇 , 푟) ⊲ 푚1(푇 , 푟), a consequence of given related labeled values 푣 @푙 ⊲ 푣 @푙 ∶ Lab ̄ (⟦푆 ⟧) ⊲ 1 1 1 1 푙1 1 푚 ⊲ 푚 . ′ 1 2 Lab ′̄ (⟦푆 ⟧). If 푙 ∉ ↓푙 ̄ , we have ⟦푇 ≼ 푇 ⟧(푣 @푙 ) = 휆(−). error, 푙1 1 1 2 1 2 1 1 ̄ ′̄ ̄ ′̄ ′ and the result is trivial. Otherwise, we have 푙1 ∈ ↓푙2 ⊆ ↓푙2, Case set. Given 푙푖 ⊲ 푙푖 for 푖 ∈ {1, 2} and 푇 ⊲ 푇 , we have which implies to show that

푣2 ← ⟦푆1 ≼ 푆2⟧(푣1); set ̄ ̄ ⊲ set ′̄ ′̄ ′ ⟦푇1 ≼ 푇2⟧(푣1@푙1) = do { 푙1,푙2,푇 푙1,푙2,푇 return(푣2@푙1) ∘ cont ∘ cont ∶ Ref ̄ ×⟦푇 ⟧ −−−−→ LIO ̄ ̄ (1) ⊲ Ref ′̄ ×⟦푇 ⟧ −−−−→ LIO ′̄ ′̄ (1), 푙1 푙2,푙2 푙1 푙2,푙2 ′ ′ ′ ′ ′ ′ ′ 푣2 ← ⟦푆1 ≼ 푆2⟧(푣1); ⟦푇1 ≼ 푇2 ⟧(푣1@푙1) = do { ′ (As in the get case, 푇 does not have to vary.) return(푣2@푙1). ̄ ′̄ Suppose we are given a label 푙1 ∈ ↓푙1 ⊆ ↓푙1 along elements We conclude by composition, applying the induction hypoth- ′ ∘ ∘ ′ ′ 푟 ⊲ 푟 ∶ Ref푙 ̄ ⊲ Ref푙′̄ 푣 ⊲ 푣 ∶ ⟦푇 ⟧ ⊲ ⟦푇 ⟧ esis on 푆1, 푆2, 푆1 and 푆2.  2 2 ′ ′ ′ Corollary A.17. If 푇1 ⊲ 푇1 and 푇2 ⊲ 푇2 , then ⟦푇1 ∶ 푇2⟧ ⊲ 푚1 ⊲ 푚1 ∶ Mem ⊲ Mem . ′ ′ ⟦푇1 ∶ 푇2 ⟧. ∘ ′ Suppose that (푇 , 푟) ∈ dom(푚1) = dom(푚1) and 푙1 ≼ 푟label, ′ ′ Proof. If 푇1 ≼ 푇2, then 푇1 ≼ 푇2 by Lemma A.10, and the otherwise the result follows because ′ ′ result is equivalent to ⟦푇1 ≼ 푇2⟧ ⊲ ⟦푇1 ≼ 푇2 ⟧, which follows ′ ′ set(푟, 푣)(푚1, 푙1) = set(푟, 푣 )(푚1, 푙1) = error . from Lemma A.16. Otherwise, ⟦푇1 ∶ 푇2⟧ = 휆(−). error, and ∘ the result is trivial.  By unfolding the definition of set, we must show that [푇 , 푟 ↦ 푣] ⊲ [푇 ∘, 푟 ↦ 푣′] (follows by Lemma A.13) and 1 ⊲ 1 (triv- Lemma A.18. Each primitive 푓 of Figure 14 satisfies 푓 ⊲ 푓 ial). (given suitable parameters).

Proof. By “given suitable parameters,” we mean that each Case new. We must show that new ̄ ̄ ⊲ new ′̄ ′̄ ′ at the 푙1,푙2,푇 푙1,푙2,푇 primitive is parameterized by CPOs and labels, and we must CPOs choose the parameters correctly for each side of the above ∘ cont 훾(푙 ̄ ) × ⟦푇 ⟧ −−−−→ LIO ̄ ̄ (Ref ̄ ) relation for it to hold. This means that the labels on the 1 푙2,푙2 푙1 left-hand side must be less dynamic than those on the right- ′̄ ∘ cont ⊲ 훾(푙1) × ⟦푇 ⟧ −−−−→ LIO ′̄ ′̄ (Ref ′̄ ) hand side. We provide more precise statements for each case 푙2,푙2 푙1 ̄ ′̄ ′ below. when 푙푖 ⊲ 푙푖 for every 푖 and 푇 ⊲ 푇 . (As in the get case, 푇 does not need to vary.) Case unlabel. We want to show unlabel ̄ ̄ ⊲ unlabel ′̄ ′̄ ′ ∘ ∘ ̄ ′̄ 푙1,푙2 푙1,푙2 Suppose we are given 푣 ⊲ 푣 ∶ ⟦푇 ⟧ ⊲ ⟦푇 ⟧, 푙푖 ∈ ↓푙푖 ⊆ ↓푙푖 ̄ ′̄ ̄ ′ when 푙푖 ⊲ 푙푖 for all 푖. Suppose that we have a label 푙1 ∈ ↓푙1 ⊆ (푖 ∈ {1, 2}) and memories 푚1 ⊲ 푚1. We have to show that ′̄ ′ ′ ′ ′ ′ ↓푙1, labeled values 푣@푙2 ⊲ 푣 @푙2 and memories 푚1 ⊲ 푚1. new(푙1, 푣)(푚1, 푙2) ⊲ new(푙1, 푣 )(푚1, 푙2). Suppose that 푙2 ≼ 푙1, ′ ′ By definition, we have 푙2 = 푙2 and 푣 ⊲ 푣 , and the results of otherwise both terms are equal to error and the result is ′ ′ executing unlabel are (∅, 푣, 푙1 ⋎ 푙2) and (∅, 푣 , 푙1 ⋎ 푙2). Thus, trivial. In this case, since dom(푚1) = dom(푚1), the results ′ ∘ ∘ ′ we have to show ∅ ⊲ ∅ (trivial) and 푣 ⊲ 푣 , which follows are of the form ([푇 , 푟 ↦ 푣], 푟, 푙2) and ([푇 , 푟 ↦ 푣 ], 푟, 푙2) from the assumption. for some reference 푟, and we can conclude. Arthur Azevedo de Amorim, Matt Fredrikson, and Limin Jia

Case toLab. We want to show Case app. We have 푒 = 푒′ = app(푓 , 푥), with ̄ ̄ 푙3,푙2 toLab ̄ ̄ ̄ ⊲ toLab ′̄ ′̄ ′̄ ′ 푙1,푙2,푙3,⟦푇 ⟧ 푙1,푙2,푙3,⟦푇 ⟧ Γ(푓 ) ∶ 푆1 −−−→푇 Γ(푥) ∶ 푆2 푙′̄ ,푙′̄ ̄ ′̄ ′ ′ ′ 3 2 ′ ′ whenever 푙푖 ⊲ 푙푖 for every 푖 and 푇 ⊲ 푇 . Suppose that we Γ (푓 ) ∶ 푆1 −−−→푇 Γ(푥) ∶ 푆2, ̄ ′̄ ̄ ′̄ have labels 푙1 ∈ 훾(푙1) ⊆ 훾(푙1), 푙2 ∈ ↓푙2 ⊆ ↓푙2 and ̄ ′̄ ′ ′ ′ ′ such that 푙3 ⊲ 푙3, 푆1 ⊲ 푆1, 푆2 ⊲ 푆2, 푆2 ≼ 푆1 and 푆2 ≼ 푆1. ′ ′ ′ 푓 ⊲ 푓 ∶ LIO ̄ ̄ (푋) ⊲ LIO ′̄ ′̄ (푋 ) Given environments 푠 ⊲ 푠 , after performing the appropriate 푙2,푙3 푙2,푙3 checks, it suffices to show that 푠(푓 )(푣) ⊲ 푠′(푓 )(푣′) for 푣 ⊲ 푣′. ′ 푚1 ⊲ 푚1 ∶ Mem ⊲ Mem . This follows from the definition of error approximation for environments and for functions.  There are the following cases to consider.

1. If toLab(푙1, 푓 )(푚1, 푙2) = ⊥, we know that 푓 (푚1, 푙2) = ⊥. ′ ′ ′ ′ This implies toLab(푙1, 푓 )(푚1, 푙2) = 푓 (푚1, 푙2) = ⊥ by the above hypothesis, and the conclusion follows. 2. If toLab(푙1, 푓 )(푚1, 푙2) = error, the relation reduces to ′ ′ error ⊲ toLab(푙1, 푓 )(푚1, 푙2), which also holds trivially. 3. Otherwise, toLab(푙1, 푓 )(푚1, 푙2) must be of the form (푚2, 푣2@푙1, 푙2), with 푓 (푚1, 푙2) = (푚2, 푣2, 푙3) and 푙3 ≼ ′ ′ 푙1 ⋎푙2. Since 푓 ⊲ 푓 , it must be the case that 푓 (푚1, 푙2) = ′ ′ ′ ′ (푚2, 푣2, 푙3) with 푚2 ⊲ 푚2 and 푣2 ⊲ 푣2. We conclude ′ ′ ′ ′ that toLab(푙1, 푓 )(푚1, 푙2) = (푚2, 푣2@푙1, 푙2), which im- plies the final result. 

Lemma A.19 (Unique Typing). If Γ ⊢ ̄ ̄ 푒 ∶ 푇 and Γ ⊢ ̄ ′̄ 푙1,푙2 푙1,푙2 ′ ̄ ′̄ ′ 푒 ∶ 푇 , then 푙2 = 푙2 and 푇 = 푇 . Proof. By induction on 푒 and inversion on the typing deriva- tions. 

Theorem 6.3 (Dynamic Gradual Guarantee, General). If ′ ′ ′ ′ ′ Γ ⊢ ̄ ̄ 푒 ∶ 푇, Γ ⊢ ′̄ ′̄ 푒 ∶ 푇 , Γ ⊲ Γ , 푙 ̄ ⊲ 푙 ̄ (∀푖 ∈ {1, 2}), 푙1,푙2 푙1,푙2 푖 푖 ′ ′ ′ cont 푒 ⊲ 푒 and 푇 ⊲ 푇 , then ⟦푒⟧ ⊲ ⟦푒 ⟧ ∶ ⟦Γ⟧ −−−−→ LIO ̄ ̄ (⟦푇 ⟧) ⊲ 푙1,푙2 ′ cont ′ ⟦Γ ⟧ −−−−→ LIO ′̄ ′̄ (⟦푇 ⟧). 푙1,푙2 Proof. By Theorem 6.2 and Lemma A.19, the typing deriva- ′ ′ ′̄ tion of 푒 is entirely determined by that of 푒, plus Γ and 푙1. We proceed by induction on the derivation of 푒 and inver- sion on the derivation of 푒′ for each case. Most cases follow by composition, induction hypotheses, and the results of Lemma A.18; we detail the interesting ones here.

Case pcLabel. Trivial: the results depend only on the PC label, which is the same on both sides.

′ Case fun. We have 푒 = fun(푥 ∶푙 ̄ 푆.푒1) and 푒 = fun(푥 ∶푙′̄ ′ ′ ̄ ′̄ ′ ′ 푆 .푒1) with 푙 ⊲ 푙 , 푆 ⊲ 푆 and 푒1 ⊲ 푒1. By the induction hy- ′ pothesis, we know that ⟦푒1⟧ ⊲ ⟦푒1⟧, implying that ⟦푒1⟧(푠[푥 ↦ ′ ′ ′ ′ 푣]) ⊲ ⟦푒1⟧(푠 [푥 ↦ 푣 ]) for all environments 푠 ⊲ 푠 and ′ arguments 푣 ⊲ 푣 . By definition, 휆푣.⟦푒1⟧(푠[푥 ↦ 푣]) ⊲ ′ ′ ′ ′ ′ 휆푣.⟦푒1⟧(푠 [푥 ↦ 푣 ]), hence ⟦푒⟧(푠) ⊲ ⟦푒 ⟧(푠 ), concluding this case.