Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(398)

Side by Side Diff: chrome/app/breakpad_linux.cc

Issue 9212033: Linux/CrOS: Use PR_SET_PTRACER for non-browser crashes. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // For linux_syscall_support.h. This makes it safe to call embedded system 5 // For linux_syscall_support.h. This makes it safe to call embedded system
6 // calls when in seccomp mode. 6 // calls when in seccomp mode.
7 #define SYS_SYSCALL_ENTRYPOINT "playground$syscallEntryPoint" 7 #define SYS_SYSCALL_ENTRYPOINT "playground$syscallEntryPoint"
8 8
9 #include "chrome/app/breakpad_linux.h" 9 #include "chrome/app/breakpad_linux.h"
10 10
11 #include <fcntl.h> 11 #include <fcntl.h>
(...skipping 20 matching lines...) Expand all
32 #include "breakpad/src/common/linux/linux_libc_support.h" 32 #include "breakpad/src/common/linux/linux_libc_support.h"
33 #include "breakpad/src/common/memory.h" 33 #include "breakpad/src/common/memory.h"
34 #include "chrome/common/child_process_logging.h" 34 #include "chrome/common/child_process_logging.h"
35 #include "chrome/common/chrome_paths.h" 35 #include "chrome/common/chrome_paths.h"
36 #include "chrome/common/chrome_switches.h" 36 #include "chrome/common/chrome_switches.h"
37 #include "chrome/common/chrome_version_info_posix.h" 37 #include "chrome/common/chrome_version_info_posix.h"
38 #include "chrome/common/env_vars.h" 38 #include "chrome/common/env_vars.h"
39 #include "content/common/chrome_descriptors.h" 39 #include "content/common/chrome_descriptors.h"
40 #include "seccompsandbox/linux_syscall_support.h" 40 #include "seccompsandbox/linux_syscall_support.h"
41 41
42 #ifndef PR_SET_PTRACER
43 #define PR_SET_PTRACER 0x59616d61
44 #endif
45
42 // Some versions of gcc are prone to warn about unused return values. In cases 46 // Some versions of gcc are prone to warn about unused return values. In cases
43 // where we either a) know the call cannot fail, or b) there is nothing we 47 // where we either a) know the call cannot fail, or b) there is nothing we
44 // can do when a call fails, we mark the return code as ignored. This avoids 48 // can do when a call fails, we mark the return code as ignored. This avoids
45 // spurious compiler warnings. 49 // spurious compiler warnings.
46 #define IGNORE_RET(x) do { if (x); } while (0) 50 #define IGNORE_RET(x) do { if (x); } while (0)
47 51
48 static const char kUploadURL[] = 52 static const char kUploadURL[] =
49 "https://clients2.google.com/cr/report"; 53 "https://clients2.google.com/cr/report";
50 54
51 static bool is_crash_reporter_enabled = false; 55 static bool is_crash_reporter_enabled = false;
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 const bool upload, 718 const bool upload,
715 const bool succeeded) { 719 const bool succeeded) {
716 // WARNING: this code runs in a compromised context. It may not call into 720 // WARNING: this code runs in a compromised context. It may not call into
717 // libc nor allocate memory normally. 721 // libc nor allocate memory normally.
718 if (!succeeded) 722 if (!succeeded)
719 return false; 723 return false;
720 724
721 google_breakpad::PageAllocator allocator; 725 google_breakpad::PageAllocator allocator;
722 const unsigned dump_path_len = my_strlen(dump_path); 726 const unsigned dump_path_len = my_strlen(dump_path);
723 const unsigned minidump_id_len = my_strlen(minidump_id); 727 const unsigned minidump_id_len = my_strlen(minidump_id);
724 char *const path = reinterpret_cast<char*>(allocator.Alloc( 728 char* const path = reinterpret_cast<char*>(allocator.Alloc(
725 dump_path_len + 1 /* '/' */ + minidump_id_len + 729 dump_path_len + 1 /* '/' */ + minidump_id_len +
726 4 /* ".dmp" */ + 1 /* NUL */)); 730 4 /* ".dmp" */ + 1 /* NUL */));
727 memcpy(path, dump_path, dump_path_len); 731 memcpy(path, dump_path, dump_path_len);
728 path[dump_path_len] = '/'; 732 path[dump_path_len] = '/';
729 memcpy(path + dump_path_len + 1, minidump_id, minidump_id_len); 733 memcpy(path + dump_path_len + 1, minidump_id, minidump_id_len);
730 memcpy(path + dump_path_len + 1 + minidump_id_len, ".dmp", 4); 734 memcpy(path + dump_path_len + 1 + minidump_id_len, ".dmp", 4);
731 path[dump_path_len + 1 + minidump_id_len + 4] = 0; 735 path[dump_path_len + 1 + minidump_id_len + 4] = 0;
732 736
733 BreakpadInfo info; 737 BreakpadInfo info;
734 info.filename = path; 738 info.filename = path;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 CrashDoneNoUpload, NULL, 787 CrashDoneNoUpload, NULL,
784 true /* install handlers */); 788 true /* install handlers */);
785 } else { 789 } else {
786 new google_breakpad::ExceptionHandler(tmp_path.value().c_str(), NULL, 790 new google_breakpad::ExceptionHandler(tmp_path.value().c_str(), NULL,
787 CrashDoneUpload, NULL, 791 CrashDoneUpload, NULL,
788 true /* install handlers */); 792 true /* install handlers */);
789 } 793 }
790 } 794 }
791 795
792 // Non-Browser = Extension, Gpu, Plugins, Ppapi and Renderer 796 // Non-Browser = Extension, Gpu, Plugins, Ppapi and Renderer
793 static bool 797 static bool NonBrowserCrashHandler(const void* crash_context,
794 NonBrowserCrashHandler(const void* crash_context, size_t crash_context_size, 798 size_t crash_context_size,
795 void* context) { 799 void* context) {
796 const int fd = reinterpret_cast<intptr_t>(context); 800 const int fd = reinterpret_cast<intptr_t>(context);
797 int fds[2] = { -1, -1 }; 801 int fds[2] = { -1, -1 };
798 if (sys_socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) { 802 if (sys_socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
799 static const char msg[] = "Failed to create socket for crash dumping.\n"; 803 static const char msg[] = "Failed to create socket for crash dumping.\n";
800 sys_write(2, msg, sizeof(msg)-1); 804 sys_write(2, msg, sizeof(msg)-1);
801 return false; 805 return false;
802 } 806 }
807
808 // On kernels with ptrace protection, e.g. Ubuntu 10.10+, the browser cannot
809 // ptrace this crashing process and crash dumping will fail. When using the
810 // SUID sandbox, this crashing process is likely to be in its own PID
811 // namespace, and thus there is no way to permit only the browser process to
812 // ptrace it.
813 // The workaround is to allow all processes to ptrace this process if we
814 // reach this point, by passing -1 as the allowed PID. However, support for
815 // passing -1 as the PID won't reach kernels until around the Ubuntu 12.04
816 // timeframe.
817 sys_prctl(PR_SET_PTRACER, -1);
818
819 // Start constructing the message to send to the browser.
803 char guid[kGuidSize + 1] = {0}; 820 char guid[kGuidSize + 1] = {0};
804 char crash_url[kMaxActiveURLSize + 1] = {0}; 821 char crash_url[kMaxActiveURLSize + 1] = {0};
805 char distro[kDistroSize + 1] = {0}; 822 char distro[kDistroSize + 1] = {0};
806 const size_t guid_len = 823 const size_t guid_len =
807 std::min(my_strlen(child_process_logging::g_client_id), kGuidSize); 824 std::min(my_strlen(child_process_logging::g_client_id), kGuidSize);
808 const size_t crash_url_len = 825 const size_t crash_url_len =
809 std::min(my_strlen(child_process_logging::g_active_url), 826 std::min(my_strlen(child_process_logging::g_active_url),
810 kMaxActiveURLSize); 827 kMaxActiveURLSize);
811 const size_t distro_len = 828 const size_t distro_len =
812 std::min(my_strlen(base::g_linux_distro), kDistroSize); 829 std::min(my_strlen(base::g_linux_distro), kDistroSize);
813 memcpy(guid, child_process_logging::g_client_id, guid_len); 830 memcpy(guid, child_process_logging::g_client_id, guid_len);
814 memcpy(crash_url, child_process_logging::g_active_url, crash_url_len); 831 memcpy(crash_url, child_process_logging::g_active_url, crash_url_len);
815 memcpy(distro, base::g_linux_distro, distro_len); 832 memcpy(distro, base::g_linux_distro, distro_len);
816 833
817 char b; // Dummy variable for sys_read below. 834 char b; // Dummy variable for sys_read below.
818 const char* b_addr = &b; // Get the address of |b| so we can create the 835 const char* b_addr = &b; // Get the address of |b| so we can create the
819 // expected /proc/[pid]/syscall content in the 836 // expected /proc/[pid]/syscall content in the
820 // browser to convert namespace tids. 837 // browser to convert namespace tids.
821 838
822 // The length of the control message: 839 // The length of the control message:
823 static const unsigned kControlMsgSize = CMSG_SPACE(2*sizeof(int)); 840 static const unsigned kControlMsgSize = sizeof(fds);
841 static const unsigned kControlMsgSpaceSize = CMSG_SPACE(kControlMsgSize);
842 static const unsigned kControlMsgLenSize = CMSG_LEN(kControlMsgSize);
824 843
825 const size_t kIovSize = 7; 844 const size_t kIovSize = 7;
826 struct kernel_msghdr msg; 845 struct kernel_msghdr msg;
827 my_memset(&msg, 0, sizeof(struct kernel_msghdr)); 846 my_memset(&msg, 0, sizeof(struct kernel_msghdr));
828 struct kernel_iovec iov[kIovSize]; 847 struct kernel_iovec iov[kIovSize];
829 iov[0].iov_base = const_cast<void*>(crash_context); 848 iov[0].iov_base = const_cast<void*>(crash_context);
830 iov[0].iov_len = crash_context_size; 849 iov[0].iov_len = crash_context_size;
831 iov[1].iov_base = guid; 850 iov[1].iov_base = guid;
832 iov[1].iov_len = kGuidSize + 1; 851 iov[1].iov_len = kGuidSize + 1;
833 iov[2].iov_base = crash_url; 852 iov[2].iov_base = crash_url;
834 iov[2].iov_len = kMaxActiveURLSize + 1; 853 iov[2].iov_len = kMaxActiveURLSize + 1;
835 iov[3].iov_base = distro; 854 iov[3].iov_base = distro;
836 iov[3].iov_len = kDistroSize + 1; 855 iov[3].iov_len = kDistroSize + 1;
837 iov[4].iov_base = &b_addr; 856 iov[4].iov_base = &b_addr;
838 iov[4].iov_len = sizeof(b_addr); 857 iov[4].iov_len = sizeof(b_addr);
839 iov[5].iov_base = &fds[0]; 858 iov[5].iov_base = &fds[0];
840 iov[5].iov_len = sizeof(fds[0]); 859 iov[5].iov_len = sizeof(fds[0]);
841 iov[6].iov_base = &process_start_time; 860 iov[6].iov_base = &process_start_time;
842 iov[6].iov_len = sizeof(process_start_time); 861 iov[6].iov_len = sizeof(process_start_time);
843 862
844 msg.msg_iov = iov; 863 msg.msg_iov = iov;
845 msg.msg_iovlen = kIovSize; 864 msg.msg_iovlen = kIovSize;
846 char cmsg[kControlMsgSize]; 865 char cmsg[kControlMsgSpaceSize];
847 my_memset(cmsg, 0, kControlMsgSize); 866 my_memset(cmsg, 0, kControlMsgSpaceSize);
848 msg.msg_control = cmsg; 867 msg.msg_control = cmsg;
849 msg.msg_controllen = sizeof(cmsg); 868 msg.msg_controllen = sizeof(cmsg);
850 869
851 struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); 870 struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg);
852 hdr->cmsg_level = SOL_SOCKET; 871 hdr->cmsg_level = SOL_SOCKET;
853 hdr->cmsg_type = SCM_RIGHTS; 872 hdr->cmsg_type = SCM_RIGHTS;
854 hdr->cmsg_len = CMSG_LEN(2*sizeof(int)); 873 hdr->cmsg_len = kControlMsgLenSize;
855 ((int*) CMSG_DATA(hdr))[0] = fds[0]; 874 ((int*) CMSG_DATA(hdr))[0] = fds[0];
856 ((int*) CMSG_DATA(hdr))[1] = fds[1]; 875 ((int*) CMSG_DATA(hdr))[1] = fds[1];
857 876
858 if (HANDLE_EINTR(sys_sendmsg(fd, &msg, 0)) < 0) { 877 if (HANDLE_EINTR(sys_sendmsg(fd, &msg, 0)) < 0) {
859 static const char msg[] = "Failed to tell parent about crash.\n"; 878 static const char msg[] = "Failed to tell parent about crash.\n";
860 sys_write(2, msg, sizeof(msg)-1); 879 sys_write(2, msg, sizeof(msg)-1);
861 IGNORE_RET(sys_close(fds[1])); 880 IGNORE_RET(sys_close(fds[1]));
862 return false; 881 return false;
863 } 882 }
864 IGNORE_RET(sys_close(fds[1])); 883 IGNORE_RET(sys_close(fds[1]));
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
920 struct timeval tv; 939 struct timeval tv;
921 if (!gettimeofday(&tv, NULL)) 940 if (!gettimeofday(&tv, NULL))
922 process_start_time = timeval_to_ms(&tv); 941 process_start_time = timeval_to_ms(&tv);
923 else 942 else
924 process_start_time = 0; 943 process_start_time = 0;
925 } 944 }
926 945
927 bool IsCrashReporterEnabled() { 946 bool IsCrashReporterEnabled() {
928 return is_crash_reporter_enabled; 947 return is_crash_reporter_enabled;
929 } 948 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698