Pages

Tuesday, January 31, 2017

C, Solaris & SPARC M7: Get Defensive with Few Techniques .. Part 3/3

SPARC: Silicon Secured Memory (SSM)

Silicon Secured Memory (SSM) is a hardware feature available on the latest Oracle SPARC M7/T7/S7 platform that is designed to protect against invalid data accesses such as freed memory accesses, stale pointer references and buffer overflows real-time. It stops unauthorized access to memory whether that access is due to a programming error or a malicious attempt to exploit buffer overruns. This feature is designed to help prevent security vulnerabilities such as Heartbleed ♡. The hardware does it by comparing the version number stored in software managed pointer with the version number maintained in the memory cache lines§. A mismatch leads to a hardware trap that ultimately turns to an error.

This feature can be used during application development as well as in production to detect potential memory corruption issues. Applications written in programming languages such as C/C++ benefit the most as manual memory management plays an important role in those applications making them vulnerable to memory corruption triggered by programming errors. Existing applications can be enabled with SSM [without recompiling] by linking with a Oracle Solaris library during runtime. The overhead incurred by enabling this feature is minimal as the hardware has to generate a trap to report the error only when there is a memory access error.

As of now only 64-bit binaries can take advantage of SSM feature. One requirement is that allocated memory (target memory area for checking memory errors) needs to be 64-byte aligned and its size must be multiple of 64. Also watchout for other requirements and limitations that were outlined in some of the documents listed at the bottom of this post.

Rest of this blog post uses the following buggy code to demonstrate Silicon Secured Memory (SSM) feature.

% cat -n memerr.c

     1  #include <stdio.h>
     2  #include <stdlib.h>
     3  #include <string.h>
     4
     5  void main(int argc, char *argv[])
     6  {
     7          char *longstr  = malloc( sizeof(char) * 64 );
     8          char *longstr2 = malloc( sizeof(char) * 64 );
     9
    10          strcpy( longstr , argv[1] );
    11          strcpy( longstr2, argv[2] );
    12
    13          for (int i = 0; i < 96; ++i)
    14                  printf( "%c ", longstr[i] ); /* read beyond boundary */
    15          printf( "\n" );
    16
    17          free( longstr );
    18          free( longstr2 );
    19
    20          strcpy( longstr , argv[2] ); /* freed memory access */
    21          strcpy( longstr2, argv[1] ); /* freed memory access */
    22
    23          for (int i = 0; i < 96; ++i)
    24                  printf( "%c ", longstr[i] );
    25          printf( "\n" );
    26
    27          free( longstr );  /* double free */
    28          free( longstr2 );  /* double free */
    29  }

% cc -g -m64 -o memerr memerr.c

SSM in Development Environment

Rely on Oracle Solaris Studio Code Analyzer and SSM to find and fix memory access errors.

Couple of options here. Both options require access to Oracle Solaris Studio 12.4 4/15 Platform Specific Enhancement (PSE) or later software.

  1. Preload libdiscoverADI library and run the application. This will run all 64-bit binaries in the application in SSM mode.

    % LD_PRELOAD_64=<install-dir>/lib/compilers/sparcv9/libdiscoverADI.so ./memerr
    
  2. Enable discover utility to detect and understand runtime memory access errors identified by ADI. This can be done on a per binary basis in a large application.

     .. on build system ..
    % discover -i adi -A on -P on -w memerrs.txt memerr
    
     .. on deployment system (M7/T7/S7) ..
    % ./memerr jack jill
    j a c k                                                             j i l l
    j i l l                                                             j a c k
    
    % cat memerrs.txt
    ERROR 1 (ABR): reading memory beyond array bounds at address 0x2fffffff7d47e040 {memory: v3}:
            main() + 0x7c  
        was allocated at (0x2fffffff7d47e000, 64 bytes):
            main() + 0x10  
    ERROR 2 (FMW): writing to freed memory at address 0x2fffffff7d47e000 {memory: v9}:
            strcpy() + 0x4c
            _start() + 0x108
        was allocated at (0x2fffffff7d47e000, 64 bytes):
            main() + 0x10  
        freed at (0x2fffffff7d47e000, 64 bytes):
            main() + 0xc4  
     ...
     ...
    ERROR 12 (DFM): double freeing memory at address 0x3fffffff7d47e040 {memory: v10}:
            main() + 0x17c  
        was allocated at (0x3fffffff7d47e040, 64 bytes):
            main() + 0x20  
        freed at (0x3fffffff7d47e040, 64 bytes):
            main() + 0xd0  
    DISCOVER SUMMARY:
            unique errors   : 12 (12 total)
    
    
     .. running the ADI enabled binary on a non-SSM system fails ..
    % ./memerr
    adi_set_enabled() failed: Operation not supported
    ADI/SSM is only supported on SPARC-xx machines. See discover -i adi documentation for more information
    

SSM in Production Environment

Preload libadimalloc(3LIB) library on target M7/T7/S7 system to enable real-time data protection. Data integrity is the ultimate goal.

Check the platform supported extensions to ensure that the target M7/T7/S7 system is SSM-ready.

% isainfo -v
64-bit sparcv9 applications
 ...
        xmpmul mwait sparc5 adi vis3b

Check the normal behavior of the above sample code that has quite a few memory access errors.

% ./memerr jack jill
j a c k    ▒                                                                A         j i l l    ▒
j i l l    ▒                                                                A         j a c k    ▒

Now check the behavior of the same buggy code under SSM surveillance.

% LD_PRELOAD_64=/lib/64/libadimalloc.so.1 ./memerr jack jill
Segmentation Fault (core dumped)

% echo ::status | mdb core
debugging core file of memerr (64-bit) from dummyhost
file: /var/tmp/memerr
initial argv: ./memerr jack jill
threading model: native threads
status: process terminated by SIGSEGV (Segmentation Fault), pc=100000bbc
, ADI version d mismatch for VA ffffffff7b13ff80

Notice that an existing binary was used as is in the above example to show the benefit of SSM in catching potential memory corruption issues.


For details, SEE:

Credit: various

No comments:

Post a Comment