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
Ensure text mode file BIOs are buffered on Windows #24249
base: master
Are you sure you want to change the base?
Conversation
Commit 8300a87 disabled file buffering for text mode file BIOs on Windows to work around a bug in UCRT ftell. This is surprising to applications that expect BIO read/writes to be buffered, such as when reading cert.pem. This wraps text mode file BIOs with a buffered BIO, so the overall result is buffered (just once).
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.
Would it be possible to add some kind of test? (I assume there isn't a test or this would have been detected before now?)
I do not think this is a good idea. This is going to surprisingly return a BIO chain instead of a single BIO on one platform and that means to free it you'd have to use BIO_free_all() instead of BIO_free(). This is an API change. |
@t8m ah sorry, I thought Would it make sense to instead create macros to wrap #if defined(OPENSSL_SYS_WINDOWS)
#define BIO_NEW_TEXT_FILE(b,f,m) do { \
(b) = BIO_new_file((f),(m)); \
if ((b) != NULL) \
(b) = BIO_push(BIO_new(BIO_f_buffer()),(b)); \
} while(0)
#define BIO_FREE_TEXT_FILE(b) BIO_free_all(b)
#else
#define BIO_NEW_TEXT_FILE(b,f,m) ((b) = BIO_new_file((f),(m)))
#define BIO_FREE_TEXT_FILE(b) BIO_free(b)
#endif And then update the places where openssl creates file BIOs in text mode?
For example in by_file.c: - in = BIO_new_file(file, "r");
+ BIO_NEW_TEXT_FILE(in, file, "r");
if (in == NULL) {
ERR_raise(ERR_LIB_X509, ERR_R_BIO_LIB);
return 0;
}
inf = PEM_X509_INFO_read_bio_ex(in, NULL, NULL, "", libctx, propq);
- BIO_free(in);
+ BIO_FREE_TEXT_FILE(in); If that makes sense, where should the |
I would like to know what problem is this trying to solve. Does it matter if reading certificates/keys is not buffered? These data files aren't large. |
Sure, the problem is our application takes more than 10% longer to start up using openssl 3.0 due to 116k calls to |
I might suggest that OpenSSL consider just open those cases internally in binary mode. The PEM parser already handles CRLF itself and this helps avoid platform differences in processing the same bytes. The ftell bug is then moot in those cases. That doesn't account for the cases where OpenSSL takes a FILE* from the caller. But in those cases, the caller presumably is just expecting OpenSSL to call the libc functions on that FILE, platform warts and all. I.e. I think you can just assume the caller either doesn't care about ftell (most likely) or has applied a suitable workaround on their end. Put those together and I would suggest reverting the ftell workaround and leaving it to the call sites to apply, seeing as the workaround has significant perf costs. |
Yeah, that would make sense. |
Commit 8300a87 disabled file buffering for text mode file BIOs on Windows to work around a bug in UCRT ftell. This is surprising to applications that expect BIO read/writes to be buffered, such as when reading cert.pem.
This wraps text mode file BIOs with a buffered BIO, so the overall result is buffered (just once).