1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <stdint.h> 30 #include <string.h> 31 32 #include <vector> 33 34 #include "backtrace.h" 35 #include "Config.h" 36 #include "debug_disable.h" 37 #include "debug_log.h" 38 #include "DebugData.h" 39 #include "malloc_debug.h" 40 #include "GuardData.h" 41 42 GuardData::GuardData(DebugData* debug_data, int init_value, size_t num_bytes) 43 : OptionData(debug_data) { 44 // Create a buffer for fast comparisons of the front guard. 45 cmp_mem_.resize(num_bytes); 46 memset(cmp_mem_.data(), init_value, cmp_mem_.size()); 47 } 48 49 void GuardData::LogFailure(const Header* header, const void* pointer, const void* data) { 50 error_log(LOG_DIVIDER); 51 error_log("+++ ALLOCATION %p SIZE %zu HAS A CORRUPTED %s GUARD", pointer, 52 header->real_size(), GetTypeName()); 53 54 // Log all of the failing bytes. 55 const uint8_t* expected = cmp_mem_.data(); 56 int pointer_idx = reinterpret_cast<uintptr_t>(data) - reinterpret_cast<uintptr_t>(pointer); 57 const uint8_t* real = reinterpret_cast<const uint8_t*>(data); 58 for (size_t i = 0; i < cmp_mem_.size(); i++, pointer_idx++) { 59 if (real[i] != expected[i]) { 60 error_log(" allocation[%d] = 0x%02x (expected 0x%02x)", pointer_idx, real[i], expected[i]); 61 } 62 } 63 64 error_log("Backtrace at time of failure:"); 65 std::vector<uintptr_t> frames(64); 66 size_t frame_num = backtrace_get(frames.data(), frames.size()); 67 frames.resize(frame_num); 68 backtrace_log(frames.data(), frames.size()); 69 error_log(LOG_DIVIDER); 70 } 71 72 FrontGuardData::FrontGuardData(DebugData* debug_data, const Config& config, size_t* offset) 73 : GuardData(debug_data, config.front_guard_value, config.front_guard_bytes) { 74 // Create a buffer for fast comparisons of the front guard. 75 cmp_mem_.resize(config.front_guard_bytes); 76 memset(cmp_mem_.data(), config.front_guard_value, cmp_mem_.size()); 77 // Assumes that front_bytes is a multiple of MINIMUM_ALIGNMENT_BYTES. 78 offset_ = *offset; 79 *offset += config.front_guard_bytes; 80 } 81 82 bool FrontGuardData::Valid(const Header* header) { 83 return GuardData::Valid(debug_->GetFrontGuard(header)); 84 } 85 86 void FrontGuardData::LogFailure(const Header* header) { 87 GuardData::LogFailure(header, debug_->GetPointer(header), debug_->GetFrontGuard(header)); 88 } 89 90 RearGuardData::RearGuardData(DebugData* debug_data, const Config& config) 91 : GuardData(debug_data, config.rear_guard_value, config.rear_guard_bytes) { 92 } 93 94 bool RearGuardData::Valid(const Header* header) { 95 return GuardData::Valid(debug_->GetRearGuard(header)); 96 } 97 98 void RearGuardData::LogFailure(const Header* header) { 99 GuardData::LogFailure(header, debug_->GetPointer(header), debug_->GetRearGuard(header)); 100 } 101