diff --git a/src/client/linux/crash_generation/crash_generation_server.cc b/src/client/linux/crash_generation/crash_generation_server.cc index 8ec95038..1abf826c 100644 --- a/src/client/linux/crash_generation/crash_generation_server.cc +++ b/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 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::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(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)) { - close(signal_fd); - return true; - } - - if (!FindProcessHoldingSocket(&crashing_pid, inode_number - 1)) { - close(signal_fd); - return true; - } - string minidump_filename; if (!MakeMinidumpFilename(minidump_filename)) return true;