Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,48 @@ struct ScopedSetTracerPID {
}
};

// This detects whether ptrace is blocked (e.g., by seccomp), by forking and
// then attempting ptrace.
// This separate check is necessary because StopTheWorld() creates a *thread*,
// and therefore cannot use waitpid() due to the shared errno.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

errno should be thread local on any reasonable platform?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The existing comment on line 504 states that errno is shared. I think sanitizers run on all manner of unreasonable platforms?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole code is under SANITIZER_LINUX though

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe the real reason is the clone syscall?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, updated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe the real reason is the clone syscall?

*maybe the real treasure was the clones we made along the way

static void TestPTrace() {
// Only check the first time this is called.
static bool checked = false;
if (checked)
return;
checked = true;

// fork() should be cheap because of copy-on-write. Besides, this is only
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't call fork "cheap" exactly

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reworded

// called the first time.
int pid = internal_fork();

if (pid < 0) {
int rverrno;
if (internal_iserror(pid, &rverrno)) {
Report("WARNING: TestPTrace() failed to fork (errno %d)\n", rverrno);
}
_exit(-1);
}

if (pid == 0) {
// Child subprocess
internal_ptrace(PTRACE_ATTACH, 0, nullptr, nullptr);
_exit (0);
} else {
int wstatus;
internal_waitpid(pid, &wstatus, 0);

if (WIFSIGNALED(wstatus)) {
VReport(0, "Warning: ptrace appears to be blocked (is seccomp enabled?). LeakSanitizer may hang.\n");
VReport(0, "Child exited with signal %d.\n", WTERMSIG(wstatus));
// We don't abort the sanitizer - it's still worth letting the sanitizer try.
}
}
}

void StopTheWorld(StopTheWorldCallback callback, void *argument) {
TestPTrace();

StopTheWorldScope in_stoptheworld;
// Prepare the arguments for TracerThread.
struct TracerThreadArgument tracer_thread_argument;
Expand Down
Loading