3 ms·
> There are also hidden gotchas for situations where different libraries are linked against different OpenSSL versions and then share OpenSSL data structures b
by fortytw2 10y ago
> There are also hidden gotchas for situations where different libraries are linked against different OpenSSL versions and then share OpenSSL data structures between them[7] - many of these problems will be difficult to detect since they only fail at runtime.
Why are libraries written in this way? Seems fairly insane to expose parts of another library as a part of your public interface. This feels like the shining example of a poor practice coming back to bite, hard.
- tuwtuwtuw 10y agoBecause it might save time in the short term.
- simias 10y agoBecause wrapping around all of the potentially useful OpenSSL interfaces is a huge amount of work. For instance if you want to implement certificate pinning with libcurl you can provide a callback with "CURLOPT_SSL_CTX_FUNCTION" that will be called at the beginning of the SSL connection: https://curl.haxx.se/libcurl/c/CURLOPT_SSL_CTX_FUNCTION.html https://curl.haxx.se/libcurl/c/CURLOPT_SSL_CTX_FUNCTION.html This callback is provided with an opaque "void * ssl_ctx" which is probably an OpenSSL "SSL_CTX *" and then it's up to you to do the rest. That's assuming libcurl is built with OpenSSL or wolfSSL (what happens if your code gets linked with a libcurl that's compiled against wolfSSL and you use the pointer as an OpenSSL context? I don't know either). Seems like a very unsafe way to handle that but it's not like I can come up with some easy way around it besides adding a whole lot of complexity to libcurl. I really have a huge respect for the maintainers of OpenSSL, managing such a codebase is quite a daunting task. I consider myself a pretty decent C coder but every time I've had to deal with OpenSSL I always ended up with a deep feeling of uneasiness. Simply figuring out if you're supposed to free the pointers returned by some OpenSSL calls ends up in a deep dive into the source code. Or you get frustrated and end up copy/pasting some code you've found on stack overflow and hope the original poster knew what they were doing. I'm personally very eagerly looking forward a comprehensive crypto library written in pure Rust but it will take time. In the meantime there's rust-openssl (and other language bindings) which manage to hide some of the insanity.
- mnarayan01 10y agoIt's worth looking at the referenced link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=844018 https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=844018 You may still think it's insane, but it's much less insane than that quote might otherwise imply.
- cperciva 10y agoWhy are libraries written in this way? Seems fairly insane to expose parts of another library as a part of your public interface. It's not necessarily intentional. One of the more "interesting" bugs we've seen in FreeBSD was when a program linked to libraries A and B, and library A linked to libcrypto (openssl) while library B linked to libmd (a lightweight hash function library). Each part worked fine independently, but when it was all put together, the dynamic linker said "we need to find an object called SHA256_Init? Oh look, it's in this library we already loaded!" with predictably hilarious results. (We now use preprocessor macros to define _libmd_SHA256_Init etc. to avoid such linker confusion.) What you think your public interfaces are and what the linker thinks your public interfaces are don't necessarily align.
- rkeene2 10y agoSymbol versioning can solve this at the linker layer without modifying the source. One possibility is to use --default-symver when compiling OpenSSL and libmd, then when they are linked the appropriately the soname is used as a version tag for any unversioned symbols. An example: http://www.rkeene.org/viewer/tmp/linking-troubles/log.html.htm http://www.rkeene.org/viewer/tmp/linking-troubles/log.html.h... If you are a library maintainer and export a stable ABI, it might also be good to provide a version or every symbol if for no other reason than to avoid issues with the flat namespace.