'via Blog this'
Apple's "goto fail" bug is notorious. Much discussion about how proper unit testing would have found it. Let alone code reviews. (I hope this bug is going into the pattern database for lint-like tools.)
While goto-less programming might have avoided the problem, I think it would have done so at the cost of readability.
I think it is more interesting that the problem might have been avoided if ELSE had been used. The code in question is really a cascaded set of IFs, where each is only done if all earlier have succeeded - but it is expressed as independent statements.
The buggy code:
static OSStatus SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams, uint8_t *signature, UInt16 signatureLen) { OSStatus err; ... if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) goto fail; goto fail; if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0) goto fail; ... fail: SSLFreeBuffer(&signedHashes); SSLFreeBuffer(&hashCtx); return err; }Rewritten so that the relationship between the cascaded IFs is visible and automatically checked. Minor liberty in capitalizing the ELSEs.
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0) goto fail; ELSE if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) goto fail; goto fail; ELSE if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0) goto fail; ... ELSE ... return 0;Plus, I am sure that somebody has pointed out that an assert would also have caught the error.
fail: assert(err != 0 ); SSLFreeBuffer(&signedHashes); SSLFreeBuffer(&hashCtx); return err;
No comments:
Post a Comment