crashpad/util/mach/exc_client_variants.cc
Mark Mentovai 6645a69240 asan: Fix invalid memory access in UniversalExceptionRaise()
TEST=crashpad_util_test ExcClientVariants.UniversalExceptionRaise
R=rsesek@chromium.org

Review URL: https://codereview.chromium.org/1283323010 .
2015-08-19 18:47:02 -04:00

130 lines
4.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2014 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "util/mach/exc_client_variants.h"
#include <vector>
#include "base/logging.h"
#include "util/mach/exc.h"
#include "util/mach/mach_exc.h"
namespace crashpad {
kern_return_t UniversalExceptionRaise(exception_behavior_t behavior,
exception_handler_t exception_port,
thread_t thread,
task_t task,
exception_type_t exception,
const mach_exception_data_type_t* code,
mach_msg_type_number_t code_count,
thread_state_flavor_t* flavor,
ConstThreadState old_state,
mach_msg_type_number_t old_state_count,
thread_state_t new_state,
mach_msg_type_number_t* new_state_count) {
// This function is similar to 10.9.4 xnu-2422.110.17/osfmk/kern/exception.c
// exception_deliver() as far as the delivery logic is concerned. Unlike
// exception_deliver(), this function does not get or set thread states for
// behavior values that require this, as that is left to the caller to do if
// needed.
std::vector<exception_data_type_t> small_code_vector;
exception_data_t small_code = nullptr;
if ((behavior & MACH_EXCEPTION_CODES) == 0 && code_count) {
small_code_vector.reserve(code_count);
for (size_t code_index = 0; code_index < code_count; ++code_index) {
small_code_vector.push_back(code[code_index]);
}
small_code = &small_code_vector[0];
}
// The *exception_raise*() family has bad declarations. Their code and
// old_state arguments arent pointers to const data, although they should be.
// The generated stubs in excUser.c and mach_excUser.c make it clear that the
// data is never modified, and these parameters could be declared with const
// appropriately. The uses of const_cast below are thus safe.
switch (behavior) {
case EXCEPTION_DEFAULT:
return exception_raise(
exception_port, thread, task, exception, small_code, code_count);
case EXCEPTION_STATE:
return exception_raise_state(exception_port,
exception,
small_code,
code_count,
flavor,
const_cast<thread_state_t>(old_state),
old_state_count,
new_state,
new_state_count);
case EXCEPTION_STATE_IDENTITY:
return exception_raise_state_identity(
exception_port,
thread,
task,
exception,
small_code,
code_count,
flavor,
const_cast<thread_state_t>(old_state),
old_state_count,
new_state,
new_state_count);
case EXCEPTION_DEFAULT | kMachExceptionCodes:
return mach_exception_raise(exception_port,
thread,
task,
exception,
const_cast<mach_exception_data_type_t*>(code),
code_count);
case EXCEPTION_STATE | kMachExceptionCodes:
return mach_exception_raise_state(
exception_port,
exception,
const_cast<mach_exception_data_type_t*>(code),
code_count,
flavor,
const_cast<thread_state_t>(old_state),
old_state_count,
new_state,
new_state_count);
case EXCEPTION_STATE_IDENTITY | kMachExceptionCodes:
return mach_exception_raise_state_identity(
exception_port,
thread,
task,
exception,
const_cast<mach_exception_data_type_t*>(code),
code_count,
flavor,
const_cast<thread_state_t>(old_state),
old_state_count,
new_state,
new_state_count);
default:
NOTREACHED();
return KERN_INVALID_ARGUMENT;
}
}
} // namespace crashpad