Add heartbeat extension bounds check
github.com
github.com
unsigned char *p = &s->s3->rrec.data[0], *pl;
I think it would be better written as: unsigned char *p = s->s3->rrec.data, *pl;
to make it clearer that data is a pointer within the structure.I'm not very familiar with how TLS heartbeats are implemented, but I wonder if the buffer could have just been alloc'd once when the connection was created.
It's probably much harder to remove the one on reception due to how the rest of OpenSSL is written, but at least from a glance at the code, a lot easier to rid the sending one. In terms of design, the simplest implementation would be malloc-on-receive + modify-and-send; a little better is an expanding buffer that's allocated once but reallocated if necessary, and to me, the way it's currently being done is the most complex, inefficient, and error-prone.
Having many unnecessary dynamic allocations tends to be a trend I've noticed most often in C/C++ code written by programmers with a Java background. Not saying that this necessarily applies to heartbleed's culprit, but the general trend of excessive complexity is there.
PVS-Studio checks some open source projects and posts part of the results on their blog. I did a search and found that they did take a look at OpenSSL in 2012.
http://www.viva64.com/en/b/0183/
And Coverity: https://scan.coverity.com/projects/294
I guess that the anaylser doesn't know that it's untrusted - perhaps it's worth having separate "trusted int" and "untrusted int" data types, so this would've been a compile-time error?
/* Read type and payload length first */
And now this is actually the second thing the code does, not the first.