Commit 7030d91a authored by Joshua Peraza's avatar Joshua Peraza Committed by Commit Bot

Update Crashpad to 74490f00a47bbe38b08354eb9286f616285e8d22

0208c1a175e1 fuchsia: Don't capture incorrect/unreasonably large stacks
2291bfa32ef1 android, gyp: fix the build
74490f00a47b linux: roll lss and use sys_sigtimedwait/sys_sigprocmask

Change-Id: I220c774c372f59303e62f1da5a1946549ce47cb8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1914901
Commit-Queue: Mark Mentovai <mark@chromium.org>
Auto-Submit: Joshua Peraza <jperaza@chromium.org>
Reviewed-by: default avatarMark Mentovai <mark@chromium.org>
Cr-Commit-Position: refs/heads/master@{#715384}
parent 8045afd1
...@@ -2,7 +2,7 @@ Name: Crashpad ...@@ -2,7 +2,7 @@ Name: Crashpad
Short Name: crashpad Short Name: crashpad
URL: https://crashpad.chromium.org/ URL: https://crashpad.chromium.org/
Version: unknown Version: unknown
Revision: a8d66ae7839a59d104b35ec6eb31f95cddd1813c Revision: 74490f00a47bbe38b08354eb9286f616285e8d22
License: Apache 2.0 License: Apache 2.0
License File: crashpad/LICENSE License File: crashpad/LICENSE
Security Critical: yes Security Critical: yes
......
...@@ -30,7 +30,7 @@ deps = { ...@@ -30,7 +30,7 @@ deps = {
'8bee09f4a57807136593ddc906b0b213c21f9014', '8bee09f4a57807136593ddc906b0b213c21f9014',
'crashpad/third_party/lss/lss': 'crashpad/third_party/lss/lss':
Var('chromium_git') + '/linux-syscall-support.git@' + Var('chromium_git') + '/linux-syscall-support.git@' +
'8048ece6c16c91acfe0d36d1d3cc0890ab6e945c', '726d71ec08d15493b94eff456bc31faecf0a5902',
'crashpad/third_party/mini_chromium/mini_chromium': 'crashpad/third_party/mini_chromium/mini_chromium':
Var('chromium_git') + '/chromium/mini_chromium@' + Var('chromium_git') + '/chromium/mini_chromium@' +
'cdab1e6263ec7f3f61763efc1dac863f8dc07c80', 'cdab1e6263ec7f3f61763efc1dac863f8dc07c80',
......
...@@ -367,16 +367,7 @@ TEST_P(ExceptionHandlerServerTest, RequestCrashDumpError) { ...@@ -367,16 +367,7 @@ TEST_P(ExceptionHandlerServerTest, RequestCrashDumpError) {
INSTANTIATE_TEST_SUITE_P(ExceptionHandlerServerTestSuite, INSTANTIATE_TEST_SUITE_P(ExceptionHandlerServerTestSuite,
ExceptionHandlerServerTest, ExceptionHandlerServerTest,
#if defined(OS_ANDROID) && __ANDROID_API__ < 23
// TODO(jperaza): Using a multi-client socket is not
// supported on Android until an lss sigtimedwait()
// wrapper is available to use in
// ExceptionHandlerClient::SignalCrashDump().
// https://crbug.com/crashpad/265
testing::Values(false)
#else
testing::Bool() testing::Bool()
#endif
); );
} // namespace } // namespace
......
...@@ -53,7 +53,9 @@ void GetStackRegions( ...@@ -53,7 +53,9 @@ void GetStackRegions(
} }
if (range_with_sp.type != ZX_INFO_MAPS_TYPE_MAPPING) { if (range_with_sp.type != ZX_INFO_MAPS_TYPE_MAPPING) {
LOG(ERROR) << "stack range has unexpected type, continuing anyway"; LOG(ERROR) << "stack range has unexpected type " << range_with_sp.type
<< ", aborting";
return;
} }
if (range_with_sp.u.mapping.mmu_flags & ZX_VM_PERM_EXECUTE) { if (range_with_sp.u.mapping.mmu_flags & ZX_VM_PERM_EXECUTE) {
...@@ -75,8 +77,16 @@ void GetStackRegions( ...@@ -75,8 +77,16 @@ void GetStackRegions(
range_with_sp.base); range_with_sp.base);
const size_t region_size = const size_t region_size =
range_with_sp.size - (start_address - range_with_sp.base); range_with_sp.size - (start_address - range_with_sp.base);
// Because most Fuchsia processes use safestack, it is very unlikely that a
// stack this large would be valid. Even if it were, avoid creating
// unreasonably large dumps by artificially limiting the captured amount.
constexpr uint64_t kMaxStackCapture = 1048576u;
LOG_IF(ERROR, region_size > kMaxStackCapture)
<< "clamping unexpectedly large stack capture of " << region_size;
const size_t clamped_region_size = std::min(region_size, kMaxStackCapture);
stack_regions->push_back( stack_regions->push_back(
CheckedRange<zx_vaddr_t, size_t>(start_address, region_size)); CheckedRange<zx_vaddr_t, size_t>(start_address, clamped_region_size));
// TODO(scottmg): https://crashpad.chromium.org/bug/196, once the retrievable // TODO(scottmg): https://crashpad.chromium.org/bug/196, once the retrievable
// registers include FS and similar for ARM, retrieve the region for the // registers include FS and similar for ARM, retrieve the region for the
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "snapshot/fuchsia/process_snapshot_fuchsia.h" #include "snapshot/fuchsia/process_snapshot_fuchsia.h"
#include "test/multiprocess_exec.h" #include "test/multiprocess_exec.h"
#include "util/fuchsia/koid_utilities.h"
#include "util/fuchsia/scoped_task_suspend.h" #include "util/fuchsia/scoped_task_suspend.h"
namespace crashpad { namespace crashpad {
...@@ -139,6 +140,96 @@ TEST(ProcessSnapshotFuchsiaTest, AddressSpaceMapping) { ...@@ -139,6 +140,96 @@ TEST(ProcessSnapshotFuchsiaTest, AddressSpaceMapping) {
test.Run(); test.Run();
} }
CRASHPAD_CHILD_TEST_MAIN(StackPointerIntoInvalidLocation) {
// Map a large block, output the base address of it, and block. The parent
// will artificially set the SP into this large block to confirm that a huge
// stack is not accidentally captured.
zx_handle_t large_vmo;
constexpr uint64_t kSize = 1 << 30u;
zx_status_t status = zx_vmo_create(kSize, 0, &large_vmo);
ZX_CHECK(status == ZX_OK, status) << "zx_vmo_create";
zx_vaddr_t mapped_addr;
status = zx_vmar_map(zx_vmar_root_self(),
ZX_VM_PERM_READ | ZX_VM_PERM_WRITE,
0,
large_vmo,
0,
kSize,
&mapped_addr);
ZX_CHECK(status == ZX_OK, status) << "zx_vmar_map";
CheckedWriteFile(StdioFileHandle(StdioStream::kStandardOutput),
&mapped_addr,
sizeof(mapped_addr));
zx_nanosleep(ZX_TIME_INFINITE);
return 0;
}
class InvalidStackPointerTest : public MultiprocessExec {
public:
InvalidStackPointerTest() : MultiprocessExec() {
SetChildTestMainFunction("StackPointerIntoInvalidLocation");
SetExpectedChildTermination(kTerminationNormal,
ZX_TASK_RETCODE_SYSCALL_KILL);
}
~InvalidStackPointerTest() {}
private:
void MultiprocessParent() override {
uint64_t address_of_large_mapping;
ASSERT_TRUE(ReadFileExactly(ReadPipeHandle(),
&address_of_large_mapping,
sizeof(address_of_large_mapping)));
ScopedTaskSuspend suspend(*ChildProcess());
std::vector<zx::thread> threads = GetThreadHandles(*ChildProcess());
ASSERT_EQ(threads.size(), 1u);
zx_thread_state_general_regs_t regs;
ASSERT_EQ(threads[0].read_state(
ZX_THREAD_STATE_GENERAL_REGS, &regs, sizeof(regs)),
ZX_OK);
constexpr uint64_t kOffsetIntoMapping = 1024;
#if defined(ARCH_CPU_X86_64)
regs.rsp = address_of_large_mapping + kOffsetIntoMapping;
#elif defined(ARCH_CPU_ARM64)
regs.sp = address_of_large_mapping + kOffsetIntoMapping;
#else
#error
#endif
ASSERT_EQ(threads[0].write_state(
ZX_THREAD_STATE_GENERAL_REGS, &regs, sizeof(regs)),
ZX_OK);
ProcessSnapshotFuchsia process_snapshot;
ASSERT_TRUE(process_snapshot.Initialize(*ChildProcess()));
ASSERT_EQ(process_snapshot.Threads().size(), 1u);
const MemorySnapshot* stack = process_snapshot.Threads()[0]->Stack();
ASSERT_TRUE(stack);
// Ensure the stack capture isn't unreasonably large.
EXPECT_LT(stack->Size(), 10 * 1048576u);
// As we've corrupted the child, don't let it run again.
ASSERT_EQ(ChildProcess()->kill(), ZX_OK);
}
DISALLOW_COPY_AND_ASSIGN(InvalidStackPointerTest);
};
// This is a test for a specific failure detailed in
// https://bugs.fuchsia.dev/p/fuchsia/issues/detail?id=41212. A test of stack
// behavior that was intentionally overflowing the stack, and so when Crashpad
// received the exception the SP did not point into the actual stack. This
// caused Crashpad to erronously capture the "stack" from the next mapping in
// the address space (which could be very large, cause OOM, etc.).
TEST(ProcessSnapshotFuchsiaTest, InvalidStackPointer) {
InvalidStackPointerTest test;
test.Run();
}
} // namespace } // namespace
} // namespace test } // namespace test
} // namespace crashpad } // namespace crashpad
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/posix/eintr_wrapper.h" #include "base/posix/eintr_wrapper.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "third_party/lss/lss.h"
#include "util/file/file_io.h" #include "util/file/file_io.h"
#include "util/linux/ptrace_broker.h" #include "util/linux/ptrace_broker.h"
#include "util/linux/socket.h" #include "util/linux/socket.h"
...@@ -39,20 +40,21 @@ namespace { ...@@ -39,20 +40,21 @@ namespace {
class ScopedSigprocmaskRestore { class ScopedSigprocmaskRestore {
public: public:
explicit ScopedSigprocmaskRestore(const sigset_t& set_to_block) explicit ScopedSigprocmaskRestore(const kernel_sigset_t& set_to_block)
: orig_mask_(), mask_is_set_(false) { : orig_mask_(), mask_is_set_(false) {
mask_is_set_ = sigprocmask(SIG_BLOCK, &set_to_block, &orig_mask_) == 0; mask_is_set_ = sys_sigprocmask(SIG_BLOCK, &set_to_block, &orig_mask_) == 0;
DPLOG_IF(ERROR, !mask_is_set_) << "sigprocmask"; DPLOG_IF(ERROR, !mask_is_set_) << "sigprocmask";
} }
~ScopedSigprocmaskRestore() { ~ScopedSigprocmaskRestore() {
if (mask_is_set_ && sigprocmask(SIG_SETMASK, &orig_mask_, nullptr) != 0) { if (mask_is_set_ &&
sys_sigprocmask(SIG_SETMASK, &orig_mask_, nullptr) != 0) {
DPLOG(ERROR) << "sigprocmask"; DPLOG(ERROR) << "sigprocmask";
} }
} }
private: private:
sigset_t orig_mask_; kernel_sigset_t orig_mask_;
bool mask_is_set_; bool mask_is_set_;
DISALLOW_COPY_AND_ASSIGN(ScopedSigprocmaskRestore); DISALLOW_COPY_AND_ASSIGN(ScopedSigprocmaskRestore);
...@@ -119,11 +121,9 @@ void ExceptionHandlerClient::SetCanSetPtracer(bool can_set_ptracer) { ...@@ -119,11 +121,9 @@ void ExceptionHandlerClient::SetCanSetPtracer(bool can_set_ptracer) {
int ExceptionHandlerClient::SignalCrashDump( int ExceptionHandlerClient::SignalCrashDump(
const ExceptionHandlerProtocol::ClientInformation& info, const ExceptionHandlerProtocol::ClientInformation& info,
VMAddress stack_pointer) { VMAddress stack_pointer) {
// TODO(jperaza): Use lss for system calls when sys_sigtimedwait() exists. kernel_sigset_t dump_done_sigset;
// https://crbug.com/crashpad/265 sys_sigemptyset(&dump_done_sigset);
sigset_t dump_done_sigset; sys_sigaddset(&dump_done_sigset, ExceptionHandlerProtocol::kDumpDoneSignal);
sigemptyset(&dump_done_sigset);
sigaddset(&dump_done_sigset, ExceptionHandlerProtocol::kDumpDoneSignal);
ScopedSigprocmaskRestore scoped_block(dump_done_sigset); ScopedSigprocmaskRestore scoped_block(dump_done_sigset);
int status = SendCrashDumpRequest(info, stack_pointer); int status = SendCrashDumpRequest(info, stack_pointer);
...@@ -131,19 +131,14 @@ int ExceptionHandlerClient::SignalCrashDump( ...@@ -131,19 +131,14 @@ int ExceptionHandlerClient::SignalCrashDump(
return status; return status;
} }
#if defined(OS_ANDROID) && __ANDROID_API__ < 23
// sigtimedwait() wrappers aren't available on Android until API 23 but this
// can use the lss wrapper when it's available.
NOTREACHED();
#else
siginfo_t siginfo = {}; siginfo_t siginfo = {};
timespec timeout; timespec timeout;
timeout.tv_sec = 5; timeout.tv_sec = 5;
timeout.tv_nsec = 0; timeout.tv_nsec = 0;
if (HANDLE_EINTR(sigtimedwait(&dump_done_sigset, &siginfo, &timeout)) < 0) { if (HANDLE_EINTR(sys_sigtimedwait(&dump_done_sigset, &siginfo, &timeout)) <
0) {
return errno; return errno;
} }
#endif
return 0; return 0;
} }
......
...@@ -416,6 +416,7 @@ ...@@ -416,6 +416,7 @@
['include', '^linux/'], ['include', '^linux/'],
['include', '^misc/capture_context_linux\\.S$'], ['include', '^misc/capture_context_linux\\.S$'],
['include', '^misc/paths_linux\\.cc$'], ['include', '^misc/paths_linux\\.cc$'],
['include', '^misc/time_linux\\.cc$'],
['include', '^posix/process_info_linux\\.cc$'], ['include', '^posix/process_info_linux\\.cc$'],
['include', '^process/process_memory_linux\\.cc$'], ['include', '^process/process_memory_linux\\.cc$'],
['include', '^process/process_memory_linux\\.h$'], ['include', '^process/process_memory_linux\\.h$'],
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment