mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-27 15:32:10 +08: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();
|
||||
|
||||
PtraceClient client;
|
||||
if (client.Initialize(broker_sock, client_process_id)) {
|
||||
if (!client.Initialize(broker_sock, client_process_id)) {
|
||||
Metrics::ExceptionCaptureResult(
|
||||
Metrics::CaptureResult::kBrokeredPtraceFailed);
|
||||
return false;
|
||||
|
@ -126,8 +126,10 @@ class PtraceStrategyDeciderImpl : public PtraceStrategyDecider {
|
||||
Strategy ChooseStrategy(int sock, const ucred& client_credentials) override {
|
||||
switch (GetPtraceScope()) {
|
||||
case PtraceScope::kClassic:
|
||||
return getuid() == client_credentials.uid ? Strategy::kDirectPtrace
|
||||
: Strategy::kForkBroker;
|
||||
if (getuid() == client_credentials.uid) {
|
||||
return Strategy::kDirectPtrace;
|
||||
}
|
||||
return TryForkingBroker(sock);
|
||||
|
||||
case PtraceScope::kRestricted:
|
||||
if (!SendMessageToClient(sock,
|
||||
@ -143,7 +145,7 @@ class PtraceStrategyDeciderImpl : public PtraceStrategyDecider {
|
||||
if (status != 0) {
|
||||
errno = status;
|
||||
PLOG(ERROR) << "Handler Client SetPtracer";
|
||||
return Strategy::kForkBroker;
|
||||
return TryForkingBroker(sock);
|
||||
}
|
||||
return Strategy::kDirectPtrace;
|
||||
|
||||
@ -163,6 +165,26 @@ class PtraceStrategyDeciderImpl : public PtraceStrategyDecider {
|
||||
|
||||
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
|
||||
@ -427,12 +449,7 @@ bool ExceptionHandlerServer::HandleCrashDumpRequest(
|
||||
client_info.exception_information_address);
|
||||
break;
|
||||
|
||||
case PtraceStrategyDecider::Strategy::kForkBroker:
|
||||
if (!SendMessageToClient(client_sock,
|
||||
ServerToClientMessage::kTypeForkBroker)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
case PtraceStrategyDecider::Strategy::kUseBroker:
|
||||
delegate_->HandleExceptionWithBroker(
|
||||
client_process_id,
|
||||
client_info.exception_information_address,
|
||||
|
@ -46,8 +46,8 @@ class PtraceStrategyDecider {
|
||||
//! \brief The handler should `ptrace`-attach the client directly.
|
||||
kDirectPtrace,
|
||||
|
||||
//! \brief The client should `fork` a PtraceBroker for the handler.
|
||||
kForkBroker,
|
||||
//! \brief The client has `fork`ed a PtraceBroker for the handler.
|
||||
kUseBroker,
|
||||
};
|
||||
|
||||
//! \brief Chooses an appropriate `ptrace` strategy.
|
||||
|
@ -289,7 +289,7 @@ TEST_F(ExceptionHandlerServerTest, RequestCrashDumpNoPtrace) {
|
||||
}
|
||||
|
||||
TEST_F(ExceptionHandlerServerTest, RequestCrashDumpForkBroker) {
|
||||
ExpectCrashDumpUsingStrategy(PtraceStrategyDecider::Strategy::kForkBroker,
|
||||
ExpectCrashDumpUsingStrategy(PtraceStrategyDecider::Strategy::kUseBroker,
|
||||
true);
|
||||
}
|
||||
|
||||
|
@ -112,11 +112,14 @@ int ExceptionHandlerClient::WaitForCrashDumpComplete() {
|
||||
Signals::InstallDefaultHandler(SIGCHLD);
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid < 0) {
|
||||
Errno error = errno;
|
||||
if (pid <= 0) {
|
||||
Errno error = pid < 0 ? errno : 0;
|
||||
if (!WriteFile(server_sock_, &error, sizeof(error))) {
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
|
||||
if (pid < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user