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

Side by Side Diff: sandbox/linux/syscall_broker/broker_client.cc

Issue 693943003: Update from https://crrev.com/302630 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years, 1 month 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
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium 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 "sandbox/linux/syscall_broker/broker_client.h"
6
7 #include <errno.h>
8 #include <fcntl.h>
9 #include <sys/stat.h>
10 #include <sys/socket.h>
11 #include <sys/types.h>
12
13 #include "build/build_config.h"
14 #include "base/logging.h"
15 #include "base/pickle.h"
16 #include "base/posix/unix_domain_socket_linux.h"
17 #include "sandbox/linux/syscall_broker/broker_common.h"
18 #include "sandbox/linux/syscall_broker/broker_policy.h"
19
20 #if defined(OS_ANDROID) && !defined(MSG_CMSG_CLOEXEC)
21 #define MSG_CMSG_CLOEXEC 0x40000000
22 #endif
23
24 namespace sandbox {
25
26 namespace syscall_broker {
27
28 // Make a remote system call over IPC for syscalls that take a path and flags
29 // as arguments, currently open() and access().
30 // Will return -errno like a real system call.
31 // This function needs to be async signal safe.
32 int BrokerClient::PathAndFlagsSyscall(IPCCommand syscall_type,
33 const char* pathname,
34 int flags) const {
35 int recvmsg_flags = 0;
36 RAW_CHECK(syscall_type == COMMAND_OPEN || syscall_type == COMMAND_ACCESS);
37 if (!pathname)
38 return -EFAULT;
39
40 // For this "remote system call" to work, we need to handle any flag that
41 // cannot be sent over a Unix socket in a special way.
42 // See the comments around kCurrentProcessOpenFlagsMask.
43 if (syscall_type == COMMAND_OPEN && (flags & kCurrentProcessOpenFlagsMask)) {
44 // This implementation only knows about O_CLOEXEC, someone needs to look at
45 // this code if other flags are added.
46 RAW_CHECK(kCurrentProcessOpenFlagsMask == O_CLOEXEC);
47 recvmsg_flags |= MSG_CMSG_CLOEXEC;
48 flags &= ~O_CLOEXEC;
49 }
50
51 // There is no point in forwarding a request that we know will be denied.
52 // Of course, the real security check needs to be on the other side of the
53 // IPC.
54 if (fast_check_in_client_) {
55 if (syscall_type == COMMAND_OPEN &&
56 !broker_policy_.GetFileNameIfAllowedToOpen(pathname, flags, NULL)) {
57 return -broker_policy_.denied_errno();
58 }
59 if (syscall_type == COMMAND_ACCESS &&
60 !broker_policy_.GetFileNameIfAllowedToAccess(pathname, flags, NULL)) {
61 return -broker_policy_.denied_errno();
62 }
63 }
64
65 Pickle write_pickle;
66 write_pickle.WriteInt(syscall_type);
67 write_pickle.WriteString(pathname);
68 write_pickle.WriteInt(flags);
69 RAW_CHECK(write_pickle.size() <= kMaxMessageLength);
70
71 int returned_fd = -1;
72 uint8_t reply_buf[kMaxMessageLength];
73
74 // Send a request (in write_pickle) as well that will include a new
75 // temporary socketpair (created internally by SendRecvMsg()).
76 // Then read the reply on this new socketpair in reply_buf and put an
77 // eventual attached file descriptor in |returned_fd|.
78 ssize_t msg_len = UnixDomainSocket::SendRecvMsgWithFlags(ipc_channel_,
79 reply_buf,
80 sizeof(reply_buf),
81 recvmsg_flags,
82 &returned_fd,
83 write_pickle);
84 if (msg_len <= 0) {
85 if (!quiet_failures_for_tests_)
86 RAW_LOG(ERROR, "Could not make request to broker process");
87 return -ENOMEM;
88 }
89
90 Pickle read_pickle(reinterpret_cast<char*>(reply_buf), msg_len);
91 PickleIterator iter(read_pickle);
92 int return_value = -1;
93 // Now deserialize the return value and eventually return the file
94 // descriptor.
95 if (read_pickle.ReadInt(&iter, &return_value)) {
96 switch (syscall_type) {
97 case COMMAND_ACCESS:
98 // We should never have a fd to return.
99 RAW_CHECK(returned_fd == -1);
100 return return_value;
101 case COMMAND_OPEN:
102 if (return_value < 0) {
103 RAW_CHECK(returned_fd == -1);
104 return return_value;
105 } else {
106 // We have a real file descriptor to return.
107 RAW_CHECK(returned_fd >= 0);
108 return returned_fd;
109 }
110 default:
111 RAW_LOG(ERROR, "Unsupported command");
112 return -ENOSYS;
113 }
114 } else {
115 RAW_LOG(ERROR, "Could not read pickle");
116 NOTREACHED();
117 return -ENOMEM;
118 }
119 }
120
121 BrokerClient::BrokerClient(const BrokerPolicy& broker_policy,
122 int ipc_channel,
123 bool fast_check_in_client,
124 bool quiet_failures_for_tests)
125 : broker_policy_(broker_policy),
126 ipc_channel_(ipc_channel),
127 fast_check_in_client_(fast_check_in_client),
128 quiet_failures_for_tests_(quiet_failures_for_tests) {
129 }
130
131 BrokerClient::~BrokerClient() {
132 }
133
134 int BrokerClient::Access(const char* pathname, int mode) const {
135 return PathAndFlagsSyscall(COMMAND_ACCESS, pathname, mode);
136 }
137
138 int BrokerClient::Open(const char* pathname, int flags) const {
139 return PathAndFlagsSyscall(COMMAND_OPEN, pathname, flags);
140 }
141
142 } // namespace syscall_broker
143
144 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/linux/syscall_broker/broker_client.h ('k') | sandbox/linux/syscall_broker/broker_common.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698