[Cryptography] letter versus spirit of the law ... UB delenda est

John Denker jsd at av8n.com
Thu Oct 22 11:41:04 EDT 2015


Executive summary:  UB delenda est.
Keywords: disingenuous pettifoggery, pharisaical legalism.

In the context of UB (i.e. Undefined Behavior) in the specification
for the C language, let's consider the /spirit/ of the law.  As 
a first example, let's consider signed integer overflow.  By all 
accounts, when the specification was being drafted, a handful of 
possibilities were considered.  These were based on the behavior
of the hardware of the day:

 1) Overflow could throw an exception.
   1a) It might be possible to recover from the exception.
   1b) Or it might not.

 2) It could saturate at INT_MAX or INT_MIN as appropriate.

 3) It could wrap around in a way that made sense in one of 
  the three allowable integer representations:
   3a) two's complement
   3b) one's complement
   3c) sign-and-magnitude

It must be emphasized that in all cases the intent was at 
worst an LSV (i.e. Loosely Specified Value) ... but it was
still a value.  In all cases the result was supposed to be 
a well-behaved signed int.  No other wild behavior was
contemplated.  In particular, wild behavior such as "having
a negative value yet passing a test for positive values" was
never contemplated.

However, this wild behavior is exactly what we see in the
incisive example attributed to Alexander Cherepanov and posted 
in this forum on 10/21/2015 07:42 PM by Peter Gutmann.

Let's be clear:  This wild behavior is exactly the sort of 
thing that gives disingenuous pettifoggery a bad name.  It is
the sort of thing that gives pharisaical legalism a bad name.
It tramples on the spirit of the law and exploits the letter
of the law to achieve a result that (at best) benefits some 
at the expense of others.

  Actually, it's worse than that.  It should be obvious that
  a so-called "optimization" that results in wild behavior 
  doesn't really benefit anyone.  There is no advantage 
  in getting the wrong answer quickly.  Bypassing security 
  checks is not really an optimization.  A machine that 
  is not secure cannot be relied upon for /any/ purpose.

  Requiring people to use unsigned ints to the exclusion
  of signed ints when writing reliable code is not really
  an optimization ... and isn't sufficient anyway.  Using
  unsigned ints gets rid of the UB with respect to overflow,
  but other UB remains, including e.g. x<<y.

  I am reminded of Knuth's dictum:
    Premature optimization is the root of all evil.

There are two distinct problems here:
 A) The fact that the C language specification is vulnerable
  to this sort of abuse is a bug in the spec.  
 B) The fact that some compiler writers would exploit this 
  vulnerability is a problem of a different kind.


The best solution is to rewrite the specification so that
no UB remains.  No Undefined Behavior!  None whatsoever!
As a first step, one could replace UB with LSV, in accordance
with the original intent of the spec and in accordance with 
longstanding practice.  As a second step, it would be nice 
to get rid of all LSV behavior also.  Note that the IEEE
floating-point spec got rid of UB and mostly got rid of
LSV with respect to floating point;  surely doing the same
for ints can't be that difficult.  In the interim we can 
live with LSV a lot easier than we can live with UB. 
(We've been living with LSV for years.)

  I don't care whether we call the rewritten thing a 
  "new language" or a "dialect" of the old language.
  Let's just fix the problem already.

UB delenda est.


More information about the cryptography mailing list