1 // Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <sys/socket.h> 6 #include <sys/un.h> 7 #include <unistd.h> 8 9 #include <cerrno> 10 #include <cstdint> 11 #include <cstdlib> 12 #include <cstring> 13 #include <cstdio> 14 15 int recbomb(int n); 16 void PrepareBelow(int argc, char *argv[]); 17 extern int DefeatTailOptimizationForCrasher(); 18 int DefeatTailOptimizationForBomb() { 19 return 0; 20 } 21 22 int main(int argc, char *argv[]) { 23 PrepareBelow(argc, argv); 24 return recbomb(16) + DefeatTailOptimizationForCrasher(); 25 } 26 27 bool SendPid(const char *socket_path); 28 29 // Prepare for doing the crash, but do it below main so that main's 30 // line numbers remain stable. 31 void PrepareBelow(int argc, char *argv[]) { 32 fprintf(stderr, "pid=%jd\n", (intmax_t) getpid()); 33 if (argc == 2 && strcmp(argv[1], "--nocrash") == 0) { 34 fprintf(stderr, "Doing normal exit\n"); 35 exit(0); 36 } 37 if (argc == 3 && strcmp(argv[1], "--sendpid") == 0) { 38 if (!SendPid(argv[2])) 39 exit(0); 40 } 41 fprintf(stderr, "Crashing as requested.\n"); 42 } 43 44 // Used when the crasher runs in a different PID namespace than the test. A PID 45 // sent over a Unix domain socket to a process in a different PID namespace is 46 // converted to that PID namespace. 47 bool SendPid(const char *socket_path) { 48 struct Socket { 49 Socket(): fd(socket(AF_UNIX, SOCK_DGRAM, 0)) {} 50 ~Socket() { if (fd != -1) close(fd); } 51 int fd; 52 } sock; 53 54 if (sock.fd == -1) { 55 fprintf(stderr,"socket() failed: %s\n", strerror(errno)); 56 return false; 57 } 58 59 sockaddr_un address = { AF_UNIX }; 60 strncpy(address.sun_path, socket_path, sizeof(address.sun_path) - 1); 61 sockaddr *address_ptr = reinterpret_cast<sockaddr *>(&address); 62 if (connect(sock.fd, address_ptr, sizeof(address)) == -1) { 63 fprintf(stderr, "connect() failed: %s\n", strerror(errno)); 64 return false; 65 } 66 67 char zero = '\0'; 68 iovec data = { &zero, 1 }; 69 msghdr msg = { NULL, 0, &data, 1 }; 70 71 if (sendmsg(sock.fd, &msg, 0) == -1) { 72 fprintf(stderr, "sendmsg() failed: %s\n", strerror(errno)); 73 return false; 74 } 75 76 return true; 77 } 78