| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 <dlfcn.h> | 5 #include <dlfcn.h> |
| 6 #include <fcntl.h> | 6 #include <fcntl.h> |
| 7 #include <pthread.h> | 7 #include <pthread.h> |
| 8 #include <sys/epoll.h> | 8 #include <sys/epoll.h> |
| 9 #include <sys/prctl.h> | 9 #include <sys/prctl.h> |
| 10 #include <sys/signal.h> | 10 #include <sys/signal.h> |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 if (pickle.ReadInt(&iter, &kind)) { | 159 if (pickle.ReadInt(&iter, &kind)) { |
| 160 switch (kind) { | 160 switch (kind) { |
| 161 case ZygoteHost::kCmdFork: | 161 case ZygoteHost::kCmdFork: |
| 162 // This function call can return multiple times, once per fork(). | 162 // This function call can return multiple times, once per fork(). |
| 163 return HandleForkRequest(fd, pickle, iter, fds); | 163 return HandleForkRequest(fd, pickle, iter, fds); |
| 164 case ZygoteHost::kCmdReap: | 164 case ZygoteHost::kCmdReap: |
| 165 if (!fds.empty()) | 165 if (!fds.empty()) |
| 166 break; | 166 break; |
| 167 HandleReapRequest(fd, pickle, iter); | 167 HandleReapRequest(fd, pickle, iter); |
| 168 return false; | 168 return false; |
| 169 case ZygoteHost::kCmdDidProcessCrash: | 169 case ZygoteHost::kCmdGetTerminationStatus: |
| 170 if (!fds.empty()) | 170 if (!fds.empty()) |
| 171 break; | 171 break; |
| 172 HandleDidProcessCrash(fd, pickle, iter); | 172 HandleGetTerminationStatus(fd, pickle, iter); |
| 173 return false; | 173 return false; |
| 174 case ZygoteHost::kCmdGetSandboxStatus: | 174 case ZygoteHost::kCmdGetSandboxStatus: |
| 175 HandleGetSandboxStatus(fd, pickle, iter); | 175 HandleGetSandboxStatus(fd, pickle, iter); |
| 176 return false; | 176 return false; |
| 177 default: | 177 default: |
| 178 NOTREACHED(); | 178 NOTREACHED(); |
| 179 break; | 179 break; |
| 180 } | 180 } |
| 181 } | 181 } |
| 182 | 182 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 201 if (!actual_child) | 201 if (!actual_child) |
| 202 return; | 202 return; |
| 203 real_pids_to_sandbox_pids.erase(child); | 203 real_pids_to_sandbox_pids.erase(child); |
| 204 } else { | 204 } else { |
| 205 actual_child = child; | 205 actual_child = child; |
| 206 } | 206 } |
| 207 | 207 |
| 208 ProcessWatcher::EnsureProcessTerminated(actual_child); | 208 ProcessWatcher::EnsureProcessTerminated(actual_child); |
| 209 } | 209 } |
| 210 | 210 |
| 211 void HandleDidProcessCrash(int fd, const Pickle& pickle, void* iter) { | 211 void HandleGetTerminationStatus(int fd, const Pickle& pickle, void* iter) { |
| 212 base::ProcessHandle child; | 212 base::ProcessHandle child; |
| 213 | 213 |
| 214 if (!pickle.ReadInt(&iter, &child)) { | 214 if (!pickle.ReadInt(&iter, &child)) { |
| 215 LOG(WARNING) << "Error parsing DidProcessCrash request from browser"; | 215 LOG(WARNING) << "Error parsing GetTerminationStatus request " |
| 216 << "from browser"; |
| 216 return; | 217 return; |
| 217 } | 218 } |
| 218 | 219 |
| 219 bool child_exited; | 220 base::TerminationStatus status; |
| 220 bool did_crash; | 221 int exit_code; |
| 221 if (g_suid_sandbox_active) | 222 if (g_suid_sandbox_active) |
| 222 child = real_pids_to_sandbox_pids[child]; | 223 child = real_pids_to_sandbox_pids[child]; |
| 223 if (child) | 224 if (child) { |
| 224 did_crash = base::DidProcessCrash(&child_exited, child); | 225 status = base::GetTerminationStatus(child, &exit_code); |
| 225 else | 226 } else { |
| 226 did_crash = child_exited = false; | 227 // Assume that if we can't find the child in the sandbox, then |
| 228 // it terminated normally. |
| 229 status = base::TERMINATION_STATUS_NORMAL_TERMINATION; |
| 230 exit_code = 0; |
| 231 } |
| 227 | 232 |
| 228 Pickle write_pickle; | 233 Pickle write_pickle; |
| 229 write_pickle.WriteBool(did_crash); | 234 write_pickle.WriteInt(static_cast<int>(status)); |
| 230 write_pickle.WriteBool(child_exited); | 235 write_pickle.WriteInt(exit_code); |
| 231 if (HANDLE_EINTR(write(fd, write_pickle.data(), write_pickle.size())) != | 236 if (HANDLE_EINTR(write(fd, write_pickle.data(), write_pickle.size())) != |
| 232 write_pickle.size()) { | 237 write_pickle.size()) { |
| 233 PLOG(ERROR) << "write"; | 238 PLOG(ERROR) << "write"; |
| 234 } | 239 } |
| 235 } | 240 } |
| 236 | 241 |
| 237 // This is equivalent to fork(), except that, when using the SUID | 242 // This is equivalent to fork(), except that, when using the SUID |
| 238 // sandbox, it returns the real PID of the child process as it | 243 // sandbox, it returns the real PID of the child process as it |
| 239 // appears outside the sandbox, rather than returning the PID inside | 244 // appears outside the sandbox, rather than returning the PID inside |
| 240 // the sandbox. | 245 // the sandbox. |
| (...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 731 LOG(INFO) << "Enabling experimental Seccomp sandbox."; | 736 LOG(INFO) << "Enabling experimental Seccomp sandbox."; |
| 732 sandbox_flags |= ZygoteHost::kSandboxSeccomp; | 737 sandbox_flags |= ZygoteHost::kSandboxSeccomp; |
| 733 } | 738 } |
| 734 } | 739 } |
| 735 #endif // SECCOMP_SANDBOX | 740 #endif // SECCOMP_SANDBOX |
| 736 | 741 |
| 737 Zygote zygote(sandbox_flags); | 742 Zygote zygote(sandbox_flags); |
| 738 // This function call can return multiple times, once per fork(). | 743 // This function call can return multiple times, once per fork(). |
| 739 return zygote.ProcessRequests(); | 744 return zygote.ProcessRequests(); |
| 740 } | 745 } |
| OLD | NEW |