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

Side by Side Diff: trunk/src/components/breakpad/browser/crash_handler_host_linux.cc

Issue 275913003: Revert 270173 "Remove SCM_CREDENTIALS fallback code from breakpad" (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 6 years, 7 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 | « trunk/src/components/breakpad/app/breakpad_linux.cc ('k') | 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 #include "components/breakpad/browser/crash_handler_host_linux.h" 5 #include "components/breakpad/browser/crash_handler_host_linux.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <stdlib.h> 8 #include <stdlib.h>
9 #include <sys/socket.h> 9 #include <sys/socket.h>
10 #include <sys/syscall.h> 10 #include <sys/syscall.h>
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 LOG(ERROR) << "Received death signal message with the wrong size;" 212 LOG(ERROR) << "Received death signal message with the wrong size;"
213 << " msg.msg_controllen:" << msg.msg_controllen 213 << " msg.msg_controllen:" << msg.msg_controllen
214 << " msg.msg_flags:" << msg.msg_flags 214 << " msg.msg_flags:" << msg.msg_flags
215 << " kCrashContextSize:" << kCrashContextSize 215 << " kCrashContextSize:" << kCrashContextSize
216 << " kControlMsgSize:" << kControlMsgSize; 216 << " kControlMsgSize:" << kControlMsgSize;
217 return; 217 return;
218 } 218 }
219 219
220 // Walk the control payload an extract the file descriptor and validated pid. 220 // Walk the control payload an extract the file descriptor and validated pid.
221 pid_t crashing_pid = -1; 221 pid_t crashing_pid = -1;
222 int partner_fd = -1;
222 int signal_fd = -1; 223 int signal_fd = -1;
223 for (struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); hdr; 224 for (struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); hdr;
224 hdr = CMSG_NXTHDR(&msg, hdr)) { 225 hdr = CMSG_NXTHDR(&msg, hdr)) {
225 if (hdr->cmsg_level != SOL_SOCKET) 226 if (hdr->cmsg_level != SOL_SOCKET)
226 continue; 227 continue;
227 if (hdr->cmsg_type == SCM_RIGHTS) { 228 if (hdr->cmsg_type == SCM_RIGHTS) {
228 const unsigned len = hdr->cmsg_len - 229 const unsigned len = hdr->cmsg_len -
229 (((uint8_t*)CMSG_DATA(hdr)) - (uint8_t*)hdr); 230 (((uint8_t*)CMSG_DATA(hdr)) - (uint8_t*)hdr);
230 DCHECK_EQ(len % sizeof(int), 0u); 231 DCHECK_EQ(len % sizeof(int), 0u);
231 const unsigned num_fds = len / sizeof(int); 232 const unsigned num_fds = len / sizeof(int);
232 if (num_fds != 1) { 233 if (num_fds != 2) {
233 // A nasty process could try and send us too many descriptors and 234 // A nasty process could try and send us too many descriptors and
234 // force a leak. 235 // force a leak.
235 LOG(ERROR) << "Death signal contained wrong number of descriptors;" 236 LOG(ERROR) << "Death signal contained wrong number of descriptors;"
236 << " num_fds:" << num_fds; 237 << " num_fds:" << num_fds;
237 for (unsigned i = 0; i < num_fds; ++i) 238 for (unsigned i = 0; i < num_fds; ++i)
238 close(reinterpret_cast<int*>(CMSG_DATA(hdr))[i]); 239 close(reinterpret_cast<int*>(CMSG_DATA(hdr))[i]);
239 return; 240 return;
240 } else { 241 } else {
241 signal_fd = reinterpret_cast<int*>(CMSG_DATA(hdr))[0]; 242 partner_fd = reinterpret_cast<int*>(CMSG_DATA(hdr))[0];
243 signal_fd = reinterpret_cast<int*>(CMSG_DATA(hdr))[1];
242 } 244 }
243 } else if (hdr->cmsg_type == SCM_CREDENTIALS) { 245 } else if (hdr->cmsg_type == SCM_CREDENTIALS) {
244 const struct ucred *cred = 246 const struct ucred *cred =
245 reinterpret_cast<struct ucred*>(CMSG_DATA(hdr)); 247 reinterpret_cast<struct ucred*>(CMSG_DATA(hdr));
246 crashing_pid = cred->pid; 248 crashing_pid = cred->pid;
247 } 249 }
248 } 250 }
249 251
250 if (crashing_pid == -1 || signal_fd == -1) { 252 if (crashing_pid == -1 || partner_fd == -1 || signal_fd == -1) {
251 LOG(ERROR) << "Death signal message didn't contain all expected control" 253 LOG(ERROR) << "Death signal message didn't contain all expected control"
252 << " messages"; 254 << " messages";
255 if (partner_fd >= 0)
256 close(partner_fd);
253 if (signal_fd >= 0) 257 if (signal_fd >= 0)
254 close(signal_fd); 258 close(signal_fd);
255 return; 259 return;
256 } 260 }
257 261
262 // Kernel bug workaround (broken in 2.6.30 and 2.6.32, working in 2.6.38).
263 // The kernel doesn't translate PIDs in SCM_CREDENTIALS across PID
264 // namespaces. Thus |crashing_pid| might be garbage from our point of view.
265 // In the future we can remove this workaround, but we have to wait a couple
266 // of years to be sure that it's worked its way out into the world.
267 // TODO(thestig) Remove the workaround when Ubuntu Lucid is deprecated.
268
269 // The crashing process closes its copy of the signal_fd immediately after
270 // calling sendmsg(). We can thus not reliably look for with with
271 // FindProcessHoldingSocket(). But by necessity, it has to keep the
272 // partner_fd open until the crashdump is complete.
273 ino_t inode_number;
274 if (!base::FileDescriptorGetInode(&inode_number, partner_fd)) {
275 LOG(WARNING) << "Failed to get inode number for passed socket";
276 close(partner_fd);
277 close(signal_fd);
278 return;
279 }
280 close(partner_fd);
281
282 pid_t actual_crashing_pid = -1;
283 if (!base::FindProcessHoldingSocket(&actual_crashing_pid, inode_number)) {
284 LOG(WARNING) << "Failed to find process holding other end of crash reply "
285 "socket";
286 close(signal_fd);
287 return;
288 }
289
290 crashing_pid = actual_crashing_pid;
291
258 // The crashing TID set inside the compromised context via 292 // The crashing TID set inside the compromised context via
259 // sys_gettid() in ExceptionHandler::HandleSignal might be wrong (if 293 // sys_gettid() in ExceptionHandler::HandleSignal might be wrong (if
260 // the kernel supports PID namespacing) and may need to be 294 // the kernel supports PID namespacing) and may need to be
261 // translated. 295 // translated.
262 // 296 //
263 // We expect the crashing thread to be in sys_read(), waiting for us to 297 // We expect the crashing thread to be in sys_read(), waiting for us to
264 // write to |signal_fd|. Most newer kernels where we have the different pid 298 // write to |signal_fd|. Most newer kernels where we have the different pid
265 // namespaces also have /proc/[pid]/syscall, so we can look through 299 // namespaces also have /proc/[pid]/syscall, so we can look through
266 // |actual_crashing_pid|'s thread group and find the thread that's in the 300 // |actual_crashing_pid|'s thread group and find the thread that's in the
267 // read syscall with the right arguments. 301 // read syscall with the right arguments.
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 // no-ops. 456 // no-ops.
423 shutting_down_ = true; 457 shutting_down_ = true;
424 uploader_thread_->Stop(); 458 uploader_thread_->Stop();
425 } 459 }
426 460
427 bool CrashHandlerHostLinux::IsShuttingDown() const { 461 bool CrashHandlerHostLinux::IsShuttingDown() const {
428 return shutting_down_; 462 return shutting_down_;
429 } 463 }
430 464
431 } // namespace breakpad 465 } // namespace breakpad
OLDNEW
« no previous file with comments | « trunk/src/components/breakpad/app/breakpad_linux.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698