In addition to the runtime overhead imposed by Scrash, the system requires some effort from the programmer. This effort includes annotating an initial set of sensitive variables or deciding to use a pre-annotated ``prelude'' file that automatically marks the parameters and return values of certain functions as sensitive. In addition, it was necessary to make 33 lines of source code changes to ssh before it could run through the Scrash transformation, due to the fact that CIL is more restrictive in type checking than gcc. Such changes included fixing missing or mismatched variable declarations.
The performance of the Scrash code transformation tool is adequate. It takes roughly three minutes to run the entire Scrash transformation on ssh, from preprocessing through program modification, using the same test machine as above.
One feature of the ssh code was particularly problematic for Scrash: all calls to malloc are performed using a wrapper function, xmalloc, that checks for a null return value. Recall that Scrash rewrites calls to the malloc function to use smalloc, locating the new region on either the secure or insecure heap as appropriate. Since the ssh program calls the xmalloc wrapper, the only instance of malloc in the ssh source code is within the xmalloc wrapper. Scrash must choose whether to translate this malloc call into an allocation on the secure or insecure heap at compile time. Since the results of this allocation are assigned to some variables declared with the $sensitive keyword, Scrash conservatively translates the malloc call to allocate all its storage on the sensitive heap. As a result, all heap allocations in ssh would normally appear on the sensitive heap. To avoid this problem, we replaced the xmalloc function with an equivalent preprocessor macro at each allocation point. Thus, in the post-processed file, there is now one malloc call where each xmalloc call previously appeared, allowing the different malloc calls to be assigned to different heaps.
We must be a bit careful in evaluating the success of a technique like
Scrash. For example, the absence of the password from the core file does not
mean that there is no sensitive information related to the password in the
core file. It may be possible to ascertain the size of a sensitive
buffer by comparing pointers. If is a pointer to a sensitive data field,
an attacker can bound the size of the sensitive data by comparing all
other heap-allocated pointers, , to the sensitive data pointer:
That is, the size of the buffer at is at most the difference between and the first pointer whose value is greater than . Thus, it may be possible to reveal the length of a variable-sized sensitive buffer even if all variables that explicitly store this length are kept in the sensitive memory region. This apparent vulnerability would seem to suggest that is also sensitive and should be placed on the sensitive heap, adding an extra level of indirection to all accesses to . We eschew this extra indirection, however, in favor of providing greater debugging usefulness to the developer, since hiding the pointer values may hamper the developer's ability to track down memory problems.
Another issue with Scrash involves the use of precompiled and dynamic (shared) libraries. Current libraries such as glibc are written without consideration of the concept of sensitive data. CQual understands the semantics of many glibc functions and will correctly propagate qualifiers across, for example, calls to memcpy. There is no way, however, for a source-level translation like Scrash to modify the storage of variables in precompiled libraries. For example, a precompiled version of strcpy may keep a char temporarily on the stack, or strlen may keep a running string length count as a stack variable. In the event of a crash, these variables will remain on the insecure stack, where they can leak pieces of sensitive information. One solution would be to recompile libraries with Scrash under the assumption that all data passed to a shared library is sensitive. The library would therefore use the shadow stack and sensitive heap so that sensitive data may be passed to the shared library without fear of privacy violations. However, we have not implemented this solution in our prototype.
As we discussed in Section 2.1, there are tradeoffs between user privacy and utility to the developer when dealing with crash information. Scrash provides the developer with a larger set of tradeoffs than the all-or-nothing choice that exists currently, while requiring minimal effort and time to specify and apply these tradeoffs to a program.
We believe that Scrash will help developers to allay users' privacy concerns about using crash reporting tools, and dissuade users from turning off the automatic crash reporting features in their applications. Widespread use of remote crash reporting will aid developers in improving the overall quality of software, in addition to helping make users aware of software patches for problems that they are experiencing.