diff options
Diffstat (limited to 'libstdc++-v3/libsupc++/vtv_fail.cc')
-rw-r--r-- | libstdc++-v3/libsupc++/vtv_fail.cc | 233 |
1 files changed, 0 insertions, 233 deletions
diff --git a/libstdc++-v3/libsupc++/vtv_fail.cc b/libstdc++-v3/libsupc++/vtv_fail.cc deleted file mode 100644 index 4f183d8cac2..00000000000 --- a/libstdc++-v3/libsupc++/vtv_fail.cc +++ /dev/null @@ -1,233 +0,0 @@ -/* Copyright (C) 2012-2013 - Free Software Foundation - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - GCC is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - <http://www.gnu.org/licenses/>. */ - -/* This file is part of the vtable security feature implementation. - The vtable security feature is designed to detect when a virtual - call is about to be made through an invalid vtable pointer - (possibly due to data corruption or malicious attacks). - - This file also contains the failure functions that get called when - a vtable pointer is not found in the data set. Two particularly - important functions are __vtv_verify_fail and __vtv_really_fail. - They are both externally visible. __vtv_verify_fail is defined in - such a way that it can be replaced by a programmer, if desired. It - is the function that __VLTVerifyVtablePointer calls if it can't - find the pointer in the data set. Allowing the programmer to - overwrite this function means that he/she can do some alternate - verification, including NOT failing in certain specific cases, if - desired. This may be the case if the programmer has to deal wtih - unverified third party software, for example. __vtv_really_fail is - available for the programmer to call from his version of - __vtv_verify_fail, if he decides the failure is real. - -*/ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <execinfo.h> -#include <unistd.h> - -#include "vtv_utils.h" -#include "vtv_fail.h" - -/* This is used to disable aborts for debugging purposes. */ -bool vtv_no_abort = false; - - -extern "C" { - - /* __fortify_fail is a function in glibc that calls __libc_message, - causing it to print out a program termination error message - (including the name of the binary being terminated), a stack - trace where the error occurred, and a memory map dump. Ideally - we would have called __libc_message directly, but that function - does not appear to be accessible to functions outside glibc, - whereas __fortify_fail is. We call __fortify_fail from - __vtv_really_fail. We looked at calling __libc_fatal, which is - externally accessible, but it does not do the back trace and - memory dump. */ - - extern void __fortify_fail (const char *) __attribute__((noreturn)); - -} /* extern "C" */ - -const unsigned long SET_HANDLE_HANDLE_BIT = 0x2; - -/* Instantiate the template classes (in vtv_set.h) for our particular - hash table needs. */ -typedef void * vtv_set_handle; -typedef vtv_set_handle * vtv_set_handle_handle; - -static int vtv_failures_log_fd = -1; - -/* Open error logging file, if not already open, and write vtable - verification failure messages (LOG_MSG) to the log file. Also - generate a backtrace in the log file, if GENERATE_BACKTRACE is - set. */ - -static void -log_error_message (const char *log_msg, bool generate_backtrace) -{ - if (vtv_failures_log_fd == -1) - vtv_failures_log_fd = vtv_open_log ("vtable_verification_failures.log"); - - if (vtv_failures_log_fd == -1) - return; - - vtv_add_to_log (vtv_failures_log_fd, "%s", log_msg); - - if (generate_backtrace) - { -#define STACK_DEPTH 20 - void *callers[STACK_DEPTH]; - int actual_depth = backtrace (callers, STACK_DEPTH); - backtrace_symbols_fd (callers, actual_depth, vtv_failures_log_fd); - } -} - -/* In the case where a vtable map variable is the only instance of the - variable we have seen, it points directly to the set of valid - vtable pointers. All subsequent instances of the 'same' vtable map - variable point to the first vtable map variable. This function, - given a vtable map variable PTR, checks a bit to see whether it's - pointing directly to the data set or to the first vtable map - variable. */ - -static inline bool -is_set_handle_handle (void * ptr) -{ - return ((unsigned long) ptr & SET_HANDLE_HANDLE_BIT) - == SET_HANDLE_HANDLE_BIT; -} - -/* Returns the actual pointer value of a vtable map variable, PTR (see - comments for is_set_handle_handle for more details). */ - -static inline vtv_set_handle * -ptr_from_set_handle_handle (void * ptr) -{ - return (vtv_set_handle *) ((unsigned long) ptr & ~SET_HANDLE_HANDLE_BIT); -} - -/* Given a vtable map variable, PTR, this function sets the bit that - says this is the second (or later) instance of a vtable map - variable. */ - -static inline vtv_set_handle_handle -set_handle_handle (vtv_set_handle * ptr) -{ - return (vtv_set_handle_handle) ((unsigned long) ptr | SET_HANDLE_HANDLE_BIT); -} - -/* This function is called from __VLTVerifyVtablePointerDebug; it - sends as much debugging information as it can to the error log - file, then calls __vtv_verify_fail. SET_HANDLE_PTR is the pointer - to the set of valid vtable pointers, VTBL_PTR is the pointer that - was not found in the set, and DEBUG_MSG is the message to be - written to the log file before failing. n */ - -void -__vtv_verify_fail_debug (void **set_handle_ptr, const void *vtbl_ptr, - const char *debug_msg) -{ - log_error_message (debug_msg, false); - - /* Call the public interface in case it has been overwritten by - user. */ - __vtv_verify_fail (set_handle_ptr, vtbl_ptr); - - log_error_message ("Returned from __vtv_verify_fail." - " Secondary verification succeeded.\n", false); -} - -/* This function calls __fortify_fail with a FAILURE_MSG and then - calls abort. */ - -void -__vtv_really_fail (const char *failure_msg) -{ - __fortify_fail (failure_msg); - - /* We should never get this far; __fortify_fail calls __libc_message - which prints out a back trace and a memory dump and then is - supposed to call abort, but let's play it safe anyway and call abort - ourselves. */ - abort (); -} - -/* This function takes an error MSG, a vtable map variable - (DATA_SET_PTR) and a vtable pointer (VTBL_PTR). It is called when - an attempt to verify VTBL_PTR with the set pointed to by - DATA_SET_PTR failed. It outputs a failure message with the - addresses involved, and calls __vtv_really_fail. */ - -static void -vtv_fail (const char *msg, void **data_set_ptr, const void *vtbl_ptr) -{ - char buffer[128]; - int buf_len; - const char *format_str = - "*** Unable to verify vtable pointer (%p) in set (%p) *** \n"; - - snprintf (buffer, sizeof (buffer), format_str, vtbl_ptr, - is_set_handle_handle(*data_set_ptr) ? - ptr_from_set_handle_handle (*data_set_ptr) : - *data_set_ptr); - buf_len = strlen (buffer); - /* Send this to to stderr. */ - write (2, buffer, buf_len); - - if (!vtv_no_abort) - __vtv_really_fail (msg); -} - -/* Send information about what we were trying to do when verification - failed to the error log, then call vtv_fail. This function can be - overwritten/replaced by the user, to implement a secondary - verification function instead. DATA_SET_PTR is the vtable map - variable used for the failed verification, and VTBL_PTR is the - vtable pointer that was not found in the set. */ - -void -__vtv_verify_fail (void **data_set_ptr, const void *vtbl_ptr) -{ - char log_msg[256]; - snprintf (log_msg, sizeof (log_msg), "Looking for vtable %p in set %p.\n", - vtbl_ptr, - is_set_handle_handle (*data_set_ptr) ? - ptr_from_set_handle_handle (*data_set_ptr) : - *data_set_ptr); - log_error_message (log_msg, false); - - const char *format_str = - "*** Unable to verify vtable pointer (%p) in set (%p) *** \n"; - snprintf (log_msg, sizeof (log_msg), format_str, vtbl_ptr, *data_set_ptr); - log_error_message (log_msg, false); - log_error_message (" Backtrace: \n", true); - - const char *fail_msg = "Potential vtable pointer corruption detected!!\n"; - vtv_fail (fail_msg, data_set_ptr, vtbl_ptr); -} - |