mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-17 16:43:53 +00:00
linux: verify whether a broker has been successfully forked
Also fix an error in checking that PtraceClient was initialized. Bug: crashpad:30 Change-Id: I1928340a2a642c2d831f0152bb9faaa12afb07e8 Reviewed-on: https://chromium-review.googlesource.com/978630 Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
parent
9c89cd99f3
commit
6b23575b34
@ -63,7 +63,7 @@ bool CrashReportExceptionHandler::HandleExceptionWithBroker(
|
|||||||
Metrics::ExceptionEncountered();
|
Metrics::ExceptionEncountered();
|
||||||
|
|
||||||
PtraceClient client;
|
PtraceClient client;
|
||||||
if (client.Initialize(broker_sock, client_process_id)) {
|
if (!client.Initialize(broker_sock, client_process_id)) {
|
||||||
Metrics::ExceptionCaptureResult(
|
Metrics::ExceptionCaptureResult(
|
||||||
Metrics::CaptureResult::kBrokeredPtraceFailed);
|
Metrics::CaptureResult::kBrokeredPtraceFailed);
|
||||||
return false;
|
return false;
|
||||||
|
@ -126,8 +126,10 @@ class PtraceStrategyDeciderImpl : public PtraceStrategyDecider {
|
|||||||
Strategy ChooseStrategy(int sock, const ucred& client_credentials) override {
|
Strategy ChooseStrategy(int sock, const ucred& client_credentials) override {
|
||||||
switch (GetPtraceScope()) {
|
switch (GetPtraceScope()) {
|
||||||
case PtraceScope::kClassic:
|
case PtraceScope::kClassic:
|
||||||
return getuid() == client_credentials.uid ? Strategy::kDirectPtrace
|
if (getuid() == client_credentials.uid) {
|
||||||
: Strategy::kForkBroker;
|
return Strategy::kDirectPtrace;
|
||||||
|
}
|
||||||
|
return TryForkingBroker(sock);
|
||||||
|
|
||||||
case PtraceScope::kRestricted:
|
case PtraceScope::kRestricted:
|
||||||
if (!SendMessageToClient(sock,
|
if (!SendMessageToClient(sock,
|
||||||
@ -143,7 +145,7 @@ class PtraceStrategyDeciderImpl : public PtraceStrategyDecider {
|
|||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
errno = status;
|
errno = status;
|
||||||
PLOG(ERROR) << "Handler Client SetPtracer";
|
PLOG(ERROR) << "Handler Client SetPtracer";
|
||||||
return Strategy::kForkBroker;
|
return TryForkingBroker(sock);
|
||||||
}
|
}
|
||||||
return Strategy::kDirectPtrace;
|
return Strategy::kDirectPtrace;
|
||||||
|
|
||||||
@ -163,6 +165,26 @@ class PtraceStrategyDeciderImpl : public PtraceStrategyDecider {
|
|||||||
|
|
||||||
DCHECK(false);
|
DCHECK(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Strategy TryForkingBroker(int client_sock) {
|
||||||
|
if (!SendMessageToClient(client_sock,
|
||||||
|
ServerToClientMessage::kTypeForkBroker)) {
|
||||||
|
return Strategy::kError;
|
||||||
|
}
|
||||||
|
|
||||||
|
Errno status;
|
||||||
|
if (!LoggingReadFileExactly(client_sock, &status, sizeof(status))) {
|
||||||
|
return Strategy::kError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != 0) {
|
||||||
|
errno = status;
|
||||||
|
PLOG(ERROR) << "Handler Client ForkBroker";
|
||||||
|
return Strategy::kNoPtrace;
|
||||||
|
}
|
||||||
|
return Strategy::kUseBroker;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -427,12 +449,7 @@ bool ExceptionHandlerServer::HandleCrashDumpRequest(
|
|||||||
client_info.exception_information_address);
|
client_info.exception_information_address);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PtraceStrategyDecider::Strategy::kForkBroker:
|
case PtraceStrategyDecider::Strategy::kUseBroker:
|
||||||
if (!SendMessageToClient(client_sock,
|
|
||||||
ServerToClientMessage::kTypeForkBroker)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
delegate_->HandleExceptionWithBroker(
|
delegate_->HandleExceptionWithBroker(
|
||||||
client_process_id,
|
client_process_id,
|
||||||
client_info.exception_information_address,
|
client_info.exception_information_address,
|
||||||
|
@ -46,8 +46,8 @@ class PtraceStrategyDecider {
|
|||||||
//! \brief The handler should `ptrace`-attach the client directly.
|
//! \brief The handler should `ptrace`-attach the client directly.
|
||||||
kDirectPtrace,
|
kDirectPtrace,
|
||||||
|
|
||||||
//! \brief The client should `fork` a PtraceBroker for the handler.
|
//! \brief The client has `fork`ed a PtraceBroker for the handler.
|
||||||
kForkBroker,
|
kUseBroker,
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief Chooses an appropriate `ptrace` strategy.
|
//! \brief Chooses an appropriate `ptrace` strategy.
|
||||||
|
@ -289,7 +289,7 @@ TEST_F(ExceptionHandlerServerTest, RequestCrashDumpNoPtrace) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ExceptionHandlerServerTest, RequestCrashDumpForkBroker) {
|
TEST_F(ExceptionHandlerServerTest, RequestCrashDumpForkBroker) {
|
||||||
ExpectCrashDumpUsingStrategy(PtraceStrategyDecider::Strategy::kForkBroker,
|
ExpectCrashDumpUsingStrategy(PtraceStrategyDecider::Strategy::kUseBroker,
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,11 +112,14 @@ int ExceptionHandlerClient::WaitForCrashDumpComplete() {
|
|||||||
Signals::InstallDefaultHandler(SIGCHLD);
|
Signals::InstallDefaultHandler(SIGCHLD);
|
||||||
|
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
if (pid < 0) {
|
if (pid <= 0) {
|
||||||
Errno error = errno;
|
Errno error = pid < 0 ? errno : 0;
|
||||||
if (!WriteFile(server_sock_, &error, sizeof(error))) {
|
if (!WriteFile(server_sock_, &error, sizeof(error))) {
|
||||||
return errno;
|
return errno;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid < 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user