blob: 7aea0bd4060bf193e73c033870283f2bd5198312 [file] [log] [blame]
//=== SoftBoundRuntime/softboundcets.c - Creates the main function for SoftBound+CETS Runtime --*- C -*===//
// Copyright (c) 2011 Santosh Nagarakatte, Milo M. K. Martin. All rights reserved.
// Developed by: Santosh Nagarakatte, Milo M.K. Martin,
// Jianzhou Zhao, Steve Zdancewic
// Department of Computer and Information Sciences,
// University of Pennsylvania
// http://www.cis.upenn.edu/acg/softbound/
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal with the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimers.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimers in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the names of Santosh Nagarakatte, Milo M. K. Martin,
// Jianzhou Zhao, Steve Zdancewic, University of Pennsylvania, nor
// the names of its contributors may be used to endorse or promote
// products derived from this Software without specific prior
// written permission.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// WITH THE SOFTWARE.
//===---------------------------------------------------------------------===//
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#if defined(__linux__)
#include <malloc.h>
#endif
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <sys/mman.h>
#if !defined(__FreeBSD__)
#include <execinfo.h>
#endif
#include "softboundcets.h"
__softboundcets_trie_entry_t** __softboundcets_trie_primary_table;
size_t* __softboundcets_free_map_table = NULL;
size_t* __softboundcets_shadow_stack_ptr = NULL;
size_t* __softboundcets_lock_next_location = NULL;
size_t* __softboundcets_lock_new_location = NULL;
size_t __softboundcets_key_id_counter = 2;
#ifdef __SOFTBOUNDCETS_STATISTICS_MODE
size_t __softboundcets_statistics_metadata_memcopies = 0;
size_t __softboundcets_statistics_spatial_load_dereference_checks = 0;
size_t __softboundcets_statistics_spatial_store_dereference_checks = 0;
size_t __softboundcets_statistics_temporal_load_dereference_checks = 0;
size_t __softboundcets_statistics_temporal_store_dereference_checks = 0;
size_t __softboundcets_statistics_metadata_loads = 0;
size_t __softboundcets_statistics_metadata_stores = 0;
size_t __softboundcets_statistics_heap_allocations = 0;
size_t __softboundcets_statistics_stack_allocations = 0;
size_t __softboundcets_statistics_heap_deallocations = 0;
size_t __softboundcets_statistics_stack_deallocations = 0;
#endif
/* key 0 means not used, 1 means globals*/
size_t __softboundcets_deref_check_count = 0;
size_t* __softboundcets_global_lock = 0;
size_t* __softboundcets_temporal_space_begin = 0;
size_t* __softboundcets_stack_temporal_space_begin = NULL;
void* malloc_address = NULL;
#ifdef __SOFTBOUNDCETS_STATISTICS_MODE
static __attribute__ ((__destructor__))
void __softboundcets_statistics_fini() {
// 4kB page size, 1024*1024 bytes per MB,
const double MULTIPLIER = 4096.0/(1024.0*1024.0);
FILE* proc_file, *statistics_file;
size_t total_size_in_pages = 0;
size_t res_size_in_pages = 0;
statistics_file = fopen("bench_statistics.log", "w");
assert(statistics_file != NULL);
proc_file = fopen("/proc/self/statm", "r");
fscanf(proc_file, "%zd %zd", &total_size_in_pages, &res_size_in_pages);
fprintf(statistics_file, "memory_total: %lf \n", total_size_in_pages*MULTIPLIER);
fprintf(statistics_file, "memory_resident: %lf \n", res_size_in_pages*MULTIPLIER);
fprintf(statistics_file, "Num_spatial_load_checks:%zd\n",
__softboundcets_statistics_spatial_load_dereference_checks);
fprintf(statistics_file, "Num_spatial_store_checks:%zd\n",
__softboundcets_statistics_spatial_store_dereference_checks);
fprintf(statistics_file, "Num_temporal_load_checks:%zd\n",
__softboundcets_statistics_temporal_load_dereference_checks);
fprintf(statistics_file, "Num_temporal_store_checks:%zd\n",
__softboundcets_statistics_temporal_store_dereference_checks);
fprintf(statistics_file, "Num_metadata_loads:%zd\n",
__softboundcets_statistics_metadata_loads);
fprintf(statistics_file, "Num_metadata_stores:%zd\n",
__softboundcets_statistics_metadata_stores);
fprintf(statistics_file, "Num_heap_allocations:%zd\n",
__softboundcets_statistics_heap_allocations);
fprintf(statistics_file, "Num_stack_allocations:%zd\n",
__softboundcets_statistics_stack_allocations);
fprintf(statistics_file, "Num_heap_deallocations:%zd\n",
__softboundcets_statistics_heap_deallocations);
fprintf(statistics_file, "Num_stack_deallocations:%zd\n",
__softboundcets_statistics_stack_deallocations);
fprintf(statistics_file, "Num_metadata_memcopies:%zd\n",
__softboundcets_statistics_metadata_memcopies);
fprintf(statistics_file,
"============================================\n");
fclose(statistics_file);
}
#endif
__SOFTBOUNDCETS_NORETURN void __softboundcets_abort()
{
fprintf(stderr, "\nSoftboundcets: Bounds violation detected\n\nBacktrace:\n");
// Based on code from the backtrace man page
size_t size;
void *array[100];
#if !defined (__FreeBSD__)
size = backtrace(array, 100);
backtrace_symbols_fd(array, size, fileno(stderr));
#endif
fprintf(stderr, "\n\n");
abort();
}
static int softboundcets_initialized = 0;
__NO_INLINE void __softboundcets_stub(void) {
return;
}
void __softboundcets_init( int is_trie)
{
if (__SOFTBOUNDCETS_DEBUG) {
__softboundcets_printf("Running __softboundcets_init for module\n");
}
if (is_trie != __SOFTBOUNDCETS_TRIE) {
__softboundcets_printf("Softboundcets: Inconsistent specification of metadata encoding\n");
abort();
}
if (softboundcets_initialized != 0) {
return; // already initialized, do nothing
}
softboundcets_initialized = 1;
if (__SOFTBOUNDCETS_DEBUG) {
__softboundcets_printf("Initializing softboundcets metadata space\n");
}
if(__SOFTBOUNDCETS_TRIE){
assert(sizeof(__softboundcets_trie_entry_t) >= 16);
}
/* Allocating the temporal shadow space */
size_t temporal_table_length = (__SOFTBOUNDCETS_N_TEMPORAL_ENTRIES)* sizeof(void*);
__softboundcets_lock_new_location = mmap(0, temporal_table_length,
PROT_READ| PROT_WRITE,
SOFTBOUNDCETS_MMAP_FLAGS, -1, 0);
assert(__softboundcets_lock_new_location != (void*) -1);
__softboundcets_temporal_space_begin = (size_t *)__softboundcets_lock_new_location;
size_t stack_temporal_table_length = (__SOFTBOUNDCETS_N_STACK_TEMPORAL_ENTRIES) * sizeof(void*);
__softboundcets_stack_temporal_space_begin = mmap(0, stack_temporal_table_length,
PROT_READ| PROT_WRITE,
SOFTBOUNDCETS_MMAP_FLAGS, -1, 0);
assert(__softboundcets_stack_temporal_space_begin != (void*) -1);
size_t global_lock_size = (__SOFTBOUNDCETS_N_GLOBAL_LOCK_SIZE) * sizeof(void*);
__softboundcets_global_lock = mmap(0, global_lock_size,
PROT_READ|PROT_WRITE,
SOFTBOUNDCETS_MMAP_FLAGS, -1, 0);
assert(__softboundcets_global_lock != (void*) -1);
// __softboundcets_global_lock = __softboundcets_lock_new_location++;
*((size_t*)__softboundcets_global_lock) = 1;
size_t shadow_stack_size = __SOFTBOUNDCETS_SHADOW_STACK_ENTRIES * sizeof(size_t);
__softboundcets_shadow_stack_ptr = mmap(0, shadow_stack_size,
PROT_READ|PROT_WRITE,
SOFTBOUNDCETS_MMAP_FLAGS, -1, 0);
assert(__softboundcets_shadow_stack_ptr != (void*)-1);
*((size_t*)__softboundcets_shadow_stack_ptr) = 0; /* prev stack size */
size_t * current_size_shadow_stack_ptr = __softboundcets_shadow_stack_ptr +1 ;
*(current_size_shadow_stack_ptr) = 0;
if(__SOFTBOUNDCETS_SHADOW_STACK_DEBUG){
printf("[mmap_shadow_stack]mmaped shadowstack pointer = %p\n",
__softboundcets_shadow_stack_ptr);
}
if(__SOFTBOUNDCETS_FREE_MAP) {
size_t length_free_map = (__SOFTBOUNDCETS_N_FREE_MAP_ENTRIES) * sizeof(size_t);
__softboundcets_free_map_table = mmap(0, length_free_map,
PROT_READ| PROT_WRITE,
SOFTBOUNDCETS_MMAP_FLAGS, -1, 0);
assert(__softboundcets_free_map_table != (void*) -1);
}
if(__SOFTBOUNDCETS_TRIE) {
size_t length_trie = (__SOFTBOUNDCETS_TRIE_PRIMARY_TABLE_ENTRIES) * sizeof(__softboundcets_trie_entry_t*);
__softboundcets_trie_primary_table = mmap(0, length_trie,
PROT_READ| PROT_WRITE,
SOFTBOUNDCETS_MMAP_FLAGS, -1, 0);
assert(__softboundcets_trie_primary_table != (void *)-1);
int* temp = malloc(1);
__softboundcets_allocation_secondary_trie_allocate_range(0, (size_t)temp);
return;
}
}
static void softboundcets_init_ctype(){
#if defined(__linux__)
char* ptr;
char* base_ptr;
ptr = (void*) __ctype_b_loc();
base_ptr = (void*) (*(__ctype_b_loc()));
__softboundcets_allocation_secondary_trie_allocate(base_ptr);
#ifdef __SOFTBOUNDCETS_SPATIAL
__softboundcets_metadata_store(ptr, ((char*) base_ptr - 129),
((char*) base_ptr + 256));
#elif __SOFTBOUNDCETS_TEMPORAL
__softboundcets_metadata_store(ptr, 1, __softboundcets_global_lock);
#elif __SOFTBOUNDCETS_SPATIAL_TEMPORAL
__softboundcets_metadata_store(ptr, ((char*) base_ptr - 129),
((char*) base_ptr + 256), 1,
__softboundcets_global_lock);
#else
__softboundcets_metadata_store(ptr, ((char*) base_ptr - 129),
((char*) base_ptr + 256), 1,
__softboundcets_global_lock);
#endif
#endif // __linux ends
}
void __softboundcets_printf(const char* str, ...)
{
va_list args;
va_start(args, str);
vfprintf(stderr, str, args);
va_end(args);
}
extern int softboundcets_pseudo_main(int argc, char **argv);
int main(int argc, char **argv){
#if __WORDSIZE == 32
exit(1);
#endif
char** new_argv = argv;
int i;
char* temp_ptr;
int return_value;
size_t argv_key;
void* argv_loc;
int* temp = malloc(1);
malloc_address = temp;
__softboundcets_allocation_secondary_trie_allocate_range(0, (size_t)temp);
__softboundcets_stack_memory_allocation(&argv_loc, &argv_key);
#if defined(__linux__)
mallopt(M_MMAP_MAX, 0);
#endif
for(i = 0; i < argc; i++) {
#ifdef __SOFTBOUNDCETS_SPATIAL
__softboundcets_metadata_store(&new_argv[i],
new_argv[i],
new_argv[i] + strlen(new_argv[i]) + 1);
#elif __SOFTBOUNDCETS_TEMPORAL
// printf("performing metadata store\n");
__softboundcets_metadata_store(&new_argv[i],
argv_key, argv_loc);
#elif __SOFTBOUNDCETS_SPATIAL_TEMPORAL
__softboundcets_metadata_store(&new_argv[i],
new_argv[i],
new_argv[i] + strlen(new_argv[i]) + 1,
argv_key, argv_loc);
#else
__softboundcets_metadata_store(&new_argv[i],
new_argv[i],
new_argv[i] + strlen(new_argv[i]) + 1,
argv_key, argv_loc);
#endif
}
// printf("before init_ctype\n");
softboundcets_init_ctype();
/* Santosh: Real Nasty hack because C programmers assume argv[argc]
* to be NULL. Also this NUll is a pointer, doing + 1 will make the
* size_of_type to fail
*/
temp_ptr = ((char*) &new_argv[argc]) + 8;
/* &new_argv[0], temp_ptr, argv_key, argv_loc * the metadata */
__softboundcets_allocate_shadow_stack_space(2);
#ifdef __SOFTBOUNDCETS_SPATIAL
__softboundcets_store_base_shadow_stack(&new_argv[0], 1);
__softboundcets_store_bound_shadow_stack(temp_ptr, 1);
#elif __SOFTBOUNDCETS_TEMPORAL
// printf("before writing to shadow stack\n");
__softboundcets_store_key_shadow_stack(argv_key, 1);
__softboundcets_store_lock_shadow_stack(argv_loc, 1);
#elif __SOFTBOUNDCETS_SPATIAL_TEMPORAL
__softboundcets_store_base_shadow_stack(&new_argv[0], 1);
__softboundcets_store_bound_shadow_stack(temp_ptr, 1);
__softboundcets_store_key_shadow_stack(argv_key, 1);
__softboundcets_store_lock_shadow_stack(argv_loc, 1);
#else
__softboundcets_store_base_shadow_stack(&new_argv[0], 1);
__softboundcets_store_bound_shadow_stack(temp_ptr, 1);
__softboundcets_store_key_shadow_stack(argv_key, 1);
__softboundcets_store_lock_shadow_stack(argv_loc, 1);
#endif
// printf("before calling program main\n");
return_value = softboundcets_pseudo_main(argc, new_argv);
__softboundcets_deallocate_shadow_stack_space();
__softboundcets_stack_memory_deallocation(argv_key);
return return_value;
}
void * __softboundcets_safe_mmap(void* addr,
size_t length, int prot,
int flags, int fd,
off_t offset){
return mmap(addr, length, prot, flags, fd, offset);
}
void* __softboundcets_safe_calloc(size_t nmemb, size_t size){
return calloc(nmemb, size);
}
void* __softboundcets_safe_malloc(size_t size){
return malloc(size);
}
void __softboundcets_safe_free(void* ptr){
free(ptr);
}