Bug 1068410 - Remove procfs-searching workaround for credential-passing bug. r=ted

This commit is contained in:
Jed Davis 2014-10-03 14:55:03 -07:00
Родитель fd7f734997
Коммит aaac17ba60
2 изменённых файлов: 151 добавлений и 127 удалений

Просмотреть файл

@ -0,0 +1,151 @@
commit 467c77076b232246970551cfba645d235381f588
Author: Jed Davis <jld@mozilla.com>
Date: Wed Sep 17 11:34:38 2014 -0700
Bug 1068410 - Remove procfs-searching workaround for credential-passing bug.
diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/crash_generation_server.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/crash_generation_server.cc
index f1e16b1..420e4b2 100644
--- a/toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/crash_generation_server.cc
+++ b/toolkit/crashreporter/google-breakpad/src/client/linux/crash_generation/crash_generation_server.cc
@@ -51,116 +51,6 @@
static const char kCommandQuit = 'x';
-static bool
-GetInodeForFileDescriptor(ino_t* inode_out, int fd)
-{
- assert(inode_out);
-
- struct stat buf;
- if (fstat(fd, &buf) < 0)
- return false;
-
- if (!S_ISSOCK(buf.st_mode))
- return false;
-
- *inode_out = buf.st_ino;
- return true;
-}
-
-// expected prefix of the target of the /proc/self/fd/%d link for a socket
-static const char kSocketLinkPrefix[] = "socket:[";
-
-// Parse a symlink in /proc/pid/fd/$x and return the inode number of the
-// socket.
-// inode_out: (output) set to the inode number on success
-// path: e.g. /proc/1234/fd/5 (must be a UNIX domain socket descriptor)
-static bool
-GetInodeForProcPath(ino_t* inode_out, const char* path)
-{
- assert(inode_out);
- assert(path);
-
- char buf[PATH_MAX];
- if (!google_breakpad::SafeReadLink(path, buf)) {
- return false;
- }
-
- if (0 != memcmp(kSocketLinkPrefix, buf, sizeof(kSocketLinkPrefix) - 1)) {
- return false;
- }
-
- char* endptr;
- const uint64_t inode_ul =
- strtoull(buf + sizeof(kSocketLinkPrefix) - 1, &endptr, 10);
- if (*endptr != ']')
- return false;
-
- if (inode_ul == ULLONG_MAX) {
- return false;
- }
-
- *inode_out = inode_ul;
- return true;
-}
-
-static bool
-FindProcessHoldingSocket(pid_t* pid_out, ino_t socket_inode)
-{
- assert(pid_out);
- bool already_found = false;
-
- DIR* proc = opendir("/proc");
- if (!proc) {
- return false;
- }
-
- std::vector<pid_t> pids;
-
- struct dirent* dent;
- while ((dent = readdir(proc))) {
- char* endptr;
- const unsigned long int pid_ul = strtoul(dent->d_name, &endptr, 10);
- if (pid_ul == ULONG_MAX || '\0' != *endptr)
- continue;
- pids.push_back(pid_ul);
- }
- closedir(proc);
-
- for (std::vector<pid_t>::const_iterator
- i = pids.begin(); i != pids.end(); ++i) {
- const pid_t current_pid = *i;
- char buf[PATH_MAX];
- snprintf(buf, sizeof(buf), "/proc/%d/fd", current_pid);
- DIR* fd = opendir(buf);
- if (!fd)
- continue;
-
- while ((dent = readdir(fd))) {
- if (snprintf(buf, sizeof(buf), "/proc/%d/fd/%s", current_pid,
- dent->d_name) >= static_cast<int>(sizeof(buf))) {
- continue;
- }
-
- ino_t fd_inode;
- if (GetInodeForProcPath(&fd_inode, buf)
- && fd_inode == socket_inode) {
- if (already_found) {
- closedir(fd);
- return false;
- }
-
- already_found = true;
- *pid_out = current_pid;
- break;
- }
- }
-
- closedir(fd);
- }
-
- return already_found;
-}
-
namespace google_breakpad {
CrashGenerationServer::CrashGenerationServer(
@@ -367,23 +257,6 @@ CrashGenerationServer::ClientEvent(short revents)
return true;
}
- // Kernel bug workaround (broken in 2.6.30 at least):
- // The kernel doesn't translate PIDs in SCM_CREDENTIALS across PID
- // namespaces. Thus |crashing_pid| might be garbage from our point of view.
- // In the future we can remove this workaround, but we have to wait a couple
- // of years to be sure that it's worked its way out into the world.
-
- ino_t inode_number;
- if (!GetInodeForFileDescriptor(&inode_number, signal_fd)) {
- HANDLE_EINTR(close(signal_fd));
- return true;
- }
-
- if (!FindProcessHoldingSocket(&crashing_pid, inode_number - 1)) {
- HANDLE_EINTR(close(signal_fd));
- return true;
- }
-
string minidump_filename;
if (!MakeMinidumpFilename(minidump_filename))
return true;

Просмотреть файл

@ -51,116 +51,6 @@
static const char kCommandQuit = 'x';
static bool
GetInodeForFileDescriptor(ino_t* inode_out, int fd)
{
assert(inode_out);
struct stat buf;
if (fstat(fd, &buf) < 0)
return false;
if (!S_ISSOCK(buf.st_mode))
return false;
*inode_out = buf.st_ino;
return true;
}
// expected prefix of the target of the /proc/self/fd/%d link for a socket
static const char kSocketLinkPrefix[] = "socket:[";
// Parse a symlink in /proc/pid/fd/$x and return the inode number of the
// socket.
// inode_out: (output) set to the inode number on success
// path: e.g. /proc/1234/fd/5 (must be a UNIX domain socket descriptor)
static bool
GetInodeForProcPath(ino_t* inode_out, const char* path)
{
assert(inode_out);
assert(path);
char buf[PATH_MAX];
if (!google_breakpad::SafeReadLink(path, buf)) {
return false;
}
if (0 != memcmp(kSocketLinkPrefix, buf, sizeof(kSocketLinkPrefix) - 1)) {
return false;
}
char* endptr;
const uint64_t inode_ul =
strtoull(buf + sizeof(kSocketLinkPrefix) - 1, &endptr, 10);
if (*endptr != ']')
return false;
if (inode_ul == ULLONG_MAX) {
return false;
}
*inode_out = inode_ul;
return true;
}
static bool
FindProcessHoldingSocket(pid_t* pid_out, ino_t socket_inode)
{
assert(pid_out);
bool already_found = false;
DIR* proc = opendir("/proc");
if (!proc) {
return false;
}
std::vector<pid_t> pids;
struct dirent* dent;
while ((dent = readdir(proc))) {
char* endptr;
const unsigned long int pid_ul = strtoul(dent->d_name, &endptr, 10);
if (pid_ul == ULONG_MAX || '\0' != *endptr)
continue;
pids.push_back(pid_ul);
}
closedir(proc);
for (std::vector<pid_t>::const_iterator
i = pids.begin(); i != pids.end(); ++i) {
const pid_t current_pid = *i;
char buf[PATH_MAX];
snprintf(buf, sizeof(buf), "/proc/%d/fd", current_pid);
DIR* fd = opendir(buf);
if (!fd)
continue;
while ((dent = readdir(fd))) {
if (snprintf(buf, sizeof(buf), "/proc/%d/fd/%s", current_pid,
dent->d_name) >= static_cast<int>(sizeof(buf))) {
continue;
}
ino_t fd_inode;
if (GetInodeForProcPath(&fd_inode, buf)
&& fd_inode == socket_inode) {
if (already_found) {
closedir(fd);
return false;
}
already_found = true;
*pid_out = current_pid;
break;
}
}
closedir(fd);
}
return already_found;
}
namespace google_breakpad {
CrashGenerationServer::CrashGenerationServer(
@ -367,23 +257,6 @@ CrashGenerationServer::ClientEvent(short revents)
return true;
}
// Kernel bug workaround (broken in 2.6.30 at least):
// The kernel doesn't translate PIDs in SCM_CREDENTIALS across PID
// namespaces. Thus |crashing_pid| might be garbage from our point of view.
// In the future we can remove this workaround, but we have to wait a couple
// of years to be sure that it's worked its way out into the world.
ino_t inode_number;
if (!GetInodeForFileDescriptor(&inode_number, signal_fd)) {
HANDLE_EINTR(close(signal_fd));
return true;
}
if (!FindProcessHoldingSocket(&crashing_pid, inode_number - 1)) {
HANDLE_EINTR(close(signal_fd));
return true;
}
string minidump_filename;
if (!MakeMinidumpFilename(minidump_filename))
return true;