linux: extend handler protocol with credential messages

This message type allows the browser to determine the handler's process
ID to be used with `prctl(PR_SET_PTRACER, ...)`.

Bug: crashpad:284
Change-Id: I2664f3e8aee269b159de9074e389397346c808f0
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/1577704
Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
Joshua Peraza 2019-05-01 18:55:58 -07:00
parent a11243e8f1
commit e23286dc37
5 changed files with 60 additions and 9 deletions

View File

@ -147,6 +147,14 @@ void SendSIGCONT(pid_t pid, pid_t tid) {
}
}
bool SendCredentials(int client_sock) {
ExceptionHandlerProtocol::ServerToClientMessage message = {};
message.type =
ExceptionHandlerProtocol::ServerToClientMessage::kTypeCredentials;
return UnixCredentialSocket::SendMsg(
client_sock, &message, sizeof(message)) == 0;
}
class PtraceStrategyDeciderImpl : public PtraceStrategyDecider {
public:
PtraceStrategyDeciderImpl() : PtraceStrategyDecider() {}
@ -415,7 +423,10 @@ bool ExceptionHandlerServer::ReceiveClientMessage(Event* event) {
}
switch (message.type) {
case ExceptionHandlerProtocol::ClientToServerMessage::kCrashDumpRequest:
case ExceptionHandlerProtocol::ClientToServerMessage::kTypeCheckCredentials:
return SendCredentials(event->fd.get());
case ExceptionHandlerProtocol::ClientToServerMessage::kTypeCrashDumpRequest:
return HandleCrashDumpRequest(
creds,
message.client_info,

View File

@ -68,6 +68,20 @@ ExceptionHandlerClient::ExceptionHandlerClient(int sock, bool multiple_clients)
ExceptionHandlerClient::~ExceptionHandlerClient() = default;
bool ExceptionHandlerClient::GetHandlerCredentials(ucred* creds) {
ExceptionHandlerProtocol::ClientToServerMessage message = {};
message.type =
ExceptionHandlerProtocol::ClientToServerMessage::kTypeCheckCredentials;
if (UnixCredentialSocket::SendMsg(server_sock_, &message, sizeof(message)) !=
0) {
return false;
}
ExceptionHandlerProtocol::ServerToClientMessage response;
return UnixCredentialSocket::RecvMsg(
server_sock_, &response, sizeof(response), creds);
}
int ExceptionHandlerClient::RequestCrashDump(
const ExceptionHandlerProtocol::ClientInformation& info) {
VMAddress sp = FromPointerCast<VMAddress>(&sp);
@ -139,7 +153,7 @@ int ExceptionHandlerClient::SendCrashDumpRequest(
VMAddress stack_pointer) {
ExceptionHandlerProtocol::ClientToServerMessage message;
message.type =
ExceptionHandlerProtocol::ClientToServerMessage::kCrashDumpRequest;
ExceptionHandlerProtocol::ClientToServerMessage::kTypeCrashDumpRequest;
message.requesting_thread_stack_address = stack_pointer;
message.client_info = info;
return UnixCredentialSocket::SendMsg(server_sock_, &message, sizeof(message));
@ -197,6 +211,10 @@ int ExceptionHandlerClient::WaitForCrashDumpComplete() {
continue;
}
case ExceptionHandlerProtocol::ServerToClientMessage::kTypeCredentials:
DCHECK(false);
continue;
case ExceptionHandlerProtocol::ServerToClientMessage::
kTypeCrashDumpComplete:
case ExceptionHandlerProtocol::ServerToClientMessage::

View File

@ -15,6 +15,7 @@
#ifndef CRASHPAD_UTIL_LINUX_EXCEPTION_HANDLER_CLIENT_H_
#define CRASHPAD_UTIL_LINUX_EXCEPTION_HANDLER_CLIENT_H_
#include <sys/socket.h>
#include <sys/types.h>
#include "base/macros.h"
@ -34,6 +35,17 @@ class ExceptionHandlerClient {
~ExceptionHandlerClient();
//! \brief Communicates with the handler to determine its credentials.
//!
//! If using a multi-client socket, this method should be called before
//! sharing the client socket end, or the handler's response may not be
//! received.
//!
//! \param[out] creds The handler process' credentials, valid if this method
//! returns `true`.
//! \return `true` on success. Otherwise, `false` with a message logged.
bool GetHandlerCredentials(ucred* creds);
//! \brief Request a crash dump from the ExceptionHandlerServer.
//!
//! This method blocks until the crash dump is complete.

View File

@ -20,6 +20,6 @@ ExceptionHandlerProtocol::ClientInformation::ClientInformation()
: exception_information_address(0), sanitization_information_address(0) {}
ExceptionHandlerProtocol::ClientToServerMessage::ClientToServerMessage()
: version(kVersion), type(kCrashDumpRequest), client_info() {}
: version(kVersion), type(kTypeCrashDumpRequest), client_info() {}
} // namespace crashpad

View File

@ -69,14 +69,19 @@ class ExceptionHandlerProtocol {
//! \brief Indicates what message version is being used.
int32_t version;
enum Type : uint32_t {
//! \brief Request that the server respond with its credentials.
kTypeCheckCredentials,
//! \brief Used to request a crash dump for the sending client.
kTypeCrashDumpRequest
};
Type type;
//! \brief A stack address of the thread sending the message.
VMAddress requesting_thread_stack_address;
enum Type : uint32_t {
//! \brief Used to request a crash dump for the sending client.
kCrashDumpRequest
} type;
union {
//! \brief Valid for type == kCrashDumpRequest
ClientInformation client_info;
@ -86,6 +91,9 @@ class ExceptionHandlerProtocol {
//! \brief The message passed from server to client.
struct ServerToClientMessage {
enum Type : uint32_t {
//! \brief Used to pass credentials with `SCM_CREDENTIALS`.
kTypeCredentials,
//! \brief Indicates that the client should fork a PtraceBroker process.
kTypeForkBroker,
@ -100,7 +108,9 @@ class ExceptionHandlerProtocol {
//! \brief Indicicates that the handler was unable to produce a crash
//! dump.
kTypeCrashDumpFailed
} type;
};
Type type;
//! \brief The handler's process ID. Valid for kTypeSetPtracer.
pid_t pid;