The Mystery of Dynamically Linked or Statically Linked Executables (Part 2)

Welcome back. This post is a continuation of part 1 and it assumes you have read it. Find part 1 here.

Now, let’s continue the discussion about a dynamic vs static linked executable. You should probably ask yourself why and when would I use one vs the other?

Let’s summarize the difference between a static and a dynamically linked executable. The dynamic linked executable simply expects all the dependencies to be present, for example: in part 1, in the C program we included the standard library called stdio for standard input/output operation, so we could use the printf function. This function is part of the Linux standard runtime library. Take a minute to really understand the statements above before continuing.

When we execute the program, the program makes an external call to the kernel asking for the function, the kernel finds based on the library path execution in the library libc, then it will execute it passing the parameters and returns the value back to the calling program.

Now when a statically linked executable is executed, the call to the printf function is part of the executable itself, handled internally. That is why, statically linked programs have a bigger file size. Because they include all the functions called from external libraries within.

Are you following up to this point? If not, please go through the exercise in part 1. Things will be clearer now.

Let’s talk about advantages and disadvantages that one has vs the other. Our example is very simple, so one vs the other does not really present any issues. But for larger applications with hundreds or even thousands of system calls, the differences can be substantial. In reality most of the programs in Linux and applications you will develop will be dynamically linked, that are reasons why the default mode is dynamic, first of all for system updates. In today’s world, security is very important. For simplicity, let’s take the program we wrote in part 1. The program depends on libc.6. Let’s assume there is a security vulnerability in the libc.6 version used when you linked the program. Let’s say that the program was dynamically linked, what happens when the system is patched/updated? Simple, the latest version of libc.6 is updated, and you program will call the function printf that has the latest security patching.

Now, let’s imagine this patch allows a backdoor for malicious code to execute without permission on the system. With a dynamically linked program, as soon as the libc.6 is patched, the vulnerability is gone. But, if you are using a statically linked executable, the vulnerable portion of libc.6 included in your program is still vulnerable to the attack. In order to patch the program, you would have to recompile and link the program with a patched version of libc.6, and redistribute your program.

Imagine the problem that this could cause? And by now, you should understand why dynamically linked executable are the default and most applications use them.

By now you should be asking yourself, when would I use a static linked executable? Well, there are use cases for that. But the number one use case is to use statically linked programs for installation binaries. Because you do not know how/when your program will be executed. You could also use static linked programs to assure compatibility and to isolate bugs and eliminate system dependencies, but those use cases are temporary in my opinion.

I hope by now, you better understand the explained concepts, and can better make decisions on when to use statically linked programs.

Thank you for reading and type away!

Leave a Reply