-
Notifications
You must be signed in to change notification settings - Fork 114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow 0 byte read/write in SSL_{read,write}_ex #1316
Allow 0 byte read/write in SSL_{read,write}_ex #1316
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #1316 +/- ##
==========================================
- Coverage 76.43% 76.38% -0.06%
==========================================
Files 421 421
Lines 70974 70980 +6
==========================================
- Hits 54250 54218 -32
- Misses 16724 16762 +38 ☔ View full report in Codecov by Sentry. |
@@ -1026,6 +1026,10 @@ static int ssl_read_impl(SSL *ssl) { | |||
} | |||
|
|||
int SSL_read_ex(SSL *ssl, void *buf, size_t num, size_t *read_bytes) { | |||
if (num == 0 && read_bytes != nullptr) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the null pointer needed here? Should we always set read_bytes to 0 and return 1 when num == 0?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My goal here was to balance safety with compatibility. from my reading, OpenSSL won't return 1 in that case; it'll segfault. Admittedly, because of the amount of indirection via function pointers in OpenSSL's libssl, I'm not 100% confident in this reading of that code (see below).
So, if indeed my reading is correct and they segfault, I guess the expected behavior of passing null pointer here is "undefined" for OpenSSL. I thought it would be good for us to return an error in that case (as opposed to returning success) because the API's contract is for *read_bytes
to be set to the number of bytes read on success. Since we can't do that with a null pointer, per the contract, returning success doesn't make sense in my opinion.
My reading of OpenSSL's relevant code:
SSL_read_ex
callsssl_read_internal
, which in turn calls thessl_read
implementation ons->method
.- I believe the implementation for our purposes here (i.e. not DTLS) is
ssl3_write
, which in turn calls anssl_write_bytes
implementation attached tos->method
. - Presumably, that implementation is
ssl3_write_bytes
, which never checks thewritten
pointer before dereferencing in the case when 0 bytes have been requested to be written (and 0 bytes have been written, i.e.len == tot == 0
in the code).
Side note -- somebody summed up the whole situation pretty well in an internal comment:
/*
* This is for the SSLv3/TLSv1.0 differences in crypto/hash stuff It is a bit
* of a mess of functions, but hell, think of it as an opaque structure :-)
*/
The primary motivation of this change is to match OpenSSL's behavior for these functions. Relevant links: - [SSL_read_ex docs][1] - [SSL_write_ex docs][2] - [CPython update accounting for this behavior][3] [1]: https://www.openssl.org/docs/man1.1.1/man3/SSL_read_ex.html [2]: https://www.openssl.org/docs/man1.1.1/man3/SSL_write_ex.html [3]: python/cpython#75892 (comment)
Co-authored-by: Samuel Chiang <samuelchungchiang@gmail.com>
Co-authored-by: Samuel Chiang <samuelchungchiang@gmail.com>
cec39a7
to
bf568ac
Compare
This reverts commit 89e1fd0.
This reverts commit 89e1fd0.
This reverts commit 89e1fd0.
This reverts commit 89e1fd0.
Issues:
Addresses CryptoAlg-2136
Description of changes:
The primary motivation of this change is to match OpenSSL's behavior for these functions. Relevant links:
Call-outs:
Testing:
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.