Milan Stevanovic has written and excellent book by the title of Advanced C and C++ Compiling. As I am halfway through it, I find that he provides great, relatively up-to-date, detail about executable file formats and the process of creating them and loading them. One of the discussions in the book compares static and shared libraries. The shared library was a great advance in the growth of operating systems and makes cooperation among programs more feasible. The concept seems to have a few problems.
While the book I am reading touts the benefits of shared libraries very well, and I agree fully, I have doubts. The book is an excellent refresh of knowledge I have put into practice over the years. Originally, I accepted shared libraries and made many of my own in professional settings. Around 2011, I perceived that perhaps it would be better to take a different direction.
A statically compiled program is more self-contained. All the code is in the program and is not split across various directories or files. It is a straightforward thing for a writer of malware to cleverly replace one or more of those shared library files with a version that is tailored with unwanted actions. A statically compiled program is far less susceptible to this type of hijacking.
A Researcher Discloses Methods For Bypassing All OS X Security Protections in which dylibs were compromised. That is nothing new, but what it shows is the implicit trust given to shared libraries. They are a critical part of how modern systems operate. The leading views on systems design assert the many advantages of shared shared libraries. Is there a compromise view that can increase security?
I wrote about 3 ways to improve security. That includes white-listing, technical reductionism, and machine learning. Time to focus on that second part. Technical reduction does include simplifying technology or streamlining implementations to reduce attack surface area. Shared libraries reduce the file size of executables that rely on them and that appears to simplify things. Instead, what if shared libraries became a tool primarily used for operating systems and kernel level processes, but not user mode programs?
This would reduce the amount of system wide shared libraries in use beyond core system operations. That allows operating system authors to tighten code further in those situations. The critique of statically compiled software is that the files are larger and updates require more effort. Imagine 3 different programs that all use the same publicly available code for showing photos. Maybe one program shows the photo as part of an employee update form. Another program stitches photos together. A third program creates a preview of a photo attached as part of a communication. All of them use the same common code that today is addressed by a shared library.
The benefit of a shared library in that scenario is improvements to the common code can be made available to multiple programs. When the improvements include malware, then it is a liability. You can still hijack statically compiled software if there are certain weaknesses in the code. The difference is that system wide liabilities have diminished. Programs where remaining flaws are actively cleared rather than slowly amended are rewarded with higher use by the wider population.
I rely on shared libraries as much as anyone. During private software development efforts, I am using shared libraries from repositories as do that is quick, convenient and almost effortless. Proceeding quickly through multiple revisions of a program is aided by such infrastructure. In the past, I have published articles featuring code I translate into a statically compiled executable. The effort to do so always seemed more involved but worthwhile.
The effort required to sustain statically compiled programs may be necessary in coming years. Google has created a programming language called Go with associated infrastructure that is statically compiled by default. They have well-reasoned thoughts for doing this. I talk about their efforts in an article, Things about Google Go that May Improve Software Engineering. Their justification differs from what I present here except I fully agree it is good to have certainty regarding program dependencies. The formulation for achieving this in Go seems highly streamlined. It may yet become a wider model for the composition and deployment of software.
I plan to finish the book by mid May 2015, depending on time. No general review is planned. I may have something to say the value of the knowledge. Regardless of my preferences, if I was to chose between poorly designed statically compiled software and well-written software that relies heavily on shared libraries, I will definitely go with the latter.