[Cryptography] Use Linux for its security

Kent Borg kentborg at borg.org
Sat Oct 1 19:09:33 EDT 2016


On 10/01/2016 01:17 PM, Ron Garret wrote:
> Also, safety isn’t free. You can pay for it with silicon or you can
> pay for it with time.

 From what I understand of Rust... it pays for its safety in time, but 
in compile-time, not run-time.

Tricky!! Seriously, they seem to be doing some clever stuff here.

They pay in compile time, combined with such things as requiring the 
programmer say whether the data being passed to a function is being (1) 
given away, (2) a shared read-only reference, or (3) a writable 
reference but on a loan that will be returned. This is stuff programmers 
already worry about at a lower level, by telling Rust more about what is 
going on, it can enforce data safety for us--at compile time. It makes 
the rustc more annoying than cc, but in exchange for less debugging and 
fewer low-level bugs leaking through.

In Rust data can be writable or it can be shared, but not both, at least 
not at the same time.

Much of programming is getting straight who allocates data, who looks at 
it, who touches it (plus coordinating when do the lookers and touchers 
do these things), who frees it, and does anyone try to touch or look at 
it after it has been freed. Not only is this a lot of the work of 
programming, it is implicit and scattered all over the place. It makes 
multithreaded code hellish to maintain beyond its first optimistic writing.

By forcing programmers to be explicit about ownership Rust can then 
enforce that ownership.

If I call a function and pass ownership of some object to that function, 
Rust can see that at compile time, so if I then try to access it after 
that point a static analysis can detect that and blow up at compile-time 
not run-time.

Similarly, if I pass a shared reference to some data Rust will enforce 
that as read-only data everywhere until all the shared references go out 
of scope, at which point the original owner owns it again, free and 
clear. And if no one owns it anymore it gets immediately reclaimed, 
without explicit freeing nor waiting for garbage collection.

I don't fully understand how Rust comes up with a compile-time solution 
to know when blah-blah allocated data is squirreled away in some other 
data structure and when it is not, but apparently it can.

As for bounds checking, something that sure sounds like a run-time cost, 
the Rust approach is try get the programmer to say what access is 
needed, but at a higher level. For example, there is a slice syntax that 
is a bit like Python. If that fills the bill then there will be *zero* 
runtime cost for bounds checking because Rusts trusts its own code 
generation, it trusts its own index arithmetic, so it runs at full 
speed. No extra checking required. (And are we really going to miss 
writing "for (i=0, i<len; i++) ..." over and over again?)

But what if there is an access pattern that cannot be efficiently 
expressed in Rust, what if you really need to do some run-time index 
calculation that hops all over the place?

A couple options.

How much data are you accessing? Is this a one-off access? Then pay the 
price, let Rust do the bounds checking, it's a service.

Or, what if it really is a hot little loop but chaotic as hell? Then 
maybe you need an unsafe block with maybe a whole dozen lines of code in 
it. Okay, but that is still a win. But...reconsider whether you really 
need an unsafe block there, look at your code carefully, test it 
carefully, and have it reviewed carefully. Frown hard over that unsafe code.

Instead of every line of the C program being unsafe, in Rust you can 
grep for the unsafe code. Being really careful is easier to do with a 
dozen lines of code than with thousands or millions. That's why Rust is 
a suitable language for low-level systems programming. Every line of 
Linux kernel C sources is unsafe, but only a small minority are doing 
something inherently unsafe, only a small minority would need be marked 
unsafe were it written in something like Rust.

I think there is an odd trick going on here: by giving programmers 
higher-level features Rust designers have figured out how to better know 
in advance what the hell will be going on. They somehow designed the 
language to make it possible to move abstractions closer in time, move 
them into compile time, where they can be bolted down safely.

I don't understand this well enough to grok the corner cases that must 
be there where this falls down, but apparently it mostly doesn't. I 
guess language design has progressed; I guess computer science is still 
happening.


-kb, the Kent whose Rust understanding is admittedly incomplete.


More information about the cryptography mailing list