How mbeddr prevents goto fail (and similar problems)

 

As a consequence of the Apple goto fail, everybody seems to feel the need to point out how their particular system would have prevented this problem. So I guess we should do this with mbeddr as well.

One can make out several causes for the problem (in addition to the obvious, which is that somebody made a mistake). So here are some thoughts relative to these causes and mbeddr.

First, there is a mix up between indentation and actual block structure. The goto fail code clearly shows, that the developer intended to make the gotos part of the if. After all both gotos were indented. In mbeddr developers have no control over indentation (as a consequence of MPS' projectional editor). So the second goto would not have been indented, avoiding the visual confusion.

A second reason for the goto fail could be the missing curlies in the body of the if statement. Since the if statement executes conditionally the one statement that follows the if condition, it is good style to use a block statement there (curlies). In mbeddr, the definition of the if statement forces the use of a block statement as the body of an if statement. Thus, an if is ALWAYS followed by curlies. This really does prevent errors like the one that caused goto fail.

Some people argue that the goto statement should not be used in code in the first place (even though the C code in the goto fail example is idiomatic C). In mbeddr, it is trivial to define a modular language extension that contains a constraint that prevents developers from using gotos, if this is so desired.

If no gotos should be used, then some other means of handling errors need to be provided. Obviously, in C++, exceptions could have been used; the fail part is an exception handler. However, exceptions do incur some runtime overhead, they don't work with functions that return an error code, and, of course, they are not available in C. However, in mbeddr, one could simply develop a language extension for the following syntax:

This extension could be translated in the following way:

While the implementation uses the same pattern used by the Apple code, the pattern is automatically generated, and hence users cannot make mistakes for error handling. This is a little bit like exception handling, but it works only locally (it doesn't use longjmp) and it works with existing library functions. And of course this language could easily be extended to where the error handler can get information about the failed call (by passing a step variable to the error handler). One could also easily have several error handlers that each handle a specific (range of) error code(s).

By the way, you can find this language extension in the mbeddr repository now. It took 30 minutes to build :-)

So this is in fact a nice example how, by avoiding unnecessary detail, a language extension can improve the robustness and security (in this case!) of low level code. It simply prevents users from making mistakes in the (unnecessary) details. In addition, the intent of what the users wanted to do is much clearer.

There are many things like that in (embedded) software. The goal of mbeddr is to make it simple to extend C with "little languages" that prevent these problems.