From 78bcb55e1c7baa5badbd7ff7685ab63da17aab6a Mon Sep 17 00:00:00 2001 From: Joshua Peraza Date: Tue, 10 Aug 2021 14:55:25 -0700 Subject: [PATCH] Construct ProcessMemoryLinux using PtraceConnection Update ProcessMemoryLinux to be constructed from PtraceConnection instead of being Initialize()d with a pid_t. This allows consolidating PtraceClient's BrokeredMemory with ProcessMemoryLinux and providing the PtraceConnection as a alternative to the memory file (previously only done for brokered connections). Change-Id: I1363e208030eaf595fb8051e9a2c6b255c1f9886 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/3072402 Reviewed-by: Mark Mentovai Commit-Queue: Joshua Peraza --- .../crashpad_info_reader_test.cc | 10 ++++ .../image_annotation_reader_test.cc | 10 ++++ snapshot/elf/elf_image_reader_test.cc | 18 +++++-- snapshot/linux/debug_rendezvous_test.cc | 3 +- .../sanitization_information_test.cc | 13 +++-- test/linux/fake_ptrace_connection.cc | 14 +++--- test/linux/fake_ptrace_connection.h | 3 ++ util/linux/auxiliary_vector_test.cc | 3 +- util/linux/direct_ptrace_connection.cc | 15 ++++-- util/linux/direct_ptrace_connection.h | 3 +- util/linux/ptrace_broker_test.cc | 31 +++++------- util/linux/ptrace_client.cc | 30 ++---------- util/linux/ptrace_client.h | 22 +-------- util/linux/ptrace_connection.h | 14 ++++++ util/process/process_memory_linux.cc | 49 +++++++++---------- util/process/process_memory_linux.h | 19 ++----- util/process/process_memory_range_test.cc | 10 ++++ util/process/process_memory_sanitized_test.cc | 16 ++++++ util/process/process_memory_test.cc | 29 +++++++++++ 19 files changed, 183 insertions(+), 129 deletions(-) diff --git a/snapshot/crashpad_types/crashpad_info_reader_test.cc b/snapshot/crashpad_types/crashpad_info_reader_test.cc index ebc6a4d3..556ead1b 100644 --- a/snapshot/crashpad_types/crashpad_info_reader_test.cc +++ b/snapshot/crashpad_types/crashpad_info_reader_test.cc @@ -30,6 +30,10 @@ #include "util/misc/from_pointer_cast.h" #include "util/process/process_memory_native.h" +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#include "test/linux/fake_ptrace_connection.h" +#endif + namespace crashpad { namespace test { namespace { @@ -102,8 +106,14 @@ void ExpectCrashpadInfo(ProcessType process, VMAddress extra_memory_address, VMAddress simple_annotations_address, VMAddress annotations_list_address) { +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) + FakePtraceConnection connection; + ASSERT_TRUE(connection.Initialize(process)); + ProcessMemoryLinux memory(&connection); +#else ProcessMemoryNative memory; ASSERT_TRUE(memory.Initialize(process)); +#endif ProcessMemoryRange range; ASSERT_TRUE(range.Initialize(&memory, is_64_bit)); diff --git a/snapshot/crashpad_types/image_annotation_reader_test.cc b/snapshot/crashpad_types/image_annotation_reader_test.cc index 72a637bf..9d9970e6 100644 --- a/snapshot/crashpad_types/image_annotation_reader_test.cc +++ b/snapshot/crashpad_types/image_annotation_reader_test.cc @@ -32,6 +32,10 @@ #include "util/misc/from_pointer_cast.h" #include "util/process/process_memory_native.h" +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#include "test/linux/fake_ptrace_connection.h" +#endif + namespace crashpad { namespace test { namespace { @@ -90,8 +94,14 @@ void ExpectAnnotations(ProcessType process, bool is_64_bit, VMAddress simple_map_address, VMAddress annotation_list_address) { +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) + FakePtraceConnection connection; + ASSERT_TRUE(connection.Initialize(process)); + ProcessMemoryLinux memory(&connection); +#else ProcessMemoryNative memory; ASSERT_TRUE(memory.Initialize(process)); +#endif ProcessMemoryRange range; ASSERT_TRUE(range.Initialize(&memory, is_64_bit)); diff --git a/snapshot/elf/elf_image_reader_test.cc b/snapshot/elf/elf_image_reader_test.cc index 63da92ae..2ea55ad1 100644 --- a/snapshot/elf/elf_image_reader_test.cc +++ b/snapshot/elf/elf_image_reader_test.cc @@ -127,21 +127,22 @@ void ReadThisExecutableInTarget(ProcessType process, constexpr bool am_64_bit = false; #endif // ARCH_CPU_64_BITS - ProcessMemoryNative memory; - ASSERT_TRUE(memory.Initialize(process)); - ProcessMemoryRange range; - ASSERT_TRUE(range.Initialize(&memory, am_64_bit)); - VMAddress elf_address; #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) FakePtraceConnection connection; ASSERT_TRUE(connection.Initialize(process)); + ProcessMemoryLinux memory(&connection); LocateExecutable(&connection, &memory, &elf_address); #elif defined(OS_FUCHSIA) + ProcessMemoryFuchsia memory; + ASSERT_TRUE(memory.Initialize(process)); LocateExecutable(process, &memory, &elf_address); #endif ASSERT_NO_FATAL_FAILURE(); + ProcessMemoryRange range; + ASSERT_TRUE(range.Initialize(&memory, am_64_bit)); + ElfImageReader reader; ASSERT_TRUE(reader.Initialize(range, elf_address)); @@ -191,8 +192,15 @@ void ReadLibcInTarget(ProcessType process, constexpr bool am_64_bit = false; #endif // ARCH_CPU_64_BITS +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) + FakePtraceConnection connection; + ASSERT_TRUE(connection.Initialize(process)); + ProcessMemoryLinux memory(&connection); +#else ProcessMemoryNative memory; ASSERT_TRUE(memory.Initialize(process)); +#endif + ProcessMemoryRange range; ASSERT_TRUE(range.Initialize(&memory, am_64_bit)); diff --git a/snapshot/linux/debug_rendezvous_test.cc b/snapshot/linux/debug_rendezvous_test.cc index d32bd193..41956aa5 100644 --- a/snapshot/linux/debug_rendezvous_test.cc +++ b/snapshot/linux/debug_rendezvous_test.cc @@ -83,8 +83,7 @@ void TestAgainstTarget(PtraceConnection* connection) { ASSERT_EQ(exe_mappings->Count(), 1u); LinuxVMAddress elf_address = exe_mappings->Next()->range.Base(); - ProcessMemoryLinux memory; - ASSERT_TRUE(memory.Initialize(connection->GetProcessID())); + ProcessMemoryLinux memory(connection); ProcessMemoryRange range; ASSERT_TRUE(range.Initialize(&memory, connection->Is64Bit())); diff --git a/snapshot/sanitized/sanitization_information_test.cc b/snapshot/sanitized/sanitization_information_test.cc index f3864424..425ec752 100644 --- a/snapshot/sanitized/sanitization_information_test.cc +++ b/snapshot/sanitized/sanitization_information_test.cc @@ -20,6 +20,10 @@ #include "util/misc/from_pointer_cast.h" #include "util/process/process_memory_linux.h" +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#include "test/linux/fake_ptrace_connection.h" +#endif + namespace crashpad { namespace test { namespace { @@ -27,11 +31,12 @@ namespace { class AllowedAnnotationsTest : public testing::Test { public: void SetUp() override { - ASSERT_TRUE(memory_.Initialize(getpid())); + ASSERT_TRUE(connection_.Initialize(getpid())); + #if defined(ARCH_CPU_64_BITS) - ASSERT_TRUE(range_.Initialize(&memory_, true)); + ASSERT_TRUE(range_.Initialize(connection_.Memory(), true)); #else - ASSERT_TRUE(range_.Initialize(&memory_, false)); + ASSERT_TRUE(range_.Initialize(connection_.Memory(), false)); #endif } @@ -41,7 +46,7 @@ class AllowedAnnotationsTest : public testing::Test { range_, FromPointerCast(address), &allowed_annotations_); } - ProcessMemoryLinux memory_; + FakePtraceConnection connection_; ProcessMemoryRange range_; std::vector allowed_annotations_; }; diff --git a/test/linux/fake_ptrace_connection.cc b/test/linux/fake_ptrace_connection.cc index d5560454..774a340a 100644 --- a/test/linux/fake_ptrace_connection.cc +++ b/test/linux/fake_ptrace_connection.cc @@ -83,12 +83,7 @@ bool FakePtraceConnection::ReadFileContents(const base::FilePath& path, ProcessMemory* FakePtraceConnection::Memory() { INITIALIZATION_STATE_DCHECK_VALID(initialized_); if (!memory_) { - auto mem = std::make_unique(); - if (mem->Initialize(pid_)) { - memory_ = std::move(mem); - } else { - ADD_FAILURE(); - } + memory_ = std::make_unique(this); } return memory_.get(); } @@ -99,5 +94,12 @@ bool FakePtraceConnection::Threads(std::vector* threads) { return false; } +ssize_t FakePtraceConnection::ReadUpTo(VMAddress address, + size_t size, + void* buffer) { + NOTREACHED(); + return false; +} + } // namespace test } // namespace crashpad diff --git a/test/linux/fake_ptrace_connection.h b/test/linux/fake_ptrace_connection.h index 01a6f925..79cdbd96 100644 --- a/test/linux/fake_ptrace_connection.h +++ b/test/linux/fake_ptrace_connection.h @@ -65,6 +65,9 @@ class FakePtraceConnection : public PtraceConnection { //! \todo Not yet implemented. bool Threads(std::vector* threads) override; + //! \\todo Not yet implemented. + ssize_t ReadUpTo(VMAddress address, size_t size, void* buffer) override; + private: std::set attachments_; std::unique_ptr memory_; diff --git a/util/linux/auxiliary_vector_test.cc b/util/linux/auxiliary_vector_test.cc index 00af5abe..2f6c9422 100644 --- a/util/linux/auxiliary_vector_test.cc +++ b/util/linux/auxiliary_vector_test.cc @@ -95,8 +95,7 @@ void TestAgainstCloneOrSelf(pid_t pid) { ASSERT_TRUE(aux.GetValue(AT_EGID, &egid)); EXPECT_EQ(egid, getegid()); - ProcessMemoryLinux memory; - ASSERT_TRUE(memory.Initialize(pid)); + ProcessMemoryLinux memory(&connection); LinuxVMAddress platform_addr; ASSERT_TRUE(aux.GetValue(AT_PLATFORM, &platform_addr)); diff --git a/util/linux/direct_ptrace_connection.cc b/util/linux/direct_ptrace_connection.cc index 8b552055..5da01475 100644 --- a/util/linux/direct_ptrace_connection.cc +++ b/util/linux/direct_ptrace_connection.cc @@ -39,10 +39,6 @@ bool DirectPtraceConnection::Initialize(pid_t pid) { } pid_ = pid; - if (!memory_.Initialize(pid)) { - return false; - } - INITIALIZATION_STATE_SET_VALID(initialized_); return true; } @@ -79,7 +75,10 @@ bool DirectPtraceConnection::ReadFileContents(const base::FilePath& path, ProcessMemory* DirectPtraceConnection::Memory() { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - return &memory_; + if (!memory_) { + memory_ = std::make_unique(this); + } + return memory_.get(); } bool DirectPtraceConnection::Threads(std::vector* threads) { @@ -87,4 +86,10 @@ bool DirectPtraceConnection::Threads(std::vector* threads) { return ReadThreadIDs(pid_, threads); } +ssize_t DirectPtraceConnection::ReadUpTo(VMAddress address, + size_t size, + void* buffer) { + return ptracer_.ReadUpTo(pid_, address, size, static_cast(buffer)); +} + } // namespace crashpad diff --git a/util/linux/direct_ptrace_connection.h b/util/linux/direct_ptrace_connection.h index 10f8370c..99ad233a 100644 --- a/util/linux/direct_ptrace_connection.h +++ b/util/linux/direct_ptrace_connection.h @@ -57,10 +57,11 @@ class DirectPtraceConnection : public PtraceConnection { std::string* contents) override; ProcessMemory* Memory() override; bool Threads(std::vector* threads) override; + ssize_t ReadUpTo(VMAddress, size_t size, void* buffer) override; private: std::vector> attachments_; - ProcessMemoryLinux memory_; + std::unique_ptr memory_; pid_t pid_; Ptracer ptracer_; InitializationStateDcheck initialized_; diff --git a/util/linux/ptrace_broker_test.cc b/util/linux/ptrace_broker_test.cc index 341f2c80..2012df38 100644 --- a/util/linux/ptrace_broker_test.cc +++ b/util/linux/ptrace_broker_test.cc @@ -151,8 +151,7 @@ class SameBitnessTest : public Multiprocess { broker_thread.Start(); PtraceClient client; - ASSERT_TRUE(client.Initialize( - client_sock.get(), ChildPID(), /* try_direct_memory= */ false)); + ASSERT_TRUE(client.Initialize(client_sock.get(), ChildPID())); EXPECT_EQ(client.GetProcessID(), ChildPID()); @@ -177,32 +176,26 @@ class SameBitnessTest : public Multiprocess { ASSERT_TRUE(client.GetThreadInfo(child2_tid, &info2)); EXPECT_EQ(info2.thread_specific_data_address, child2_tls); - ProcessMemory* memory = client.Memory(); - ASSERT_TRUE(memory); - - auto buffer = std::make_unique(mapping_.len()); - ASSERT_TRUE(memory->Read( - mapping_.addr_as(), mapping_.len(), buffer.get())); auto expected_buffer = mapping_.addr_as(); - for (size_t index = 0; index < mapping_.len(); ++index) { - EXPECT_EQ(buffer[index], expected_buffer[index]); - } - char first; - ASSERT_TRUE( - memory->Read(mapping_.addr_as(), sizeof(first), &first)); + ASSERT_EQ( + client.ReadUpTo(mapping_.addr_as(), sizeof(first), &first), + 1); EXPECT_EQ(first, expected_buffer[0]); char last; - ASSERT_TRUE(memory->Read(mapping_.addr_as() + mapping_.len() - 1, - sizeof(last), - &last)); + ASSERT_EQ( + client.ReadUpTo(mapping_.addr_as() + mapping_.len() - 1, + sizeof(last), + &last), + 1); EXPECT_EQ(last, expected_buffer[mapping_.len() - 1]); char unmapped; - EXPECT_FALSE(memory->Read(mapping_.addr_as() + mapping_.len(), + EXPECT_EQ(client.ReadUpTo(mapping_.addr_as() + mapping_.len(), sizeof(unmapped), - &unmapped)); + &unmapped), + -1); std::string file_root = file_dir.value() + '/'; broker.SetFileRoot(file_root.c_str()); diff --git a/util/linux/ptrace_client.cc b/util/linux/ptrace_client.cc index 0e9c8219..cb1a1a5d 100644 --- a/util/linux/ptrace_client.cc +++ b/util/linux/ptrace_client.cc @@ -143,7 +143,7 @@ PtraceClient::~PtraceClient() { } } -bool PtraceClient::Initialize(int sock, pid_t pid, bool try_direct_memory) { +bool PtraceClient::Initialize(int sock, pid_t pid) { INITIALIZATION_STATE_SET_INITIALIZING(initialized_); sock_ = sock; pid_ = pid; @@ -166,16 +166,6 @@ bool PtraceClient::Initialize(int sock, pid_t pid, bool try_direct_memory) { } is_64_bit_ = is_64_bit == ExceptionHandlerProtocol::kBoolTrue; - if (try_direct_memory) { - auto direct_mem = std::make_unique(); - if (direct_mem->Initialize(pid)) { - memory_.reset(direct_mem.release()); - } - } - if (!memory_) { - memory_ = std::make_unique(this); - } - INITIALIZATION_STATE_SET_VALID(initialized_); return true; } @@ -260,6 +250,9 @@ bool PtraceClient::ReadFileContents(const base::FilePath& path, ProcessMemory* PtraceClient::Memory() { INITIALIZATION_STATE_DCHECK_VALID(initialized_); + if (!memory_) { + memory_ = std::make_unique(this); + } return memory_.get(); } @@ -308,20 +301,7 @@ bool PtraceClient::Threads(std::vector* threads) { return true; } -PtraceClient::BrokeredMemory::BrokeredMemory(PtraceClient* client) - : ProcessMemory(), client_(client) {} - -PtraceClient::BrokeredMemory::~BrokeredMemory() = default; - -ssize_t PtraceClient::BrokeredMemory::ReadUpTo(VMAddress address, - size_t size, - void* buffer) const { - return client_->ReadUpTo(address, size, buffer); -} - -ssize_t PtraceClient::ReadUpTo(VMAddress address, - size_t size, - void* buffer) const { +ssize_t PtraceClient::ReadUpTo(VMAddress address, size_t size, void* buffer) { INITIALIZATION_STATE_DCHECK_VALID(initialized_); char* buffer_c = reinterpret_cast(buffer); diff --git a/util/linux/ptrace_client.h b/util/linux/ptrace_client.h index b4f27ae7..896a8b4c 100644 --- a/util/linux/ptrace_client.h +++ b/util/linux/ptrace_client.h @@ -46,11 +46,8 @@ class PtraceClient : public PtraceConnection { //! ownership of the socket. //! \param[in] pid The process ID of the process to form a PtraceConnection //! with. - //! \param[in] try_direct_memory If `true` the client will attempt to support - //! memory reading operations by directly acessing the target process' - //! /proc/[pid]/mem file. //! \return `true` on success. `false` on failure with a message logged. - bool Initialize(int sock, pid_t pid, bool try_direct_memory = true); + bool Initialize(int sock, pid_t pid); // PtraceConnection: @@ -62,24 +59,9 @@ class PtraceClient : public PtraceConnection { std::string* contents) override; ProcessMemory* Memory() override; bool Threads(std::vector* threads) override; + ssize_t ReadUpTo(VMAddress address, size_t size, void* buffer) override; private: - class BrokeredMemory : public ProcessMemory { - public: - explicit BrokeredMemory(PtraceClient* client); - ~BrokeredMemory(); - - ssize_t ReadUpTo(VMAddress address, - size_t size, - void* buffer) const override; - - private: - PtraceClient* client_; - - DISALLOW_COPY_AND_ASSIGN(BrokeredMemory); - }; - - ssize_t ReadUpTo(VMAddress address, size_t size, void* buffer) const; bool SendFilePath(const char* path, size_t length); std::unique_ptr memory_; diff --git a/util/linux/ptrace_connection.h b/util/linux/ptrace_connection.h index 21117475..9b31d52a 100644 --- a/util/linux/ptrace_connection.h +++ b/util/linux/ptrace_connection.h @@ -73,6 +73,20 @@ class PtraceConnection { //! this method returns `false`, \a threads may contain a partial list of //! thread IDs. virtual bool Threads(std::vector* threads) = 0; + + //! \brief Copies memory from the connected process into a caller-provided + //! buffer in the current process, up to a maximum number of bytes. + //! + //! \param[in] address The address, in the connected process' address space, + //! of the memory region to copy. + //! \param[in] size The maximum size, in bytes, of the memory region to copy. + //! \a buffer must be at least this size. + //! \param[out] buffer The buffer into which the contents of the other + //! process' memory will be copied. + //! + //! \return the number of bytes copied, 0 if there is no more data to read, or + //! -1 on failure with a message logged. + virtual ssize_t ReadUpTo(VMAddress address, size_t size, void* buffer) = 0; }; } // namespace crashpad diff --git a/util/process/process_memory_linux.cc b/util/process/process_memory_linux.cc index 1fc3c05f..56ac0ec8 100644 --- a/util/process/process_memory_linux.cc +++ b/util/process/process_memory_linux.cc @@ -27,38 +27,37 @@ namespace crashpad { -ProcessMemoryLinux::ProcessMemoryLinux() - : ProcessMemory(), mem_fd_(), pid_(-1), initialized_() {} +ProcessMemoryLinux::ProcessMemoryLinux(PtraceConnection* connection) + : ProcessMemory(), mem_fd_() { + char path[32]; + snprintf(path, sizeof(path), "/proc/%d/mem", connection->GetProcessID()); + mem_fd_.reset(HANDLE_EINTR(open(path, O_RDONLY | O_NOCTTY | O_CLOEXEC))); + if (mem_fd_.is_valid()) { + read_up_to_ = [this](VMAddress address, size_t size, void* buffer) { + ssize_t bytes_read = + HANDLE_EINTR(pread64(mem_fd_.get(), buffer, size, address)); + if (bytes_read < 0) { + PLOG(ERROR) << "pread64"; + } + return bytes_read; + }; + return; + } + + read_up_to_ = std::bind(&PtraceConnection::ReadUpTo, + connection, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3); +} ProcessMemoryLinux::~ProcessMemoryLinux() {} -bool ProcessMemoryLinux::Initialize(pid_t pid) { - INITIALIZATION_STATE_SET_INITIALIZING(initialized_); - pid_ = pid; - char path[32]; - snprintf(path, sizeof(path), "/proc/%d/mem", pid_); - mem_fd_.reset(HANDLE_EINTR(open(path, O_RDONLY | O_NOCTTY | O_CLOEXEC))); - if (!mem_fd_.is_valid()) { - PLOG(ERROR) << "open"; - return false; - } - INITIALIZATION_STATE_SET_VALID(initialized_); - return true; -} - ssize_t ProcessMemoryLinux::ReadUpTo(VMAddress address, size_t size, void* buffer) const { - INITIALIZATION_STATE_DCHECK_VALID(initialized_); - DCHECK(mem_fd_.is_valid()); DCHECK_LE(size, size_t{std::numeric_limits::max()}); - - ssize_t bytes_read = - HANDLE_EINTR(pread64(mem_fd_.get(), buffer, size, address)); - if (bytes_read < 0) { - PLOG(ERROR) << "pread64"; - } - return bytes_read; + return read_up_to_(address, size, buffer); } } // namespace crashpad diff --git a/util/process/process_memory_linux.h b/util/process/process_memory_linux.h index 4fe008bb..1150f14c 100644 --- a/util/process/process_memory_linux.h +++ b/util/process/process_memory_linux.h @@ -17,12 +17,13 @@ #include +#include #include #include "base/files/scoped_file.h" #include "base/macros.h" +#include "util/linux/ptrace_connection.h" #include "util/misc/address_types.h" -#include "util/misc/initialization_state_dcheck.h" #include "util/process/process_memory.h" namespace crashpad { @@ -30,26 +31,14 @@ namespace crashpad { //! \brief Accesses the memory of another Linux process. class ProcessMemoryLinux final : public ProcessMemory { public: - ProcessMemoryLinux(); + explicit ProcessMemoryLinux(PtraceConnection* connection); ~ProcessMemoryLinux(); - //! \brief Initializes this object to read the memory of a process whose ID - //! is \a pid. - //! - //! This method must be called successfully prior to calling any other method - //! in this class. - //! - //! \param[in] pid The process ID of a target process. - //! - //! \return `true` on success, `false` on failure with a message logged. - bool Initialize(pid_t pid); - private: ssize_t ReadUpTo(VMAddress address, size_t size, void* buffer) const override; + std::function read_up_to_; base::ScopedFD mem_fd_; - pid_t pid_; - InitializationStateDcheck initialized_; DISALLOW_COPY_AND_ASSIGN(ProcessMemoryLinux); }; diff --git a/util/process/process_memory_range_test.cc b/util/process/process_memory_range_test.cc index a5c7afb0..2e34665f 100644 --- a/util/process/process_memory_range_test.cc +++ b/util/process/process_memory_range_test.cc @@ -23,6 +23,10 @@ #include "util/misc/from_pointer_cast.h" #include "util/process/process_memory_native.h" +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#include "test/linux/fake_ptrace_connection.h" +#endif + namespace crashpad { namespace test { namespace { @@ -39,8 +43,14 @@ TEST(ProcessMemoryRange, Basic) { constexpr bool is_64_bit = false; #endif // ARCH_CPU_64_BITS +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) + FakePtraceConnection connection; + ASSERT_TRUE(connection.Initialize(GetSelfProcess())); + ProcessMemoryLinux memory(&connection); +#else ProcessMemoryNative memory; ASSERT_TRUE(memory.Initialize(GetSelfProcess())); +#endif // OS_ANDROID || OS_LINUX || OS_CHROMEOS ProcessMemoryRange range; ASSERT_TRUE(range.Initialize(&memory, is_64_bit)); diff --git a/util/process/process_memory_sanitized_test.cc b/util/process/process_memory_sanitized_test.cc index 1a7f9c93..b88eab13 100644 --- a/util/process/process_memory_sanitized_test.cc +++ b/util/process/process_memory_sanitized_test.cc @@ -19,13 +19,23 @@ #include "util/misc/from_pointer_cast.h" #include "util/process/process_memory_native.h" +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#include "test/linux/fake_ptrace_connection.h" +#endif + namespace crashpad { namespace test { namespace { TEST(ProcessMemorySanitized, DenyDisallowedMemory) { +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) + FakePtraceConnection connection; + ASSERT_TRUE(connection.Initialize(GetSelfProcess())); + ProcessMemoryLinux memory(&connection); +#else ProcessMemoryNative memory; ASSERT_TRUE(memory.Initialize(GetSelfProcess())); +#endif // OS_ANDROID || OS_LINUX || OS_CHROMEOS char c = 42; char out; @@ -41,8 +51,14 @@ TEST(ProcessMemorySanitized, DenyDisallowedMemory) { } TEST(ProcessMemorySanitized, AllowedMemory) { +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) + FakePtraceConnection connection; + ASSERT_TRUE(connection.Initialize(GetSelfProcess())); + ProcessMemoryLinux memory(&connection); +#else ProcessMemoryNative memory; ASSERT_TRUE(memory.Initialize(GetSelfProcess())); +#endif // OS_ANDROID || OS_LINUX || OS_CHROMEOS char str[4] = "ABC"; char out[4]; diff --git a/util/process/process_memory_test.cc b/util/process/process_memory_test.cc index 7faa4004..6857b040 100644 --- a/util/process/process_memory_test.cc +++ b/util/process/process_memory_test.cc @@ -34,6 +34,11 @@ #include "test/mac/mach_multiprocess.h" #endif // defined(OS_APPLE) +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#include "test/linux/fake_ptrace_connection.h" +#include "util/linux/direct_ptrace_connection.h" +#endif // OS_ANDROID || OS_LINUX || OS_CHROMEOS + namespace crashpad { namespace test { namespace { @@ -148,8 +153,14 @@ class ReadTest : public MultiprocessAdaptor { } void DoTest(ProcessType process, size_t region_size, VMAddress address) { +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) + FakePtraceConnection connection; + ASSERT_TRUE(connection.Initialize(process)); + ProcessMemoryLinux memory(&connection); +#else ProcessMemoryNative memory; ASSERT_TRUE(memory.Initialize(process)); +#endif // OS_ANDROID || OS_LINUX || OS_CHROMEOS std::unique_ptr result(new char[region_size]); @@ -328,8 +339,14 @@ class ReadCStringTest : public MultiprocessAdaptor { VMAddress local_empty_address, VMAddress local_short_address, VMAddress long_string_address) { +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) + FakePtraceConnection connection; + ASSERT_TRUE(connection.Initialize(process)); + ProcessMemoryLinux memory(&connection); +#else ProcessMemoryNative memory; ASSERT_TRUE(memory.Initialize(process)); +#endif // OS_ANDROID || OS_LINUX || OS_CHROMEOS Compare(memory, const_empty_address, kConstCharEmpty); Compare(memory, const_short_address, kConstCharShort); @@ -399,8 +416,14 @@ class ReadUnmappedTest : public MultiprocessAdaptor { } void DoTest(ProcessType process, VMAddress address) { +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) + DirectPtraceConnection connection; + ASSERT_TRUE(connection.Initialize(process)); + ProcessMemoryLinux memory(&connection); +#else ProcessMemoryNative memory; ASSERT_TRUE(memory.Initialize(process)); +#endif // OS_ANDROID || OS_LINUX || OS_CHROMEOS VMAddress page_addr1 = address; VMAddress page_addr2 = page_addr1 + base::GetPageSize(); @@ -525,8 +548,14 @@ class ReadCStringUnmappedTest : public MultiprocessAdaptor { void DoTest(ProcessType process, const std::vector& strings) { +#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) + DirectPtraceConnection connection; + ASSERT_TRUE(connection.Initialize(process)); + ProcessMemoryLinux memory(&connection); +#else ProcessMemoryNative memory; ASSERT_TRUE(memory.Initialize(process)); +#endif // OS_ANDROID || OS_LINUX || OS_CHROMEOS std::string result; result.reserve(kChildProcessStringLength + 1);