OLD | NEW |
1 // Copyright (c) 2012 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 #include "sandbox/linux/services/broker_process.h" | 5 #include "sandbox/linux/services/broker_process.h" |
6 | 6 |
7 #include <fcntl.h> | 7 #include <fcntl.h> |
8 #include <signal.h> | 8 #include <signal.h> |
9 #include <sys/socket.h> | 9 #include <sys/socket.h> |
10 #include <sys/stat.h> | 10 #include <sys/stat.h> |
11 #include <sys/syscall.h> | 11 #include <sys/syscall.h> |
12 #include <sys/types.h> | 12 #include <sys/types.h> |
13 #include <sys/wait.h> | 13 #include <sys/wait.h> |
14 #include <unistd.h> | 14 #include <unistd.h> |
15 | 15 |
16 #include <algorithm> | 16 #include <algorithm> |
17 #include <string> | 17 #include <string> |
18 #include <vector> | 18 #include <vector> |
19 | 19 |
20 #include "base/basictypes.h" | 20 #include "base/basictypes.h" |
21 #include "base/callback.h" | 21 #include "base/callback.h" |
22 #include "base/compiler_specific.h" | 22 #include "base/compiler_specific.h" |
23 #include "base/files/scoped_file.h" | 23 #include "base/files/scoped_file.h" |
24 #include "base/logging.h" | 24 #include "base/logging.h" |
| 25 #include "base/memory/scoped_vector.h" |
25 #include "base/pickle.h" | 26 #include "base/pickle.h" |
26 #include "base/posix/eintr_wrapper.h" | 27 #include "base/posix/eintr_wrapper.h" |
27 #include "base/posix/unix_domain_socket_linux.h" | 28 #include "base/posix/unix_domain_socket_linux.h" |
28 #include "base/process/process_metrics.h" | 29 #include "base/process/process_metrics.h" |
29 #include "base/third_party/valgrind/valgrind.h" | 30 #include "base/third_party/valgrind/valgrind.h" |
30 #include "build/build_config.h" | 31 #include "build/build_config.h" |
31 #include "sandbox/linux/services/linux_syscalls.h" | 32 #include "sandbox/linux/services/linux_syscalls.h" |
32 | 33 |
33 #if defined(OS_ANDROID) && !defined(MSG_CMSG_CLOEXEC) | 34 #if defined(OS_ANDROID) && !defined(MSG_CMSG_CLOEXEC) |
34 #define MSG_CMSG_CLOEXEC 0x40000000 | 35 #define MSG_CMSG_CLOEXEC 0x40000000 |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 NOTREACHED(); | 314 NOTREACHED(); |
314 return -ENOMEM; | 315 return -ENOMEM; |
315 } | 316 } |
316 } | 317 } |
317 | 318 |
318 // Handle a request on the IPC channel ipc_socketpair_. | 319 // Handle a request on the IPC channel ipc_socketpair_. |
319 // A request should have a file descriptor attached on which we will reply and | 320 // A request should have a file descriptor attached on which we will reply and |
320 // that we will then close. | 321 // that we will then close. |
321 // A request should start with an int that will be used as the command type. | 322 // A request should start with an int that will be used as the command type. |
322 bool BrokerProcess::HandleRequest() const { | 323 bool BrokerProcess::HandleRequest() const { |
323 | 324 ScopedVector<base::ScopedFD> fds; |
324 std::vector<int> fds; | |
325 char buf[kMaxMessageLength]; | 325 char buf[kMaxMessageLength]; |
326 errno = 0; | 326 errno = 0; |
327 const ssize_t msg_len = UnixDomainSocket::RecvMsg(ipc_socketpair_, buf, | 327 const ssize_t msg_len = UnixDomainSocket::RecvMsg(ipc_socketpair_, buf, |
328 sizeof(buf), &fds); | 328 sizeof(buf), &fds); |
329 | 329 |
330 if (msg_len == 0 || (msg_len == -1 && errno == ECONNRESET)) { | 330 if (msg_len == 0 || (msg_len == -1 && errno == ECONNRESET)) { |
331 // EOF from our parent, or our parent died, we should die. | 331 // EOF from our parent, or our parent died, we should die. |
332 _exit(0); | 332 _exit(0); |
333 } | 333 } |
334 | 334 |
335 // The parent should send exactly one file descriptor, on which we | 335 // The parent should send exactly one file descriptor, on which we |
336 // will write the reply. | 336 // will write the reply. |
337 if (msg_len < 0 || fds.size() != 1 || fds.at(0) < 0) { | 337 // TODO(mdempsky): ScopedVector doesn't have 'at()', only 'operator[]'. |
| 338 if (msg_len < 0 || fds.size() != 1 || fds[0]->get() < 0) { |
338 PLOG(ERROR) << "Error reading message from the client"; | 339 PLOG(ERROR) << "Error reading message from the client"; |
339 // The client could try to DoS us by sending more file descriptors, so | |
340 // make sure we close them. | |
341 for (std::vector<int>::iterator it = fds.begin(); it != fds.end(); ++it) { | |
342 PCHECK(0 == IGNORE_EINTR(close(*it))); | |
343 } | |
344 return false; | 340 return false; |
345 } | 341 } |
346 | 342 |
347 base::ScopedFD temporary_ipc(fds.at(0)); | 343 base::ScopedFD temporary_ipc(fds[0]->Pass()); |
348 | 344 |
349 Pickle pickle(buf, msg_len); | 345 Pickle pickle(buf, msg_len); |
350 PickleIterator iter(pickle); | 346 PickleIterator iter(pickle); |
351 int command_type; | 347 int command_type; |
352 if (pickle.ReadInt(&iter, &command_type)) { | 348 if (pickle.ReadInt(&iter, &command_type)) { |
353 bool r = false; | 349 bool r = false; |
354 // Go through all the possible IPC messages. | 350 // Go through all the possible IPC messages. |
355 switch (command_type) { | 351 switch (command_type) { |
356 case kCommandAccess: | 352 case kCommandAccess: |
357 case kCommandOpen: | 353 case kCommandOpen: |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 GetFileNameInWhitelist(allowed_w_files_, requested_filename, | 536 GetFileNameInWhitelist(allowed_w_files_, requested_filename, |
541 file_to_open); | 537 file_to_open); |
542 return allowed_for_read_and_write; | 538 return allowed_for_read_and_write; |
543 } | 539 } |
544 default: | 540 default: |
545 return false; | 541 return false; |
546 } | 542 } |
547 } | 543 } |
548 | 544 |
549 } // namespace sandbox. | 545 } // namespace sandbox. |
OLD | NEW |