Live data from Hacker News

Verus: Verified Rust for low-level systems code

github.com

21–30 of 53 posts

Re: Verus: Verified Rust for low-level systems code

#21

Rust is supposed to be a "safe" language for low level use, and thus has borrow checker, unsafe, etc. Building a "verifier" on top of Rust seems a bit excessive and unneeded. > Developers write specifications of what their code should do ... Verus statically checks ... the specifications for all possible executions of the code This is what tests are for.

Yes, but remember that Erlang bug discussed here last week where somebody apparently messed up SSH state transitions in such a way that people could just log in without having the password or anything?

Buffer overflows etc. are absurd things that should not be possible, but preventing them is the first step towards security.

Re: Verus: Verified Rust for low-level systems code

#22

Rust is supposed to be a "safe" language for low level use, and thus has borrow checker, unsafe, etc. Building a "verifier" on top of Rust seems a bit excessive and unneeded. > Developers write specifications of what their code should do ... Verus statically checks ... the specifications for all possible executions of the code This is what tests are for.

Why is verification excessive but not tests? A verification of a property is stronger than a mere test of a property.

The test is supposed to be the verification.

Re: Verus: Verified Rust for low-level systems code

#23

Rust is supposed to be a "safe" language for low level use, and thus has borrow checker, unsafe, etc. Building a "verifier" on top of Rust seems a bit excessive and unneeded. > Developers write specifications of what their code should do ... Verus statically checks ... the specifications for all possible executions of the code This is what tests are for.

Yes, but remember that Erlang bug discussed here last week where somebody apparently messed up SSH state transitions in such a way that people could just log in without having the password or anything? Buffer overflows etc. are absurd things that should not be possible, but preventing them is the first step towards security.

This is something that Rust should prevent, not another layer on top of Rust.

Re: Verus: Verified Rust for low-level systems code

#24

How does it differ from Prusti and Creusot? I feel, with more and more tools crowding that space, a common specification language would make sense. Sure, every tool has its own unique selling points but there is considerable overlap. For example, if all I want is to express that I expect a function not to panic, there should be one syntax that works with all tools.

I think that for a guarantee as central as non-panicking, there ought to be eventually some kind of support in the core language. (Just throwing ideas here, but there could be `#[never_panic]` for simple cases where the compiler can clearly see that panic is not possible, or error otherwise, and `#[unsafe(never_panic)]` for more involved cases, that could be proven with 3rd party tools or by reasoning by the develope…

I think the current plan is to integrate never-panic into the upcoming effect system (formerly keyword generics), along with const and async. So all these function annotations can share the same behavior and syntax, and higher order functions can be generic over them (e.g. "iterator.map(f) is never-panic if f is never-panic" etc)

Re: Verus: Verified Rust for low-level systems code

#25

Earlier quoted context omitted.

Yes, but remember that Erlang bug discussed here last week where somebody apparently messed up SSH state transitions in such a way that people could just log in without having the password or anything? Buffer overflows etc. are absurd things that should not be possible, but preventing them is the first step towards security.

This is something that Rust should prevent, not another layer on top of Rust.

Yes, it should make sure that there are not buffer overflows, but this is the next step.

Re: Verus: Verified Rust for low-level systems code

#26
post #24

Earlier quoted context omitted.

I think that for a guarantee as central as non-panicking, there ought to be eventually some kind of support in the core language. (Just throwing ideas here, but there could be `#[never_panic]` for simple cases where the compiler can clearly see that panic is not possible, or error otherwise, and `#[unsafe(never_panic)]` for more involved cases, that could be proven with 3rd party tools or by reasoning by the develope…

I think the current plan is to integrate never-panic into the upcoming effect system (formerly keyword generics), along with const and async. So all these function annotations can share the same behavior and syntax, and higher order functions can be generic over them (e.g. "iterator.map(f) is never-panic if f is never-panic" etc)

> effect system (formerly keyword generics)

Any recent link about that? Specially one that calls it effect system rather than the old name keyword generics

Re: Verus: Verified Rust for low-level systems code

#27

Earlier quoted context omitted.

Why is verification excessive but not tests? A verification of a property is stronger than a mere test of a property.

The test is supposed to be the verification.

Test verify that the code works on specific inputs. Formal verification checks that it works on every input.

Re: Verus: Verified Rust for low-level systems code

#28
post #18

Would it be better to build dependent types into the language itself so that we can guarantee any spec we want? Or do these tools have some advantage over dependent typing?

From glancing at https://www.andrew.cmu.edu/user/bparno/papers/verus-ghost.pd... it is more related than you think.

- The various "modes" are going to be needed either way, because side-effectful functions at the type level are a research problem that probably isn't worth the effort.

- The in the pure functional "promotable" fragment, it probably also makes sense to relax aliasing rules / have infinite number types / etc. because all the stuff is going to compile away anyways.

I hope projects like this catch on, and incentivize Rust getting a stronger type system, because the benefits will flow in both directions.

Re: Verus: Verified Rust for low-level systems code

#29

Earlier quoted context omitted.

Why is verification excessive but not tests? A verification of a property is stronger than a mere test of a property.

The test is supposed to be the verification.

But why? Tests can't catch everything. A single verified predicate is equivalent to a very large, potentially infinite number of tests.

Right now the Rust stdlib is being verified using Kani, a model checker, https://model-checking.github.io/verify-rust-std/

In Kani, a proof looks like this

https://github.com/model-checking/verify-rust-std/blob/00169...

    #[kani::proof_for_contract(NonNull::new_unchecked)]
    pub fn non_null_check_new_unchecked() {
        let raw_ptr = kani::any::() as *mut i32;
        unsafe {
            let _ = NonNull::new_unchecked(raw_ptr);
        }
    }
It looks like a test, but actually it is testing that every possible usize, when converted to a pointer to i32 and built with NonNull::new_unchecked, will follow the contract of NonNull::new_unchecked, which is defined here

https://github.com/model-checking/verify-rust-std/blob/00169...

    #[requires(!ptr.is_null())]
    #[ensures(|result| result.as_ptr() == ptr)]
Which means: if the caller guarantees that the parameter ptr is not null, then result.as_ptr() is the same as the passed ptr

That's a kind of trivial contract but Kani tests for all possible pointers (rather than some cherry picked pointers like the null pointer and something else), without actually brute-forcing them but instead recognizing when many inputs test the same thing (while still catching a bug if the code changes to handle some input differently). And this approach scales for non-trivial properties too, a lot of things in the stdlib have non-trivial invariants.

You can check out other proofs here https://github.com/search?q=repo%3Amodel-checking%2Fverify-r...

It's not that different from writing a regular test, it's just more powerful. And you can even use this #[requires] and #[ensures] syntax to test properties in regular tests if you use the https://crates.io/crates/contracts crate.

Really if you have ever used the https://proptest-rs.github.io/proptest/intro.html or the https://crates.io/crates/quickcheck crate, software verification is like writing a property test, but rather than testing N examples generated at random, it tests all possible examples at once. And it works when the space of possible examples is infinite or prohibitively large, too.

Re: Verus: Verified Rust for low-level systems code

#30
post #12

Rust is supposed to be a "safe" language for low level use, and thus has borrow checker, unsafe, etc. Building a "verifier" on top of Rust seems a bit excessive and unneeded. > Developers write specifications of what their code should do ... Verus statically checks ... the specifications for all possible executions of the code This is what tests are for.

Tests do not account for all possible executions of the code, rather only a subset of it. Rust is indeed a safe language, in terms of memory safety. Vulnerabilities are still very possible within a rust program, they just need to not rely on memory exploits, and the borrow checker won't catch them. That is why formal verification exists. If you have a really critical, high security application then you should ensure…

[deleted]
Post reply on HN