linux: Move ScopedPrSetPtracer to util/

CrashpadClient will need ScopedPrSetPtracer when launching a handler
process in response to a crash.

Bug: crashpad:30
Change-Id: I35bc784b948349ca771f9cd65ef1089e626976bb
Reviewed-on: https://chromium-review.googlesource.com/927352
Reviewed-by: Mark Mentovai <mark@chromium.org>
Commit-Queue: Joshua Peraza <jperaza@chromium.org>
This commit is contained in:
Joshua Peraza 2018-02-20 13:07:16 -08:00 committed by Commit Bot
parent ebad8bd925
commit 0520fdff1e
8 changed files with 29 additions and 28 deletions

View File

@ -20,11 +20,11 @@
#include "base/logging.h"
#include "gtest/gtest.h"
#include "test/errors.h"
#include "test/linux/scoped_pr_set_ptracer.h"
#include "test/multiprocess.h"
#include "util/linux/direct_ptrace_connection.h"
#include "util/linux/exception_handler_client.h"
#include "util/linux/ptrace_client.h"
#include "util/linux/scoped_pr_set_ptracer.h"
#include "util/synchronization/semaphore.h"
#include "util/thread/thread.h"
@ -205,7 +205,7 @@ class ExceptionHandlerServerTest : public testing::Test {
// If the current ptrace_scope is restricted, the broker needs to be set
// as the ptracer for this process. Setting this process as its own
// ptracer allows the broker to inherit this condition.
ScopedPrSetPtracer set_ptracer(getpid());
ScopedPrSetPtracer set_ptracer(getpid(), /* may_log= */ true);
ExceptionHandlerClient client(server_test_->SockToHandler());
ASSERT_EQ(client.RequestCrashDump(info), 0);

View File

@ -74,8 +74,6 @@ static_library("test") {
"linux/fake_ptrace_connection.h",
"linux/get_tls.cc",
"linux/get_tls.h",
"linux/scoped_pr_set_ptracer.cc",
"linux/scoped_pr_set_ptracer.h",
]
}

View File

@ -45,8 +45,6 @@
'linux/fake_ptrace_connection.h',
'linux/get_tls.cc',
'linux/get_tls.h',
'linux/scoped_pr_set_ptracer.cc',
'linux/scoped_pr_set_ptracer.h',
'mac/dyld.cc',
'mac/dyld.h',
'mac/exception_swallower.cc',

View File

@ -271,6 +271,8 @@ static_library("util") {
"linux/ptrace_connection.h",
"linux/ptracer.cc",
"linux/ptracer.h",
"linux/scoped_pr_set_ptracer.cc",
"linux/scoped_pr_set_ptracer.h",
"linux/scoped_ptrace_attach.cc",
"linux/scoped_ptrace_attach.h",
"linux/thread_info.cc",

View File

@ -12,29 +12,26 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "test/linux/scoped_pr_set_ptracer.h"
#include "util/linux/scoped_pr_set_ptracer.h"
#include <errno.h>
#include <sys/prctl.h>
#include "gtest/gtest.h"
#include "test/errors.h"
#include "base/logging.h"
namespace crashpad {
namespace test {
ScopedPrSetPtracer::ScopedPrSetPtracer(pid_t pid) {
ScopedPrSetPtracer::ScopedPrSetPtracer(pid_t pid, bool may_log)
: success_(false), may_log_(may_log) {
success_ = prctl(PR_SET_PTRACER, pid, 0, 0, 0) == 0;
if (!success_) {
EXPECT_EQ(errno, EINVAL) << ErrnoMessage("prctl");
}
PLOG_IF(ERROR, !success_ && may_log && errno != EINVAL) << "prctl";
}
ScopedPrSetPtracer::~ScopedPrSetPtracer() {
if (success_) {
EXPECT_EQ(prctl(PR_SET_PTRACER, 0, 0, 0, 0), 0) << ErrnoMessage("prctl");
int res = prctl(PR_SET_PTRACER, 0, 0, 0, 0);
PLOG_IF(ERROR, res != 0 && may_log_) << "prctl";
}
}
} // namespace test
} // namespace crashpad

View File

@ -12,36 +12,40 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef CRASHPAD_TEST_LINUX_SCOPED_PR_SET_PTRACER_H_
#define CRASHPAD_TEST_LINUX_SCOPED_PR_SET_PTRACER_H_
#ifndef CRASHPAD_UTIL_LINUX_SCOPED_PR_SET_PTRACER_H_
#define CRASHPAD_UTIL_LINUX_SCOPED_PR_SET_PTRACER_H_
#include <sys/types.h>
#include "base/macros.h"
namespace crashpad {
namespace test {
class ScopedPrSetPtracer {
public:
//! \brief Uses `PR_SET_PTRACER` to set \a pid as the caller's ptracer or
//! expects `EINVAL`.
//! \brief Uses `PR_SET_PTRACER` to set \a pid as the caller's ptracer.
//!
//! `PR_SET_PTRACER` is only supported if the Yama Linux security module (LSM)
//! is enabled. Otherwise, `prctl(PR_SET_PTRACER, ...)` fails with `EINVAL`.
//! See linux-4.9.20/security/yama/yama_lsm.c yama_task_prctl() and
//! linux-4.9.20/kernel/sys.c [sys_]prctl().
explicit ScopedPrSetPtracer(pid_t pid);
//!
//! An error message will be logged on failure only if \a may_log is `true`
//! and `prctl` does not fail with `EINVAL`;
//!
//! \param[in] pid The process ID of the process to make the caller's ptracer.
//! \param[in] may_log if `true`, this class may log error messages.
ScopedPrSetPtracer(pid_t pid, bool may_log);
~ScopedPrSetPtracer();
private:
bool success_;
bool may_log_;
DISALLOW_COPY_AND_ASSIGN(ScopedPrSetPtracer);
};
} // namespace test
} // namespace crashpad
#endif // CRASHPAD_TEST_LINUX_SCOPED_PR_SET_PTRACER_H_
#endif // CRASHPAD_UTIL_LINUX_SCOPED_PR_SET_PTRACER_H_

View File

@ -20,9 +20,9 @@
#include "gtest/gtest.h"
#include "test/errors.h"
#include "test/linux/scoped_pr_set_ptracer.h"
#include "test/multiprocess.h"
#include "util/file/file_io.h"
#include "util/linux/scoped_pr_set_ptracer.h"
namespace crashpad {
namespace test {
@ -75,7 +75,7 @@ class AttachToChildTest : public AttachTest {
}
void MultiprocessChild() override {
ScopedPrSetPtracer set_ptracer(getppid());
ScopedPrSetPtracer set_ptracer(getppid(), /* may_log= */ true);
char c = '\0';
CheckedWriteFile(WritePipeHandle(), &c, sizeof(c));
@ -98,7 +98,7 @@ class AttachToParentResetTest : public AttachTest {
private:
void MultiprocessParent() override {
ScopedPrSetPtracer set_ptracer(ChildPID());
ScopedPrSetPtracer set_ptracer(ChildPID(), /* may_log= */ true);
char c = '\0';
CheckedWriteFile(WritePipeHandle(), &c, sizeof(c));
@ -140,7 +140,7 @@ class AttachToParentDestructorTest : public AttachTest {
private:
void MultiprocessParent() override {
ScopedPrSetPtracer set_ptracer(ChildPID());
ScopedPrSetPtracer set_ptracer(ChildPID(), /* may_log= */ true);
char c = '\0';
CheckedWriteFile(WritePipeHandle(), &c, sizeof(c));

View File

@ -73,6 +73,8 @@
'linux/ptrace_connection.h',
'linux/ptracer.cc',
'linux/ptracer.h',
'linux/scoped_pr_set_ptracer.cc',
'linux/scoped_pr_set_ptracer.h',
'linux/scoped_ptrace_attach.cc',
'linux/scoped_ptrace_attach.h',
'linux/thread_info.cc',