27 comments

[ 3.1 ms ] story [ 50.8 ms ] thread
typo "distrobution" in the article.
Thanks! I just pushed up a fix for that.
Does the much broader scope and amount of code required here (compared to the underhanded-c contest) make it a much weaker contest? For example they suggest that one should create a web-server (rather than say, requiring one to implement a couple specific methods for a hypothetical web-server):

> Create a simple web server that supports at least creating accounts and payment submissions. We recommend using one of the many Rust web servers like iron, nickel, or pencil, but you are welcome to create your own web server if you like.

Compare with the winning contest entry for the last underhanded-c contest which is one printed-page of code in total.[0]

[0] http://www.underhanded-c.org/one.pdf

Rust has fewer gotchas to exploit compared to C. We considered reducing the scope, but ultimately decided to keep the scope pretty broad because writing underhanded code in Rust is hard

Note that using a library keeps the actual code size pretty small. You can't introduce underhandedness into the library (unless you explicitly fork it). But it gives you the opportunity to introduce underhandedness by misusing a library API, which adds a whole new class of interesting tricks which you can use.

Depending how this one goes, we may reduce the scope for the next ones.

> We considered reducing the scope, but ultimately decided to keep the scope pretty broad because writing underhanded code in Rust is hard

Are we sure of this? The contest may prove otherwise.

Half-jokes aside, it would be surprising if it wasn't significantly harder in Rust than in C, and presumably any glaring problems are easier to address based on the more active nature of Rust development as well as tight feedback between the language development/compiler and the rest of the community (along with Rust's general attitude of "just be careful" not being good enough).

> Are we sure of this? The contest may prove otherwise.

No, we're not. Like I said, this can change in future competitions. It's no big deal if the first one is too easy. If the first one is too hard we may not get submissions and won't know if it is due to lack of interests or if it is too hard.

My baseline for determining this was basically that almost all of the underhanded C submissions use tricks that just can't work in Rust.

Furthermore, remember that the code will be run through clippy too. Many of the gotchas (e.g. Option::iter()) that can be used to create potential underhandedness should get caught by clippy.

But yes, we fully hope to feed back any findings into the compiler/libraries/clippy.

I love that you're using this as feedback into improving the ecosystem. I'll say one thing about the Rust community, they really have their shit together when it comes to stability and things like this.

I don't think I've ever seen a language release new versions with such consistent cadence and predictability.

  > The contest may prove otherwise.
Which is exactly why I insisted on keeping the language in the opening paragraph as humble as possible. :P
> Are we sure of this? The contest may prove otherwise.

Isn't testing that assumption a big point of the contest?

This is our first crack at hosting an underhanded contest, so if this turns out to be a problem in practice we'll happily take this into account for next year. :) erickt is the one who came up with the specific challenge here, and I believe part of his motivation was to test not only the constructs of the language itself, but also to probe for the sort of exploitable bugs that may exist in real Rust codebases in the wild, e.g. web frameworks, in order to determine if tweaks to the language or stdlib would feasibly render such exploits toothless.
To add on to kibwen and Manishearth, another aspect is that one of the Rust Team's 2017 objectives [1] is to get our community more engaged in mentoring people and projects. We see the open ended aspect of this contest as a way to encourage people to help find and fix security bugs in our ecosystem. This should help to accelerate getting Rust even more production ready.

[1]: https://github.com/aturon/rfcs/blob/roadmap-2017/text/0000-r...

(comment deleted)
Too bad that underhanded-c has a broken RSS and Atom feed.

http://www.underhanded-c.org/_feed_rss2

http://www.underhanded-c.org/_feed_atom

I added those to my RSS reader a long time ago, but didn't notice the 2015 announcement, let alone the winning entries. Why? Because the feeds are stuck, their latest entries are more than 2 years old:

  11/03/2014 The 7th Underhanded C Contest is now Open
  09/29/2014 2013 Winners
  ...
Suggestion: could you provide an example submission, which is ideal for what you're looking for except for not being underhanded?

Benefits:

- More approachable to mess around with for newbies -- download the example and try to break it.

- More likely that you'll get submissions from experts who have time to implement the underhanded part but may not get around to putting together the boilerplate.

- More likely that submissions will get the general task right and look similar for parts that don't matter, making for easier review.

Drawbacks:

- Potential for too many cookie cutter submissions.

- Might lead people away from thinking about alternate server designs that are more underhanded.

Mostly I think this might be worth doing because of the second benefit -- you're asking people to do a bunch of grunt work even after they've figured out the core underhanded technique.

The underhanded@rust-lang.org email does not work for me.

> We're writing to let you know that the group you tried to contact (rust-underhanded) may not exist, or you may not have permission to post messages to the group.

Thanks for the heads up! We fixed that setting, so mail away.
I expect some underhanded entries to exploit some type-level recursion. When combined with traits, that could yield some nice surprises, particularly when overloading specific instances.
Would you mind expanding on this a bit? The first thing that comes to mind:

    struct Foo {
        foo: Foo,
    }
Is caught by the compiler:

    error[E0072]: recursive type `Foo` has infinite size
     --> src/main.rs:1:1
      |
    1 | struct Foo {
      | ^ recursive type has infinite size
      |
      = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Foo` representable
Obviously, I'm not thinking deep enough to understand the approaches you are mentioning!
I'm not deep into Rust to try myself, but I meant something like type-level integers, perhaps to encode an buffer length, and then a sneaky trait or two that specializes on particular (common) buffer sizes to manipulate the buffer in an exploitable way.
Rust doesn't yet have type level integers, so that'll have to be saved for a future contest. (It's highly desired, and there's an RFC open, but it's not clear when they will land.)

I like this idea though!

But there are some crates like https://crates.io/crates/typenum that implement type-level integers on top of the Rust type system, and quite a few other crates that then use these for things like array operations...
Using typenum in production isn't a fireable offence?!
Not natively, but you can do it via phantom type parameters.

But that does raise an interesting question: could a malicious crate overload a "safe buffer" operation provided by another crate in this way?

The reddit comments pointed out that there was a previous (unofficial) contest last year [0]. Manishearth had a fun solution with lots of ideas: [1].

[0] https://www.reddit.com/r/rust/comments/3hb0wm/underhanded_ru...

[1] https://play.rust-lang.org/?gist=cadcbee43557e8e3bbe0&versio...