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 += [
|
sources += [
|
||||||
"mac/xattr.cc",
|
"mac/xattr.cc",
|
||||||
"mac/xattr.h",
|
"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.cc",
|
||||||
"mach/mach_extensions.h",
|
"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/clock_mac.cc",
|
||||||
"misc/paths_mac.cc",
|
"misc/paths_mac.cc",
|
||||||
"synchronization/semaphore_mac.cc",
|
"synchronization/semaphore_mac.cc",
|
||||||
@ -284,16 +292,8 @@ static_library("util") {
|
|||||||
"mach/exc_client_variants.h",
|
"mach/exc_client_variants.h",
|
||||||
"mach/exc_server_variants.cc",
|
"mach/exc_server_variants.cc",
|
||||||
"mach/exc_server_variants.h",
|
"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.cc",
|
||||||
"mach/exception_types.h",
|
"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.cc",
|
||||||
"mach/notify_server.h",
|
"mach/notify_server.h",
|
||||||
"mach/scoped_task_suspend.cc",
|
"mach/scoped_task_suspend.cc",
|
||||||
@ -518,9 +518,7 @@ static_library("util") {
|
|||||||
|
|
||||||
if (crashpad_is_mac || crashpad_is_ios) {
|
if (crashpad_is_mac || crashpad_is_ios) {
|
||||||
include_dirs += [ "$root_build_dir/gen" ]
|
include_dirs += [ "$root_build_dir/gen" ]
|
||||||
deps += [
|
deps += [ ":mig_output" ]
|
||||||
":mig_output",
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (crashpad_is_mac) {
|
if (crashpad_is_mac) {
|
||||||
@ -530,9 +528,7 @@ static_library("util") {
|
|||||||
"Foundation.framework",
|
"Foundation.framework",
|
||||||
"IOKit.framework",
|
"IOKit.framework",
|
||||||
]
|
]
|
||||||
deps += [
|
deps += [ "../third_party/apple_cf:apple_cf" ]
|
||||||
"../third_party/apple_cf:apple_cf",
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (crashpad_is_win) {
|
if (crashpad_is_win) {
|
||||||
@ -674,7 +670,9 @@ source_set("util_test") {
|
|||||||
if (crashpad_is_mac || crashpad_is_ios) {
|
if (crashpad_is_mac || crashpad_is_ios) {
|
||||||
sources += [
|
sources += [
|
||||||
"mac/xattr_test.cc",
|
"mac/xattr_test.cc",
|
||||||
|
"mach/exception_behaviors_test.cc",
|
||||||
"mach/mach_extensions_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/composite_mach_message_server_test.cc",
|
||||||
"mach/exc_client_variants_test.cc",
|
"mach/exc_client_variants_test.cc",
|
||||||
"mach/exc_server_variants_test.cc",
|
"mach/exc_server_variants_test.cc",
|
||||||
"mach/exception_behaviors_test.cc",
|
|
||||||
"mach/exception_ports_test.cc",
|
"mach/exception_ports_test.cc",
|
||||||
"mach/exception_types_test.cc",
|
"mach/exception_types_test.cc",
|
||||||
"mach/mach_message_server_test.cc",
|
"mach/mach_message_server_test.cc",
|
||||||
"mach/mach_message_test.cc",
|
|
||||||
"mach/notify_server_test.cc",
|
"mach/notify_server_test.cc",
|
||||||
"mach/scoped_task_suspend_test.cc",
|
"mach/scoped_task_suspend_test.cc",
|
||||||
"mach/symbolic_constants_mach_test.cc",
|
"mach/symbolic_constants_mach_test.cc",
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
#include "util/mach/mach_message.h"
|
#include "util/mach/mach_message.h"
|
||||||
|
|
||||||
#include <AvailabilityMacros.h>
|
#include <AvailabilityMacros.h>
|
||||||
#include <bsm/libbsm.h>
|
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
@ -24,6 +23,10 @@
|
|||||||
#include "util/misc/clock.h"
|
#include "util/misc/clock.h"
|
||||||
#include "util/misc/implicit_cast.h"
|
#include "util/misc/implicit_cast.h"
|
||||||
|
|
||||||
|
#if !defined(OS_IOS)
|
||||||
|
#include <bsm/libbsm.h>
|
||||||
|
#endif // !OS_IOS
|
||||||
|
|
||||||
namespace crashpad {
|
namespace crashpad {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -217,38 +220,6 @@ const mach_msg_trailer_t* MachMessageTrailerFromHeader(
|
|||||||
return reinterpret_cast<const mach_msg_trailer_t*>(trailer_address);
|
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,
|
bool MachMessageDestroyReceivedPort(mach_port_t port,
|
||||||
mach_msg_type_name_t port_right_type) {
|
mach_msg_type_name_t port_right_type) {
|
||||||
// This implements a subset of 10.10.5
|
// 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
|
} // namespace crashpad
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "build/build_config.h"
|
||||||
|
|
||||||
namespace crashpad {
|
namespace crashpad {
|
||||||
|
|
||||||
//! \brief A Mach message option specifying that an audit trailer should be
|
//! \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_trailer_t* MachMessageTrailerFromHeader(
|
||||||
const mach_msg_header_t* header);
|
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
|
//! \brief Returns the process ID of a Mach message’s sender from its audit
|
||||||
//! trailer.
|
//! trailer.
|
||||||
//!
|
//!
|
||||||
@ -182,20 +201,7 @@ const mach_msg_trailer_t* MachMessageTrailerFromHeader(
|
|||||||
//! audit information.
|
//! audit information.
|
||||||
pid_t AuditPIDFromMachMessageTrailer(const mach_msg_trailer_t* trailer);
|
pid_t AuditPIDFromMachMessageTrailer(const mach_msg_trailer_t* trailer);
|
||||||
|
|
||||||
//! \brief Destroys or deallocates a Mach port received in a Mach message.
|
#endif // !OS_IOS
|
||||||
//!
|
|
||||||
//! 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);
|
|
||||||
|
|
||||||
} // namespace crashpad
|
} // namespace crashpad
|
||||||
|
|
||||||
|
@ -109,46 +109,6 @@ TEST(MachMessage, MachMessageTrailerFromHeader) {
|
|||||||
EXPECT_EQ(MachMessageTrailerFromHeader(&test.receive), &test.receive.trailer);
|
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) {
|
TEST(MachMessage, MachMessageDestroyReceivedPort) {
|
||||||
mach_port_t port = NewMachPort(MACH_PORT_RIGHT_RECEIVE);
|
mach_port_t port = NewMachPort(MACH_PORT_RIGHT_RECEIVE);
|
||||||
ASSERT_NE(port, kMachPortNull);
|
ASSERT_NE(port, kMachPortNull);
|
||||||
@ -198,6 +158,50 @@ TEST(MachMessage, MachMessageDestroyReceivedPort) {
|
|||||||
EXPECT_TRUE(MachMessageDestroyReceivedPort(port, MACH_MSG_TYPE_PORT_SEND));
|
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
|
||||||
} // namespace test
|
} // namespace test
|
||||||
} // namespace crashpad
|
} // namespace crashpad
|
||||||
|
Loading…
x
Reference in New Issue
Block a user