[Cryptography] Ada vs Rust vs safer C

John Denker jsd at av8n.com
Sat Sep 17 09:00:59 EDT 2016


On 09/16/2016 01:31 PM, Arnold Reinhold wrote:
> In the recent thread on safe erasure in C,  much was made of better
> languages including Ada and Rust. But there is a vast mount of code
> already written in C. Converting all of it or even a large fraction
> seems hopeless. For comparison what would it take to make a safer C?

Such things exist.

For starters, there is C++.  This provides an easy migration path,
since nearly any decent C program will compile just fine under C++.
The code can then be converted to C++ style incrementally.

Another line of attack is to add /annotations/ to make static
analysis more effective.

One way of thinking about this is to define a /dialect/, such that
stuff that is undefined behavior in the parent language is defined
in a particular way in the dialect.  For starters, you can implement
bounds checking.
  http://williambader.com/bounds/example.html

Another option is to use a language subset such as MISRA-C.  This
has the advantage of portability, insofar as anything that compiles
under the subset compiler will also compile under the parent-language
compiler.  However the MISRA-C subset is nowhere near a panacea.
For a critique, see:
  Les Hatton
  "Language subsetting in an industrial context: a comparison of MISRA C 1998 and MISRA C"
  http://www.leshatton.org/Documents/MISRA_comp_1105.pdf

If you don't like that particular subset, there are others.  You can
even implement your own ad-hoc subset.  For example, you can improve
portability by deprecating "int" and favoring "int32_t" instead,
which is easy to enforce at compile time.
  typedef int native_int;
  #define int bogus_int

More generally, for a discussion of the pros and cons of various
languages, including consideration of safety and practicality, see:
  David A. Wheeler
  "How to Prevent the next Heartbleed"
  http://www.dwheeler.com/essays/heartbleed.html

IMHO it is an excellent exercise to examine languages and tools and ask
whether they would have prevented heartbleed, and at what cost.  As
one small example, I remark that 'cppcheck' would not have prevented
heartbleed.  That is, the bad old version of openssl d1_both.c *with*
the heartbleed bug passes all the static checks performed by
	 cppcheck --enable=all -v d1_both.c
As for the cost, I find that cppcheck generates an awful lot of false
positives, falsely claiming that variables are uninitialized.

===

It should be noted that there exist C-to-Ada translators that do 80
or 90 percent of the work for you.  Also C-to-Rust translators.

On 09/16/2016 04:01 PM, Watson Ladd wrote:
>> Compilers can't introduce bounds checks without changing pointer
>> representations. 

That's sometimes true and sometimes not.  As a partial counterexample,
/electric fence/ implements a useful first approximation to bounds
checking, without changing the representation.

>> That will break calling conventions and hardware. You
>> could get around this, but it would be painful, particularly when functions
>> want to change the endpoints of pointers (like allocators).

Even if the representation has to change, the breakage isn't all that
terrible.  For example, in C++ you can convert from
	int32_t* foo;
to
	vector<int32_t> foo;

This is absolutely not going to break the hardware.  Indeed, as previously
discussed, it is likely that future improvements in hardware will focus
more on increasing the parallelism rather than increasing raw clock speed.
Bounds checking can usually be performed in parallel with everything else.



More information about the cryptography mailing list