Sections 4.2.1 and 4.2.2 present microbenchmark results on the additional cost of function calls in programs protected by StackGuard. However, these measurements are upper bounds on the real costs of running programs under StackGuard; the true penalty of running StackGuard-enhanced programs is the overall cost, not the microbenchmark cost. We have benchmarked two programs: ctags, and the StackGuard-enhanced gcc compiler itself.
The ctags program constructs an index of C source code. It is 3000 lines of C source code, comprising 68 separate functions. When run over a small set of source files (78 files, 37,000 lines of code) with a hot buffer cache, ctags is completely compute-bound. When run over a large set of files (1163 files, 567,000 lines of code) ctags it is still compute-bound, because of the large amount of RAM in our test machine.
On a smaller machine, the test becomes I/O bound, consuming 50% of the CPU's time, so it is approximately balanced. While the Canary variant still consumes more CPU time than the generic program, it is overlapped with disk I/O, and the program completes in the same amount of real time. The MemGuard variants consume so much CPU time that the program's real time is dramatically impacted.
Input | Version | User Time | System Time | Real Time |
37,000 lines | Generic | 0.41 | 0.14 | 0.55 |
Canary | 0.68 | 0.13 | 0.99 | |
MemGuard Register | 1.30 | 5.45 | 6.84 | |
MemGuard VM | 16.5 | 238.0 | 255.1 | |
586,000 lines | Generic | 7.74 | 2.08 | 10.2 |
Canary | 11.9 | 2.07 | 14.5 | |
MemGuard Register | 21.1 | 91.5 | 115.0 | |
MemGuard VM | 236 | 3482 | 3728 |
Table 4 shows ctag's run-time in these two cases. The Canary variant's performance penalties are moderate, at 80% for the small case, and 42% for the large case. The MemGuard Register penalties are substantial, at 1100% for the small case, and 1000% for the large case. The MemGuard VM performance penalties are prohibitive, at 46,000% for the small case, and 36,000% for the large case.
Version | User Time | System Time | Real Time |
Generic | 1.70 | 0.12 | 1.83 |
Canary | 1.79 | 0.16 | 1.96 |
MemGuard Register | 2.22 | 3.35 | 5.76 |
MemGuard VM | 8.17 | 87.7 | 96.2 |
Table 5 shows a similar experiment for the run-time of a StackGuard-protected gcc compiler. We thus use a StackGuard-protected gcc to measure the performance cost of StackGuard for a large and complex program. To be clear, the experiment measures the cost of running gcc protected by StackGuard, and only incidentally measures the cost of adding StackGuard protection to the compiled program.
Table 5 shows the time to compile ctags using gcc enhanced with StackGuard. Because there is more computation per function call for gcc than ctags, this time the costs are lower. The Canary version consumes only 6% more CPU time, and only 7% more real time. The MemGuard variants benefited as well; the Register version's additional real time cost is 214%, and the VM version's additional cost is 5100%.
Recall that the StackGuard protective mechanism is only necessary on privileged administrative programs. Such programs present only a minor portion of the compute load on a system, and so the StackGuard overhead will have only a modest impact on the total system load. Thus the overhead measured here could be considered within reason for heightened security, without a significant change in the administrative complexity of the system. We discuss administration of StackGuard in Section 5.