Article recommends ldd without a word of warning that you must not run that on untrusted code. It could execute malign code. Not understanding that might lead users who try to find out whether they should trust some binary to inspect it with ldd.
Is the idea of dynamic (shared) linking largely archaic? I know it exists on the OS level, but on the non-OS level, due to security and version compatibility, I feel maybe it shouldn't exist anymore.
> due to security and version compatibility, I feel maybe it shouldn't exist anymore.
I've also thought similar. From a security standpoint though it seems like shared libraries are largely a win. Imagine you're running a bunch of services and a vulnerability is found in OpenSSL. With shared libraries you can update one package to be pretty sure they're fixed.
No, dynamic loading is actually the norm for most environments. Anything JIT compiled or with "hot reloading" has some kind of dynamic loader under the hood.
The problem with shared libraries is that they're shared, of course. But this isn't the flaw it seems, it solves two issues: disk space and updates. You want programs to have their dependencies updated after they've been compiled, especially for security. The problem is that security updates are too often coupled with breakages, so whether or not a dependency update requires a recompile or patch is indeterminate and not a problem the loadable object format nor the loader can solve (it's a human problem, not a technical one). You also want shared things to be deduplicated intelligently. But rarely is that the case.
The bigger problem is that there's a lot of C/C++ code in the world and they are not designed to allow multiple versions of the same library to be linked into the same address space. This is not an unsolveable problem, except by the design of C/C++ linkers that enforce it on us.
The real unfortunate thing is that linkage is a fundamental algorithm in compilers and loaders are a fundamental piece of systems programming that people don't really dig into anymore to understand their flaws, and there's been little innovation (or wont for innovation) in years because people consider the problem solved.
9 comments
[ 3.9 ms ] story [ 28.4 ms ] threadThat 'execution' approach is why ldd is problematic; libraries can have init/finalizers (__init__ and __fini__ iirc).
Sorry, I don't remember all the details.
I've also thought similar. From a security standpoint though it seems like shared libraries are largely a win. Imagine you're running a bunch of services and a vulnerability is found in OpenSSL. With shared libraries you can update one package to be pretty sure they're fixed.
The problem with shared libraries is that they're shared, of course. But this isn't the flaw it seems, it solves two issues: disk space and updates. You want programs to have their dependencies updated after they've been compiled, especially for security. The problem is that security updates are too often coupled with breakages, so whether or not a dependency update requires a recompile or patch is indeterminate and not a problem the loadable object format nor the loader can solve (it's a human problem, not a technical one). You also want shared things to be deduplicated intelligently. But rarely is that the case.
The bigger problem is that there's a lot of C/C++ code in the world and they are not designed to allow multiple versions of the same library to be linked into the same address space. This is not an unsolveable problem, except by the design of C/C++ linkers that enforce it on us.
The real unfortunate thing is that linkage is a fundamental algorithm in compilers and loaders are a fundamental piece of systems programming that people don't really dig into anymore to understand their flaws, and there's been little innovation (or wont for innovation) in years because people consider the problem solved.