| Index: chrome/app/breakpad_linux.cc
|
| ===================================================================
|
| --- chrome/app/breakpad_linux.cc (revision 118704)
|
| +++ chrome/app/breakpad_linux.cc (working copy)
|
| @@ -1,4 +1,4 @@
|
| -// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| @@ -39,6 +39,10 @@
|
| #include "content/common/chrome_descriptors.h"
|
| #include "seccompsandbox/linux_syscall_support.h"
|
|
|
| +#ifndef PR_SET_PTRACER
|
| +#define PR_SET_PTRACER 0x59616d61
|
| +#endif
|
| +
|
| // Some versions of gcc are prone to warn about unused return values. In cases
|
| // where we either a) know the call cannot fail, or b) there is nothing we
|
| // can do when a call fails, we mark the return code as ignored. This avoids
|
| @@ -721,7 +725,7 @@
|
| google_breakpad::PageAllocator allocator;
|
| const unsigned dump_path_len = my_strlen(dump_path);
|
| const unsigned minidump_id_len = my_strlen(minidump_id);
|
| - char *const path = reinterpret_cast<char*>(allocator.Alloc(
|
| + char* const path = reinterpret_cast<char*>(allocator.Alloc(
|
| dump_path_len + 1 /* '/' */ + minidump_id_len +
|
| 4 /* ".dmp" */ + 1 /* NUL */));
|
| memcpy(path, dump_path, dump_path_len);
|
| @@ -790,9 +794,9 @@
|
| }
|
|
|
| // Non-Browser = Extension, Gpu, Plugins, Ppapi and Renderer
|
| -static bool
|
| -NonBrowserCrashHandler(const void* crash_context, size_t crash_context_size,
|
| - void* context) {
|
| +static bool NonBrowserCrashHandler(const void* crash_context,
|
| + size_t crash_context_size,
|
| + void* context) {
|
| const int fd = reinterpret_cast<intptr_t>(context);
|
| int fds[2] = { -1, -1 };
|
| if (sys_socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
|
| @@ -800,6 +804,19 @@
|
| sys_write(2, msg, sizeof(msg)-1);
|
| return false;
|
| }
|
| +
|
| + // On kernels with ptrace protection, e.g. Ubuntu 10.10+, the browser cannot
|
| + // ptrace this crashing process and crash dumping will fail. When using the
|
| + // SUID sandbox, this crashing process is likely to be in its own PID
|
| + // namespace, and thus there is no way to permit only the browser process to
|
| + // ptrace it.
|
| + // The workaround is to allow all processes to ptrace this process if we
|
| + // reach this point, by passing -1 as the allowed PID. However, support for
|
| + // passing -1 as the PID won't reach kernels until around the Ubuntu 12.04
|
| + // timeframe.
|
| + sys_prctl(PR_SET_PTRACER, -1);
|
| +
|
| + // Start constructing the message to send to the browser.
|
| char guid[kGuidSize + 1] = {0};
|
| char crash_url[kMaxActiveURLSize + 1] = {0};
|
| char distro[kDistroSize + 1] = {0};
|
| @@ -820,7 +837,9 @@
|
| // browser to convert namespace tids.
|
|
|
| // The length of the control message:
|
| - static const unsigned kControlMsgSize = CMSG_SPACE(2*sizeof(int));
|
| + static const unsigned kControlMsgSize = sizeof(fds);
|
| + static const unsigned kControlMsgSpaceSize = CMSG_SPACE(kControlMsgSize);
|
| + static const unsigned kControlMsgLenSize = CMSG_LEN(kControlMsgSize);
|
|
|
| const size_t kIovSize = 7;
|
| struct kernel_msghdr msg;
|
| @@ -843,15 +862,15 @@
|
|
|
| msg.msg_iov = iov;
|
| msg.msg_iovlen = kIovSize;
|
| - char cmsg[kControlMsgSize];
|
| - my_memset(cmsg, 0, kControlMsgSize);
|
| + char cmsg[kControlMsgSpaceSize];
|
| + my_memset(cmsg, 0, kControlMsgSpaceSize);
|
| msg.msg_control = cmsg;
|
| msg.msg_controllen = sizeof(cmsg);
|
|
|
| struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg);
|
| hdr->cmsg_level = SOL_SOCKET;
|
| hdr->cmsg_type = SCM_RIGHTS;
|
| - hdr->cmsg_len = CMSG_LEN(2*sizeof(int));
|
| + hdr->cmsg_len = kControlMsgLenSize;
|
| ((int*) CMSG_DATA(hdr))[0] = fds[0];
|
| ((int*) CMSG_DATA(hdr))[1] = fds[1];
|
|
|
|
|