So the difference in effort between changing the static library and changing the dynamic library is... maybe not nothing, but not nearly as high as I was assuming.
It's a side point, but I don't entirely understand the argument here since it's basically guaranteed you were vulnerable to a variety of other bugs due to not updating. It depends how old your OpenSSL version was I suppose, but still, it kinda feels like gloating you survived a hurricane by doing no preparation - I'm happy for you, but that doesn't necessarily make it a great idea ;)
> - dynamic responsive remove bug: Positive/neutral. Team X would have done it anyway. > - static responsive remove bug: Positive/neutral: Team X will incorporate the change from Y, although possibly somewhat slower (but safer).
You sure about that? That's basically your whole argument, and I really don't buy it. In my experience, any dependency (static or not) shipped with a program is rarely actively updated, and also never in any regular fashion - on the list of things to do it's typically near the bottom. You called this a neutral, but it's easily a positive for dynamic (and negative for static), and IMO is the biggest argument for dynamic linking and shipping libraries separately. And once you apply that change, it's just two Positives and two Negatives each.
But with that, there's another situation that you're ignoring which throws a big wrench into your table - you're assuming you already know what the dependencies of a program are, when in practice you usually don't. In a dynamically linked world, to address a bug in OpenSSL I just drop a fixed version of OpenSSL in `/lib` and reboot. If it's statically linked to some or all of my programs instead, I need to figure out which if any programs make use of a statically linked version of `OpenSSL` and either wait for a new version or attempt to recompile them with a new one. And if I miss one, then the bug is still there in some form.
Edit: It's a small point, but you're also assuming that the maintainers shipping the static library will catch every bugged version before shipping their program with it - and library maintainers typically try not to release versions with known unusable bugs, it's an accident. An issue like Heartbleed is always going to be found after it's already in the wild, making the `static responsive add bug` category a bit suspect. If a program maintainer was on top of their OpenSSL version and always shipped the latest version when they released, their users would have been vulnerable - they may have made a release in a few days with a new version (to go with the other category), but their users still got the bad OpenSSL version.
It's a side point, but I don't entirely understand the argument here since it's basically guaranteed you were vulnerable to a variety of other bugs due to not updating. It depends how old your OpenSSL version was I suppose, but still, it kinda feels like gloating you survived a hurricane by doing no preparation - I'm happy for you, but that doesn't necessarily make it a great idea ;)
At the time, I think OpenSSL had several trees that were supported, Heartbleed was in the 1.0.1 tree, but not earlier trees, 1.0.0 and 0.9.8 trees were both still supported. OpenSSL versioning isn't very conventional, so one might not realize that 1.0.1 is a major version difference from 1.0.0, and 1.0.0 is a major version different than 0.9.8, but that's how they roll, minor versions within a series get letters after the name, and sometimes break binary compatibility (ugh). There's a reason a lot of people were slow to update to 1.0.1; unfortunately for me, my company had just updated to 1.0.1 about a month before the bug was reported, so we could get TLS 1.2 support. Would have saved a lot of headache if we had waited :(
Plus the whole reasoning tends to imply old versions are overall better (you don't have just one bug added or removed from time to time, you have to consider the overall bugginess over time, and if the project is well maintained, it will hopefully eventually decrease, especially if your usage scope remains constant)
But the reality is simply: it depends. On the libraries. On the application. On the platform. On the languages. On the tooling. On the maturity of all of that.
And even so, you may want (or be forced) to take an hybrid path (classic example: a program for Windows -- static is reasonable, but not for platform libs, and actually just not even available in this case)
- static responsive add bug: Positive. Users will not get the bad version of Y.
On the contrary, it's negative because the maintainers of X will update Y and introduce the bug to their users (I'm assuming they don't thoroughly audit the source of Y each time they do a version upgrade).
Also, "unresponsive remove bug" should be given more weight since it's more likely to happen IMO.
You are of course right, though, and writing it down like this can be useful.
Ironic considering that the package manager/repo model is largely implemented as a solution to issues with dynamic linking and yet makes getting up to date software from the developer much harder by introducing a third-party maintainer into the process.
If you are not using an apt-style package manager then the program must include all of its dependencies (except ones that are guaranteed to be present on the platform, which is none on Linux and a few on Mac/Windows), and you will receive bug fixes when that program is updated, whether or not it uses static linking.
Static/dynamic linking does not affect how likely you are to get bug fixes in any way as far as I can tell.
- dynamic responsive remove bug: Positive/neutral. Team X would have done it anyway.
- dynamic unresponsive remove bug: Positive.
- dynamic responsive add bug: Negative. Team X will see the bug but only be able to passively warn users not to use Y version whatever.
- dynamic unresponsive add bug: Negative. Users will be impacted and have to get Y to fix the error.
- static responsive remove bug: Positive/neutral: Team X will incorporate the change from Y, although possibly somewhat slower (but safer).
- static unresponsive remove bug: Negative. Users will have to fork X or goad them into incorportating the fix.
- static responsive add bug: Positive. Users will not get the bad version of Y.
- static unresponsive add bug: Positive. Users will not get the bad version of Y.
Overall, dynamic is positive 1, neutral 1, negative 2, and static is positive 2, neutral 1, negative 1. Unless you can rule out Y adding bugs, static makes more sense. Dynamic is best if "unresponsive remove bug" is likely, but if X is unresponsive, maybe you should just leave X anyway.