Wednesday, May 20, 2015

gcc static linking

Take this c program that does nothing but exit.

#include<stdlib.h>
void main(){
  exit(0);
}



There is a gcc option to complile with '-static'.


Let's say you run this command to build...
  gcc -o exit exit.c

Then if you view your directory you'll see you have an executable and code...
ls -l
-rwxrwxr-x 1 user user 7291 May 20 12:02 exit
-rw-rw-r-- 1 user user 140 May 20 12:02 exit.c


Let's say you run this command to build...
  gcc -static -o exit exit.c

Then if you view your directory you'll see you have an executable and code...
ls -l
-rwxrwxr-x 1 user user 733094 May 20 12:02 exit
-rw-rw-r-- 1 user user 140 May 20 12:02 exit.c


First, let's noticed what I colored in green and red. The file sizes. Notice that the regular (dynamically linked) executable is relatively small. Notice that the statically linked (-static) executable though is quite large (a magnitude of 10x larger!). Why?

Because by statically linking the libraries, what we've told the compiler (gcc) to do is the take a copy of all libraries that are needed (such as stdlib.h), make a copy of them, and bundle them directly into the executable. If the libraries are dynamically linked, those libraries are not included in the executable, but instead are referenced/called from wherever they live on the device.

A con of static linking is that it can obviously cause disk space issues, since there is no library re-uses, instead every application built statically would have it's own independent copy of everything and it's eat up disk space.

Another con of static linking is that it can also cause compatibility issues because many times libraries are built to be machine dependent. If you statically built your executable, you only included the version of the library from which the executable was compiled on. Some of those libraries will then break on different machines.

But a pro of static linking is that it is the ideal deploy process for an application. There are no pre-requisites, no dependencies on library versions, etc., if it's on the right type of machine, it'll just work.

But the most interesting topic, and the reason for writing this blog post is Security. You should hopefully have put all the puzzle pieces together by now, and started to realize that static linking is BAD in terms of Security Vulnerabilities. Why? If an application is using a library, and that library contains a security vulnerabilities (buffer overflow, sql injection, etc.) ...

- Which do you think is going to be easier to patch? My Opinion: Dynamic is easier to patch because you just need to update the library (smaller set of code, easier to deploy/update, smaller subset to test, etc.)

- Which do you think is better for shared libraries? My Opinion: If a library is shared by multiple applications (like stdlib.h), and that library needs patched, it's much simpler to patch that one library than it would be to identify, patch, and redeploy every application using that library.

- Which do you think is more likely to expose old/missed security vulnerabilities? My Opinion: If a library has a vulnerability, it's much better to be able to patch it in 1 spot and have all applications fixed. If you have everything statically linked, you must remember which applications use that library, and make sure you patch and re-deploy each of them. What if you miss one application? Now you have an old unpatched vulnerability sitting out.


For that main reason, to my knowledge statically linked libraries are pretty much useless and should be avoided primarily because of the security risks they present.

Copyright © 2015, this post cannot be reproduced or retransmitted in any form without reference to the original post.

No comments:

Post a Comment