Thursday, December 3, 2009

Chapter 11 Performance tests

In order to compare the different solutions against buffer overflow attacks, and more precisely their performance costs, we have carried out a few tests that we present here.

Our aim is not to do a very precise study concerning these performances, but more to point out what Libsafe may change when we use its re-written functions, and if there is an important loss on basic programs when we use Grsecurity patches.

11.1 Process

Our aim is to compare the execution time of a choosen program on a system running:

• a simple 2.4.17 Kernel

• a 2.4.17 Kernel, with Open Wall feature enabled

• a 2.4.17 Kernel, with PaX feature enabled

• a 2.4.17 Kernel, with Grsecurity's mmap feature enabled

We also wish to determine the influence of Libsafe on such performances. Thus, each program is run:

• with each Kernel, without libsafe

• with each Kernel, having libsafe enabled via /etc/ld.so.preload

We have decided to use programs based on a very simple scheme for our tests. They consist in a loop calling a function which is re-implemented in libsafe, such as strcpy or strcat. Here is a pseudo-code illustration:

for(i = 0 ; i < N ;

vulnerable_function(destination_buffer, source_buffer);

Buffer sizes are choosen to avoid any overflow, and are rather great (8192 characters in the strcat case, 32000 characters in the strcpy case).

We run these test programs using the time command, one hundred times, and we add the execution lengths. We use a Pentium II 233 MHZ, 256 MB RAM.

Figures presenting our results may be found in appendix (page 100)

11.2 Analysis

Two elements may be mentionned:

• Kernel patches do not seem to affect performances on such simple tests

• Libsafe re-implementation may slow down or speed up the execution, depending on the used func­tion.

The first point is really interesting, as it means that adding such a protection does not bring any hard performance decrease. More in-depth tests should be carried out on real applications, but this is quite encouraging.

On the other hand, Libsafe plays a very different role. Its influence strongly depends on which re­written function is used. The principle of Libsafe, when re-implementing a function, is to check out its arguments for safety, and then call the real libc function, which means it should take a little longer to execute when libsafe is activated (that is exactly what we can see with strcpy). The strcat implementation is different, as no call to the original libc function is made. The copy mechanism has been really improved in libsafe, which explains the results (the more characters are copied, the more impressive the difference is). This issue is discussed in libsafe's conceptors document, Libsafe: Protecting critical elements of Stacks.

A first conclusion of this test set is that a system oriented solution based on a Kernel patch does not seem extremly costly for such simple programs. A libsafe enhancement is, generally speaking, much more costly.

11.3   Miscellaneous notes

We should not be too optimistic concerning Kernel patches. For instance, because of a PaX patch, the system stack and heap become non executable, which prevents some applications from working: it is the case for XFree86 4 servers.

As well, some programming languages such as ADA or Java (virtual machine) require an executable stack.

Some solutions exist (chpax, trampolines) but it may be seen as a breach in the wall we intend to build against buffer overflow attacks.

Some interesting information may be found at http://www.grsecurity.net/features.htm. Nevertheless, the Open Wall patch is not supposed to decrease performances too significantly.

No comments:

Post a Comment