mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 14:06:33 +00:00
ios: Build four more Mach message and exception utilities
This enables the following code in util/mach on iOS: - exception_behaviors.{cc,h} - exception_ports.{cc,h} - mach_message.{cc,h} - mach_message_server.{cc,h} Only the ExceptionBehaviors and MachMessage tests are built, because the other two are tested by multiprocess tests that won’t run on iOS. The AuditPIDFromMachMessageTrailer function from mach_message.h is excluded on iOS because it relies on <bsm/libbsm.h>, which is broken on iOS: it depends on <bsm/audit_record.h>, which is missing from the SDK. Additionally, the BSM function that Crashpad uses, audit_token_to_au32, is marked as unavailable on iOS. Crashpad uses it on macOS to authenticate Mach messages sent by other processes, but this is moot on iOS. Bug: crashpad:31 Change-Id: I5ebc4b80543989b9cd0b85b82eb4b3ff98c44e6c Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2155086 Reviewed-by: Justin Cohen <justincohen@chromium.org> Commit-Queue: Mark Mentovai <mark@chromium.org>
This commit is contained in:
parent
8dbbaff2e1
commit
4cb79941fc
@ -254,8 +254,16 @@ static_library("util") {
|
||||
sources += [
|
||||
"mac/xattr.cc",
|
||||
"mac/xattr.h",
|
||||
"mach/exception_behaviors.cc",
|
||||
"mach/exception_behaviors.h",
|
||||
"mach/exception_ports.cc",
|
||||
"mach/exception_ports.h",
|
||||
"mach/mach_extensions.cc",
|
||||
"mach/mach_extensions.h",
|
||||
"mach/mach_message.cc",
|
||||
"mach/mach_message.h",
|
||||
"mach/mach_message_server.cc",
|
||||
"mach/mach_message_server.h",
|
||||
"misc/clock_mac.cc",
|
||||
"misc/paths_mac.cc",
|
||||
"synchronization/semaphore_mac.cc",
|
||||
@ -284,16 +292,8 @@ static_library("util") {
|
||||
"mach/exc_client_variants.h",
|
||||
"mach/exc_server_variants.cc",
|
||||
"mach/exc_server_variants.h",
|
||||
"mach/exception_behaviors.cc",
|
||||
"mach/exception_behaviors.h",
|
||||
"mach/exception_ports.cc",
|
||||
"mach/exception_ports.h",
|
||||
"mach/exception_types.cc",
|
||||
"mach/exception_types.h",
|
||||
"mach/mach_message.cc",
|
||||
"mach/mach_message.h",
|
||||
"mach/mach_message_server.cc",
|
||||
"mach/mach_message_server.h",
|
||||
"mach/notify_server.cc",
|
||||
"mach/notify_server.h",
|
||||
"mach/scoped_task_suspend.cc",
|
||||
@ -518,9 +518,7 @@ static_library("util") {
|
||||
|
||||
if (crashpad_is_mac || crashpad_is_ios) {
|
||||
include_dirs += [ "$root_build_dir/gen" ]
|
||||
deps += [
|
||||
":mig_output",
|
||||
]
|
||||
deps += [ ":mig_output" ]
|
||||
}
|
||||
|
||||
if (crashpad_is_mac) {
|
||||
@ -530,9 +528,7 @@ static_library("util") {
|
||||
"Foundation.framework",
|
||||
"IOKit.framework",
|
||||
]
|
||||
deps += [
|
||||
"../third_party/apple_cf:apple_cf",
|
||||
]
|
||||
deps += [ "../third_party/apple_cf:apple_cf" ]
|
||||
}
|
||||
|
||||
if (crashpad_is_win) {
|
||||
@ -674,7 +670,9 @@ source_set("util_test") {
|
||||
if (crashpad_is_mac || crashpad_is_ios) {
|
||||
sources += [
|
||||
"mac/xattr_test.cc",
|
||||
"mach/exception_behaviors_test.cc",
|
||||
"mach/mach_extensions_test.cc",
|
||||
"mach/mach_message_test.cc",
|
||||
]
|
||||
}
|
||||
|
||||
@ -689,11 +687,9 @@ source_set("util_test") {
|
||||
"mach/composite_mach_message_server_test.cc",
|
||||
"mach/exc_client_variants_test.cc",
|
||||
"mach/exc_server_variants_test.cc",
|
||||
"mach/exception_behaviors_test.cc",
|
||||
"mach/exception_ports_test.cc",
|
||||
"mach/exception_types_test.cc",
|
||||
"mach/mach_message_server_test.cc",
|
||||
"mach/mach_message_test.cc",
|
||||
"mach/notify_server_test.cc",
|
||||
"mach/scoped_task_suspend_test.cc",
|
||||
"mach/symbolic_constants_mach_test.cc",
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "util/mach/mach_message.h"
|
||||
|
||||
#include <AvailabilityMacros.h>
|
||||
#include <bsm/libbsm.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
@ -24,6 +23,10 @@
|
||||
#include "util/misc/clock.h"
|
||||
#include "util/misc/implicit_cast.h"
|
||||
|
||||
#if !defined(OS_IOS)
|
||||
#include <bsm/libbsm.h>
|
||||
#endif // !OS_IOS
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
namespace {
|
||||
@ -217,38 +220,6 @@ const mach_msg_trailer_t* MachMessageTrailerFromHeader(
|
||||
return reinterpret_cast<const mach_msg_trailer_t*>(trailer_address);
|
||||
}
|
||||
|
||||
pid_t AuditPIDFromMachMessageTrailer(const mach_msg_trailer_t* trailer) {
|
||||
if (trailer->msgh_trailer_type != MACH_MSG_TRAILER_FORMAT_0) {
|
||||
LOG(ERROR) << "unexpected msgh_trailer_type " << trailer->msgh_trailer_type;
|
||||
return -1;
|
||||
}
|
||||
if (trailer->msgh_trailer_size <
|
||||
REQUESTED_TRAILER_SIZE(kMachMessageReceiveAuditTrailer)) {
|
||||
LOG(ERROR) << "small msgh_trailer_size " << trailer->msgh_trailer_size;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const mach_msg_audit_trailer_t* audit_trailer =
|
||||
reinterpret_cast<const mach_msg_audit_trailer_t*>(trailer);
|
||||
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_8
|
||||
pid_t audit_pid;
|
||||
audit_token_to_au32(audit_trailer->msgh_audit,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
&audit_pid,
|
||||
nullptr,
|
||||
nullptr);
|
||||
#else
|
||||
pid_t audit_pid = audit_token_to_pid(audit_trailer->msgh_audit);
|
||||
#endif
|
||||
|
||||
return audit_pid;
|
||||
}
|
||||
|
||||
bool MachMessageDestroyReceivedPort(mach_port_t port,
|
||||
mach_msg_type_name_t port_right_type) {
|
||||
// This implements a subset of 10.10.5
|
||||
@ -282,4 +253,40 @@ bool MachMessageDestroyReceivedPort(mach_port_t port,
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(OS_IOS)
|
||||
|
||||
pid_t AuditPIDFromMachMessageTrailer(const mach_msg_trailer_t* trailer) {
|
||||
if (trailer->msgh_trailer_type != MACH_MSG_TRAILER_FORMAT_0) {
|
||||
LOG(ERROR) << "unexpected msgh_trailer_type " << trailer->msgh_trailer_type;
|
||||
return -1;
|
||||
}
|
||||
if (trailer->msgh_trailer_size <
|
||||
REQUESTED_TRAILER_SIZE(kMachMessageReceiveAuditTrailer)) {
|
||||
LOG(ERROR) << "small msgh_trailer_size " << trailer->msgh_trailer_size;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const mach_msg_audit_trailer_t* audit_trailer =
|
||||
reinterpret_cast<const mach_msg_audit_trailer_t*>(trailer);
|
||||
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_8
|
||||
pid_t audit_pid;
|
||||
audit_token_to_au32(audit_trailer->msgh_audit,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
&audit_pid,
|
||||
nullptr,
|
||||
nullptr);
|
||||
#else
|
||||
pid_t audit_pid = audit_token_to_pid(audit_trailer->msgh_audit);
|
||||
#endif
|
||||
|
||||
return audit_pid;
|
||||
}
|
||||
|
||||
#endif // !OS_IOS
|
||||
|
||||
} // namespace crashpad
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "build/build_config.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
//! \brief A Mach message option specifying that an audit trailer should be
|
||||
@ -166,6 +168,23 @@ void SetMIGReplyError(mach_msg_header_t* out_header, kern_return_t error);
|
||||
const mach_msg_trailer_t* MachMessageTrailerFromHeader(
|
||||
const mach_msg_header_t* header);
|
||||
|
||||
//! \brief Destroys or deallocates a Mach port received in a Mach message.
|
||||
//!
|
||||
//! This function disposes of port rights received in a Mach message. Receive
|
||||
//! rights will be destroyed with `mach_port_mod_refs()`. Send and send-once
|
||||
//! rights will be deallocated with `mach_port_deallocate()`.
|
||||
//!
|
||||
//! \param[in] port The port to destroy or deallocate.
|
||||
//! \param[in] port_right_type The right type held for \a port:
|
||||
//! `MACH_MSG_TYPE_PORT_RECEIVE`, `MACH_MSG_TYPE_PORT_SEND`, or
|
||||
//! `MACH_MSG_TYPE_PORT_SEND_ONCE`.
|
||||
//!
|
||||
//! \return `true` on success, or `false` on failure with a message logged.
|
||||
bool MachMessageDestroyReceivedPort(mach_port_t port,
|
||||
mach_msg_type_name_t port_right_type);
|
||||
|
||||
#if !defined(OS_IOS) || DOXYGEN
|
||||
|
||||
//! \brief Returns the process ID of a Mach message’s sender from its audit
|
||||
//! trailer.
|
||||
//!
|
||||
@ -182,20 +201,7 @@ const mach_msg_trailer_t* MachMessageTrailerFromHeader(
|
||||
//! audit information.
|
||||
pid_t AuditPIDFromMachMessageTrailer(const mach_msg_trailer_t* trailer);
|
||||
|
||||
//! \brief Destroys or deallocates a Mach port received in a Mach message.
|
||||
//!
|
||||
//! This function disposes of port rights received in a Mach message. Receive
|
||||
//! rights will be destroyed with `mach_port_mod_refs()`. Send and send-once
|
||||
//! rights will be deallocated with `mach_port_deallocate()`.
|
||||
//!
|
||||
//! \param[in] port The port to destroy or deallocate.
|
||||
//! \param[in] port_right_type The right type held for \a port:
|
||||
//! `MACH_MSG_TYPE_PORT_RECEIVE`, `MACH_MSG_TYPE_PORT_SEND`, or
|
||||
//! `MACH_MSG_TYPE_PORT_SEND_ONCE`.
|
||||
//!
|
||||
//! \return `true` on success, or `false` on failure with a message logged.
|
||||
bool MachMessageDestroyReceivedPort(mach_port_t port,
|
||||
mach_msg_type_name_t port_right_type);
|
||||
#endif // !OS_IOS
|
||||
|
||||
} // namespace crashpad
|
||||
|
||||
|
@ -109,46 +109,6 @@ TEST(MachMessage, MachMessageTrailerFromHeader) {
|
||||
EXPECT_EQ(MachMessageTrailerFromHeader(&test.receive), &test.receive.trailer);
|
||||
}
|
||||
|
||||
TEST(MachMessage, AuditPIDFromMachMessageTrailer) {
|
||||
base::mac::ScopedMachReceiveRight port(NewMachPort(MACH_PORT_RIGHT_RECEIVE));
|
||||
ASSERT_NE(port, kMachPortNull);
|
||||
|
||||
mach_msg_empty_send_t send = {};
|
||||
send.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND_ONCE, 0);
|
||||
send.header.msgh_size = sizeof(send);
|
||||
send.header.msgh_remote_port = port.get();
|
||||
mach_msg_return_t mr =
|
||||
MachMessageWithDeadline(&send.header,
|
||||
MACH_SEND_MSG,
|
||||
0,
|
||||
MACH_PORT_NULL,
|
||||
kMachMessageDeadlineNonblocking,
|
||||
MACH_PORT_NULL,
|
||||
false);
|
||||
ASSERT_EQ(mr, MACH_MSG_SUCCESS)
|
||||
<< MachErrorMessage(mr, "MachMessageWithDeadline send");
|
||||
|
||||
struct EmptyReceiveMessageWithAuditTrailer : public mach_msg_empty_send_t {
|
||||
union {
|
||||
mach_msg_trailer_t trailer;
|
||||
mach_msg_audit_trailer_t audit_trailer;
|
||||
};
|
||||
};
|
||||
|
||||
EmptyReceiveMessageWithAuditTrailer receive;
|
||||
mr = MachMessageWithDeadline(&receive.header,
|
||||
MACH_RCV_MSG | kMachMessageReceiveAuditTrailer,
|
||||
sizeof(receive),
|
||||
port.get(),
|
||||
kMachMessageDeadlineNonblocking,
|
||||
MACH_PORT_NULL,
|
||||
false);
|
||||
ASSERT_EQ(mr, MACH_MSG_SUCCESS)
|
||||
<< MachErrorMessage(mr, "MachMessageWithDeadline receive");
|
||||
|
||||
EXPECT_EQ(AuditPIDFromMachMessageTrailer(&receive.trailer), getpid());
|
||||
}
|
||||
|
||||
TEST(MachMessage, MachMessageDestroyReceivedPort) {
|
||||
mach_port_t port = NewMachPort(MACH_PORT_RIGHT_RECEIVE);
|
||||
ASSERT_NE(port, kMachPortNull);
|
||||
@ -198,6 +158,50 @@ TEST(MachMessage, MachMessageDestroyReceivedPort) {
|
||||
EXPECT_TRUE(MachMessageDestroyReceivedPort(port, MACH_MSG_TYPE_PORT_SEND));
|
||||
}
|
||||
|
||||
#if !defined(OS_IOS)
|
||||
|
||||
TEST(MachMessage, AuditPIDFromMachMessageTrailer) {
|
||||
base::mac::ScopedMachReceiveRight port(NewMachPort(MACH_PORT_RIGHT_RECEIVE));
|
||||
ASSERT_NE(port, kMachPortNull);
|
||||
|
||||
mach_msg_empty_send_t send = {};
|
||||
send.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND_ONCE, 0);
|
||||
send.header.msgh_size = sizeof(send);
|
||||
send.header.msgh_remote_port = port.get();
|
||||
mach_msg_return_t mr =
|
||||
MachMessageWithDeadline(&send.header,
|
||||
MACH_SEND_MSG,
|
||||
0,
|
||||
MACH_PORT_NULL,
|
||||
kMachMessageDeadlineNonblocking,
|
||||
MACH_PORT_NULL,
|
||||
false);
|
||||
ASSERT_EQ(mr, MACH_MSG_SUCCESS)
|
||||
<< MachErrorMessage(mr, "MachMessageWithDeadline send");
|
||||
|
||||
struct EmptyReceiveMessageWithAuditTrailer : public mach_msg_empty_send_t {
|
||||
union {
|
||||
mach_msg_trailer_t trailer;
|
||||
mach_msg_audit_trailer_t audit_trailer;
|
||||
};
|
||||
};
|
||||
|
||||
EmptyReceiveMessageWithAuditTrailer receive;
|
||||
mr = MachMessageWithDeadline(&receive.header,
|
||||
MACH_RCV_MSG | kMachMessageReceiveAuditTrailer,
|
||||
sizeof(receive),
|
||||
port.get(),
|
||||
kMachMessageDeadlineNonblocking,
|
||||
MACH_PORT_NULL,
|
||||
false);
|
||||
ASSERT_EQ(mr, MACH_MSG_SUCCESS)
|
||||
<< MachErrorMessage(mr, "MachMessageWithDeadline receive");
|
||||
|
||||
EXPECT_EQ(AuditPIDFromMachMessageTrailer(&receive.trailer), getpid());
|
||||
}
|
||||
|
||||
#endif // !OS_IOS
|
||||
|
||||
} // namespace
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
||||
|
Loading…
x
Reference in New Issue
Block a user