[openssl-project] Removal of NULL checks
Richard Levitte
levitte at openssl.org
Thu Aug 9 17:12:18 UTC 2018
In message <20180809165255.GG14409 at straasha.imrryr.org> on Thu, 9 Aug 2018 12:52:56 -0400, Viktor Dukhovni <viktor at dukhovni.org> said:
viktor> On Thu, Aug 09, 2018 at 06:40:14PM +0200, Richard Levitte wrote:
viktor> > In message <20180809162245.GD14409 at straasha.imrryr.org> on Thu, 9 Aug 2018 12:22:45 -0400, Viktor Dukhovni <openssl-users at dukhovni.org> said:
viktor> >
viktor> > openssl-users> It needs to be possible to recompile and run without auditing code.
viktor> > openssl-users> The worst kind of incompatibilities are those that are not reported
viktor> > openssl-users> by the compiler, and are only found at runtime, possibly under unusual
viktor> > openssl-users> conditions.
viktor> >
viktor> > So in this particular case, such as unchecked calls of sk_ functions,
viktor> > including sk_TYPE_new(), just to discover later that "oops, the
viktor> > elements we thought we inserted aren't there"? ;-)
viktor>
viktor> The NULL checks were returning an error, not silently failing to
viktor> add the element.
I said *unchecked* calls of sk_ functions.
viktor> > Either way, sk == NULL will not be reported by the compiler, will only
viktor> > be found at runtime, possibly under unusual conditions.
viktor>
viktor> Code that tested for the error and avoided a crash would absent
viktor> NULL checks crash (in unexpected cases). The existing code should
viktor> be assumed to be correctly written for the current library behaviour.
viktor> What happens to already broken code is of little interest.
Code that is correctly written should check the value returned from
sk_TYPE_new(), no?
viktor> > The only
viktor> > difference is exactly how the user gets to find out in runtime; 1)
viktor> > mysterious failures because the stack that should contain n elements
viktor> > is really empty and unfillable, or 2) an immediate crash.
viktor>
viktor> This is simply wrong I'm afraid. The NULL checks in question
viktor> returned an *error* (rather than crash) that the application should
viktor> check. Applications that are not doing their own NULL check and
viktor> expect us to do it for them, can check for return value. This
viktor> makes possible more concise code:
viktor>
viktor> X509 *x;
viktor> STACK_OF(X509) *s;
viktor>
viktor> ...
viktor> /* Allocate 's' and initialize with x as first element */
viktor> if (sk_X509_push(s = sk_X509_new(NULL), x) < 0) {
viktor> /* error */
viktor> }
I would regard that code incorrectly written, because it doesn't check
the value returned from sk_X509_new(NULL) (i.e. it doesn't properly
check for possible errors). Correctly written code would be written
like this:
X509 *x;
STACK_OF(X509) *s;
...
/* Allocate 's' and initialize with x as first element */
if ((s = sk_X509_new(NULL)) == NULL
|| sk_X509_push(s, x) < 0) {
/* error */
}
However, if we actually want people to be able not to check if the
stack they wanted to allocate actually got allocated, the correct
course of action would be to make that a defined behaviour, i.e. fix
the docs accordingly.
I find it weird, however, that in this particular case, we would
expect users not to check if a stack was actually allocated, when such
checks is actually correct behaviour, for example on stuff returned by
OPENSSL_malloc(), EVP_PKEY_CTX_new() etc etc etc.
Cheers,
Richard
--
Richard Levitte levitte at openssl.org
OpenSSL Project http://www.openssl.org/~levitte/
More information about the openssl-project
mailing list