Skip to content

Type safety violation and soundness bug with parameterized domain #759

Open
@DebraChait

Description

@DebraChait

The following domain definition is from the 2vyper project here. $Struct defines a domain giving a unique identifier to every element of a struct, and $StructOps defines a domain for struct operations, parameterized by the type of struct element you are getting or setting. (Struct is defined in this way to avoid axioms that need to quantify over types.)

domain $Struct { function $struct_loc($s: $Struct, $m: Int): Int }
domain $StructOps[$T] {
    function $struct_get($l: Int): $T
    function $struct_set($s: $Struct, $m: Int, $t: $T): $Struct
    axiom $get_set_0_ax {
        forall $s: $Struct, $m: Int, $t: $T ::
            { $struct_loc($struct_set($s, $m, $t), $m) }
                $struct_get($struct_loc($struct_set($s, $m, $t), $m)) == $t
    }
    axiom $get_set_1_ax {
        forall $s: $Struct, $m: Int, $n: Int, $t: $T ::
            { $struct_loc($struct_set($s, $n, $t), $m) }
                $m != $n ==> $struct_loc($s, $m) == $struct_loc($struct_set($s, $n, $t), $m)
    }
}

The following does not raise a type error, allowing us to set a Bool variable to an Int value. Furthermore, it exposes a soundness bug, since the assertion (y == true) || (y == false) passes, despite the actual value of y being 10.

method test_struct() {
    var s: $Struct 
    s := $struct_set(s,0,10)
    var y: Bool 
    y := $struct_get($struct_loc(s,0))
    assert (y == true) || (y == false)
}

It seems that the SMT solver assumes that the type checker is catching all type errors, and so relies on the original type of y as a Bool to vacuously verify assert (y == true) || (y == false). However, the type checker does not catch the type safety violation of setting y to 10, leading the solver to verify the false statement (y == true) || (y == false).

(Credit to my advisor Thomas Wies on realizing that the type safety violation can lead to a soundness bug!)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions