|
|
Log in / Subscribe / Register

Project for porting C to Rust gains Mozilla's backing (InfoWorld)

InfoWorld takes a look at a C-to-Rust translation project called Corrode. "What Corrode does not do (yet) is take constructs specific to C and rewrite them in memory-safe Rust equivalents. In other words, it performs the initial grunt work involved in porting a project from C to Rust, but it leaves the heavier lifting -- for example, using Rust's idioms and language features -- to the developer."

to post comments

Project for porting C to Rust gains Mozilla's backing (InfoWorld)

Posted Nov 2, 2016 11:06 UTC (Wed) by epa (subscriber, #39769) [Link] (14 responses)

Does it reproduce all of C's unsafe semantics or just some of them? What happens to integer overflow for example?

Project for porting C to Rust gains Mozilla's backing (InfoWorld)

Posted Nov 2, 2016 11:31 UTC (Wed) by vasvir (subscriber, #92389) [Link] (13 responses)

From Corrode's github README linked in the article:

For example, if a signed addition might overflow (which is undefined behavior in C), Corrode just translates it to Rust's + operator, which panics on overflow in debug builds.

I don't know what happens in non debug (release) builds.

Project for porting C to Rust gains Mozilla's backing (InfoWorld)

Posted Nov 2, 2016 12:26 UTC (Wed) by valarauca (guest, #109490) [Link] (5 responses)

In non-debug builds the Rust integer addition mirrors the C integer addition. Overflow/underflow will behave according to the platform specification.

The developer can opt-into checked addition (actually most integer operations can be check) which returns an Option<usize> (usize is being used here as an example, usize in Rust is the same as C's size_t). The Option<usize> is just a tagged union of char, size_t where the char signals if overflow occurred.

Here [1] is a simple playpen link where you can see the various ASM generated the different levels (debug/release).

[1] https://play.rust-lang.org/?gist=2bd93049475dda6e75e345a9...

Project for porting C to Rust gains Mozilla's backing (InfoWorld)

Posted Nov 3, 2016 11:38 UTC (Thu) by smurf (subscriber, #17840) [Link] (1 responses)

> Here [1] is a simple playpen link
… which doesn't seem to work:
>> error[E0308]: match arms have incompatible types

Project for porting C to Rust gains Mozilla's backing (InfoWorld)

Posted Nov 8, 2016 18:40 UTC (Tue) by ms-tg (subscriber, #89231) [Link]

Try this (I just hacked a fix in):
https://play.rust-lang.org/?gist=1da34770cfdbb44dd77bf966...

Using this (a) it compiles and runs as expected (b) you can look at the ASM output as indicated

Project for porting C to Rust gains Mozilla's backing (InfoWorld)

Posted Nov 3, 2016 13:01 UTC (Thu) by kevincox (subscriber, #93938) [Link] (2 responses)

> In non-debug builds the Rust integer addition mirrors the C integer addition. Overflow/underflow will behave according to the platform specification.

This is NOT how integer overflow works in C. In C unsigned integer overflow is undefined. In Rust "release" builds integer overflow is two's-compliment wrapping.

While in many cases the compiler will use the platforms native overflow behavior an optimizing compiler will often make assumptions because it doesn't have to wrap like the native platform.

For example (x + 1 < x) will be optimized to (0) by most compilers. You will also often see compilers promote small integers to machine words which will cause non-wrapping behavior when you are working with integers that will be used as memory offsets (including array indexes)

Project for porting C to Rust gains Mozilla's backing (InfoWorld)

Posted Nov 3, 2016 13:21 UTC (Thu) by TomH (subscriber, #56149) [Link] (1 responses)

I think you've confused yourself - unsigned integer overflow is defined in C (it wraps). It is signed integer overflow that is undefined.

Project for porting C to Rust gains Mozilla's backing (InfoWorld)

Posted Nov 7, 2016 14:14 UTC (Mon) by musicinmybrain (subscriber, #42780) [Link]

…and to be really pedantic about it, the view of the C standard is that all overflow is undefined, and the mandated unsigned integer “wrapping” behavior (arithmetic modulo 2^n) is not a kind of overflow.

Project for porting C to Rust gains Mozilla's backing (InfoWorld)

Posted Nov 2, 2016 12:27 UTC (Wed) by excors (subscriber, #95769) [Link] (6 responses)

http://huonw.github.io/blog/2016/04/myths-and-legends-abo... has some useful comments and links. It looks like Rust's basic behaviour is:

In debug mode, by default, signed and unsigned integer overflows panic (i.e. unwind the current thread's stack then terminate the thread). (Incidentally, unwinding the stack across FFI boundaries is apparently undefined behaviour, so if you ever call from C into Rust then the Rust code must either spawn a new thread to do all its work or else must be absolutely convinced it's not going to panic (which seems hard to guarantee if it's doing any arithmetic).)

In release mode, by default, overflows wrap as two's complement.

There could be compiler options to turn the checking on/off in different parts of the program.

It seems to be designed as a debugging feature, not a security feature. It's discussed as being equivalent to debug assertions, which are helpful during development but typically disabled in production for performance, so programs shouldn't rely on them to prevent exploits.

Integer types have some low-level explicit arithmetic methods: "wrapping_add" (always wraps), "saturating_add", "checked_add" (returns Some(n) or None on overflow). And for people who prefer operator overloading there's the "Wrapping" type, e.g. if "let x = Wrapping(0u32) - Wrapping(1u32)" then "x.0 == std::u32::MAX".

As far as I can tell from Corrode's source (admittedly I'm not very familiar with Literate Haskell), it uses the wrapping_add etc methods for unsigned arithmetic, and standard arithmetic operators for signed.

Project for porting C to Rust gains Mozilla's backing (InfoWorld)

Posted Nov 2, 2016 19:36 UTC (Wed) by roc (subscriber, #30627) [Link] (2 responses)

> (Incidentally, unwinding the stack across FFI boundaries is apparently undefined behaviour, so if you ever call from C into Rust then the Rust code must either spawn a new thread to do all its work or else must be absolutely convinced it's not going to panic (which seems hard to guarantee if it's doing any arithmetic).)

There's another approach, which is preferred: use std::panic::catch_unwind in the Rust callee to catch any panics and convert them to some kind of error return.

> It seems to be designed as a debugging feature, not a security feature.

That's currently true. I find it very useful in debugging since it leads you straight to the root cause of the bug. Personally, though, I hope that one day, with improved compiler optimization or shifting performance/security tradeoffs the Rust team is able to enable overflow checking in release builds. Having it be enabled by default in debug builds now is an essential prerequisite for that, since it makes it much less likely that actual Rust programs depend on unchecked overflows.

Project for porting C to Rust gains Mozilla's backing (InfoWorld)

Posted Nov 3, 2016 11:25 UTC (Thu) by epa (subscriber, #39769) [Link] (1 responses)

I'd rather have the overflow checking on by default, then if my program runs too slowly, profile it and turn off the checking just for the speed-critical part.

Project for porting C to Rust gains Mozilla's backing (InfoWorld)

Posted Nov 3, 2016 13:02 UTC (Thu) by kevincox (subscriber, #93938) [Link]

There are crates that do this (on nightly), but yes, that would be a cool option to have.

Project for porting C to Rust gains Mozilla's backing (InfoWorld)

Posted Nov 3, 2016 23:00 UTC (Thu) by ballombe (subscriber, #9523) [Link] (2 responses)

Keep in mind that gcc provides both -ftrapv and -fwrapv for C code. You do not need rust for that.

Project for porting C to Rust gains Mozilla's backing (InfoWorld)

Posted Nov 4, 2016 17:34 UTC (Fri) by thestinger (guest, #91827) [Link] (1 responses)

Neither of which works properly in GCC... although they do in Clang. In GCC, -ftrapv misses cases it should catch and -fwrapv isn't respected everywhere. Anyway, -ftrapv is only for signed overflow and is essentially obsolete. You really want the integer sanitizers in the trapping mode for that. In GCC, the implementation of those is also less buggy but still problematic, while it all works fine in Clang.

Project for porting C to Rust gains Mozilla's backing (InfoWorld)

Posted Nov 5, 2016 1:32 UTC (Sat) by lsl (subscriber, #86508) [Link]

> Anyway, -ftrapv is only for signed overflow and is essentially obsolete.

What else should it be? Unsigned wraparound is a standard language requirement und lots of code depends on it.

Do you have more info on the "-fwrapv isn't respected everywhere" part? Are these intentional or just bugs?


Copyright © 2016, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds