The implementations for the exc and mach_exc subsystems were nearly
identical, and were a good target for templatization. The existing
split between exc and mach_exc was a good candidate for unification
based on CompositeMachMessageServer instead of the custom unification
previously done in UniversalMachMessageServer.
TEST=util_test ExcServerVariants.*
R=rsesek@chromium.org
Review URL: https://codereview.chromium.org/766193006
MachMessageServer::Run()’s distinct |nonblocking| parameter is removed.
The information it formerly conveyed is now implied by the |timeout_ms|
parameter, which can accept two special values,
kMachMessageTimeoutNonblocking and kMachMessageTimeoutWaitIndefinitely.
TEST=client_test, snapshot_test, util_test
R=rsesek@chromium.org
Review URL: https://codereview.chromium.org/777993002
Option names like --mach-service are easier to type than --mach_service.
Command-line tools don’t necessarily have the most ergonomic interfaces
anyway, but this is an improvement.
R=rsesek@chromium.org
Review URL: https://codereview.chromium.org/774763006
UniversalMachExcServer provided both an interface and an implementation,
contrary to the other classes in the exc_server_variants family. This
was mostly done for reasons of economy in an already-large class family.
Unfortunately, this decision meant that it was impossible for other code
to use UniversalMachExcServer, which required that CatchMachException()
be implemented, and also extend another class without violating the
style guide’s prohibition of multiple implementation inheritance. This
became a problem in a lot of test code, which extended MachMultiprocess
and UniversalMachExcServer.
UniversalMachExcServer is now given its own nested Interface class,
which is a pure interface. All users of UniversalMachExcServer are
changed from “is-a” UniversalMachExcServer to “has-a”
UniversalMachExcServer and “is-a” UniversalMachExcServer::Interface.
TEST=client_test, snapshot_test, util_test
R=rsesek@chromium.org
Review URL: https://codereview.chromium.org/775943005
This exposed a bug in the ExcClientVariants test, which was expecting
the memory used for new_state to be initialized with zeroes. In reality,
no guarantee of initialization is made. MIG “out” parameters are
strictly “out” and may contain garbage at function entry.
TEST=util_test
R=rsesek@chromium.org
Review URL: https://codereview.chromium.org/779633004
The F_SETNOSIGPIPE fcntl() command is not available on 10.6. Use
socketpair() instead of pipe(), so that the SO_NOSIGPIPE socket option
can be used.
TEST=util_test ChildPortHandshake.*
R=rsesek@chromium.org
Review URL: https://codereview.chromium.org/777573002
MachMessageWithDeadline() is a mach_msg() wrapper that deals with
deadlines instead of timeouts. It is a slight simplification of the
mach_msg() interface because the deadline parameter implies the timeout
option bits, and because the caller does not need to specify send_size
during sends as the message itself already carries this information.
TEST=util_test MachMessage.MachMessageDeadlineFromTimeout
R=rsesek@chromium.org
Review URL: https://codereview.chromium.org/773943002
A subsequent change will add MachMessageWithDeadline(), a mach_msg()
wrapper. Conceptually, it makes sense to include that function in this
file family. Since this file family now contains a mach_msg() wrapper,
it makes sense to rename it mach_message and lose the _util suffix.
R=rsesek@chromium.org
Review URL: https://codereview.chromium.org/772133004
MachMessageServer was wasteful with allocations for request and reply
messages. It allocated new memory for each request receive and for each
reply send, and if it needed to resize an allocation for a request, it
would maintain two request allocations simultaneously. The new behavior
allocates memory for a new request only if it needs a different size
than for the previous request, and it never maintains two request
allocations simultaneously. Memory for a reply is allocated once per
method invocation and maintained, since this never needs to be resized.
One pass of the loop is now guaranteed, even if a caller specifies a
very small timeout that expires before attempting to receive a message.
An infinite looping bug that could occur when ignoring large messages
has also been fixed.
TEST=util_test MachMessageServer.*
R=rsesek@chromium.org
Review URL: https://codereview.chromium.org/759023004
The buffer sizing logic was correct to start with. I don’t know why I
misread it. It should say “if this would resize to receive a large
message, use the entire allocation rounded up to full page size,
otherwise, only use the space expected for a message.”
TEST=util_test
R=rsesek@chromium.org
Review URL: https://codereview.chromium.org/760573003
These port dispositions were naïvely taken from excUser.c and
mach_excUser.c, but the local and remote portions were not swapped as
they would be upon receipt in a server. This swaps them to match how
they’d be visible in a server, and uses the port disposition name
aliases expected to be used in servers: MACH_MSG_TYPE_PORT_* instead of
MACH_MSG_TYPE_{MAKE,COPY,MOVE}_*.
TEST=util_test ExcServerVariants.*
R=rsesek@chromium.org
Review URL: https://codereview.chromium.org/755323002
The existing implementation used the same logic as is found in
mach_msg_server(), but that logic seems incorrect. When the caller wants
to retry a mach_msg() receive of a too-large message that returns
MACH_RCV_TOO_LARGE, there’s no harm in attempting the receive with a
larger buffer initially. On the other hand, if the caller does not want
to retry such mach_msg() receive attempts, it’s an indication that the
caller is expecting to be intolerant of too-large messages, and there’s
no need to attempt the receive with a buffer any larger than requested.
TEST=util_test
R=rsesek@chromium.org
Review URL: https://codereview.chromium.org/753363003
As documented, MACH_SEND_TRAILER would allow a sender to provide its own
message trailer instead of having the kernel append its own
kernel-generated trailer. This is a Mach feature that supports a network
of multiple Mach hosts, but even in that environment, the option is
restricted to use by privileged callers. In reality, MACH_SEND_TRAILER
has never been implemented in OS X.
The system’s mach_msg_server() family does consider the value of
MACH_SEND_TRAILER, but this is pointless. Any purported trailer set by a
server function would be ignored.
Maintaining this code gives the illusion that it’s functional, so it’s
being removed.
TEST=util_test MachMessageServer.*
R=rsesek@chromium.org
Review URL: https://codereview.chromium.org/736493007
ChildPortHandshake is the most generic system yet to allow child
processes to provide their parents with Mach rights. These are
ordinarily expected to be send rights to the children’s own task ports,
or send rights to servers that the children hold receive rights to.
This updates DEPS to pull mini_chromium 1d3523dbda93, which includes
base::mac::ScopedMachPortSet.
TEST=util_test ChildPortHandshake.*
R=rsesek@chromium.org
Review URL: https://codereview.chromium.org/756603003
Previously, MachMessageServer::Run() only provided two strategies for
dealing with large messages, indicated by mach_msg() returning
MACH_RCV_TOO_LARGE: the receive buffer could be reallocated and the
message received, or the entire function could return MACH_RCV_TOO_LARGE
to the caller. There are situations where an intermediate behavior might
be desirable. This intermediate behavior would allow the function to
continue waiting for another message without returning an error to the
caller or attempting to receive the large message. This is desirable
when dealing with fixed-sized messages and a receiver that might be sent
messages by unknown, possibly-malicious callers. This can happen when
the corresponding send right is published with the bootstrap server, for
example.
Existing users continue to request their existing behavior, typically
receiving an error when encountering a large message.
catch_exception_tool will use the new “ignore” behavior when running in
persistent mode.
TEST=util_test MachMessageServer.*
R=rsesek@chromium.org
Review URL: https://codereview.chromium.org/756803002
the child_port subsystem.
Common routines shared with the ExcServer family of classes have been
moved to a new file, where they can be shared between different
MachMessageServer::Interface implementations.
TEST=util_test ChildPortServer.*:MachMessageUtil.*
R=rsesek@chromium.org
Review URL: https://codereview.chromium.org/754123002
In b6a0183ccec7, gtest and gmock were held back at older versions with
limited C++11 support, because the then-current heads of each did not
work well in environments with C++11 language support but pre-C++11
library support. This is the environment that Chrome code for Mac builds
in. All necessary patches for this have been merged upstream, and this
has been corrected in the current released versions of gtest and gmock.
TEST=*
R=rsesek@chromium.org
Review URL: https://codereview.chromium.org/731473007
DropPrivileges() is used in exception_port_tool, so that when it is
installed as a setuid executable, it only uses elevated privileges to
obtain a task port for its -p option, and then relinquishes those
privileges.
It is difficult to provide a test for this function, because it must be
running setuid or setgid in order to do anything interesting. However,
the function contains its own CHECKs to verify that it behaves properly.
R=rsesek@chromium.org
Review URL: https://codereview.chromium.org/727053002
This also transitions exception_port_tool to use TaskForPID(), so that
it can be safely used as a setuid executable without giving permission
to operate on any process on the system.
It is difficult to provide a test for this function, because it must be
running setuid root in order to do anything interesting.
R=rsesek@chromium.org
Review URL: https://codereview.chromium.org/728973002
Also, move ProcessArgumentsForPID() into ProcessInfo.
This change prepares for a TaskForPID() implementation that’s capable of
operating correctly in a setuid root executable. TaskForPID() belongs in
util/mach, but for its permission checks, it must access some process
properties that were previously fetched by ProcessReader in snapshot.
util can’t depend on snapshot. The generic util-safe process information
bits (Is64Bit(), ProcessID(), ParentProcessID(), and StartTime()) are
moved from ProcessReader to ProcessInfo (in util), where the current
ProcessReader can use it (as it’s OK for snapshot to depend on util),
and the future TaskForPID() in util can also use it. ProcessInfo also
contains other methods that TaskForPID() will use, providing access to
the credentials that the target process holds. ProcessArgumentsForPID()
is related, and is also now a part of ProcessInfo.
TEST=snapshot_test, util_test
R=rsesek@chromium.org
Review URL: https://codereview.chromium.org/727973002
MinidumpLocationDescriptorListWriter and MinidumpRVAListWriter are
implementation details and should be in the crashpad::internal
namespace.
MinidumpUTF16StringListWriter and MinidumpUTF8StringListWriter are
accessible to outside code and should not be in this namespace.
TEST=minidump_test
R=rsesek@chromium.org
Review URL: https://codereview.chromium.org/699313007
This will be used as the foundation for writing a list of
MinidumpUTF8String objects. MinidumpUTF8String (and UTF-16
MINIDUMP_STRING) objects are never referenced by
MINIDUMP_LOCATION_DESCRIPTOR because they carry their own lengths.
Instead, they are always referenced by RVA.
The list of MinidumpUTF8String objects will be used for the module
annotations vector.
TEST=minidump_test MinidumpRVAListWriter.*
R=rsesek@chromium.org
Review URL: https://codereview.chromium.org/704333002