OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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/syscall_broker/broker_host.h" | 5 #include "sandbox/linux/syscall_broker/broker_host.h" |
6 | 6 |
7 #include <fcntl.h> | 7 #include <fcntl.h> |
8 #include <sys/socket.h> | 8 #include <sys/socket.h> |
9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
10 #include <sys/syscall.h> | 10 #include <sys/syscall.h> |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 return syscall(__NR_openat, AT_FDCWD, pathname, flags, mode); | 52 return syscall(__NR_openat, AT_FDCWD, pathname, flags, mode); |
53 } | 53 } |
54 } | 54 } |
55 | 55 |
56 // Open |requested_filename| with |flags| if allowed by our policy. | 56 // Open |requested_filename| with |flags| if allowed by our policy. |
57 // Write the syscall return value (-errno) to |write_pickle| and append | 57 // Write the syscall return value (-errno) to |write_pickle| and append |
58 // a file descriptor to |opened_files| if relevant. | 58 // a file descriptor to |opened_files| if relevant. |
59 void OpenFileForIPC(const BrokerPolicy& policy, | 59 void OpenFileForIPC(const BrokerPolicy& policy, |
60 const std::string& requested_filename, | 60 const std::string& requested_filename, |
61 int flags, | 61 int flags, |
62 Pickle* write_pickle, | 62 base::Pickle* write_pickle, |
63 std::vector<int>* opened_files) { | 63 std::vector<int>* opened_files) { |
64 DCHECK(write_pickle); | 64 DCHECK(write_pickle); |
65 DCHECK(opened_files); | 65 DCHECK(opened_files); |
66 const char* file_to_open = NULL; | 66 const char* file_to_open = NULL; |
67 bool unlink_after_open = false; | 67 bool unlink_after_open = false; |
68 const bool safe_to_open_file = policy.GetFileNameIfAllowedToOpen( | 68 const bool safe_to_open_file = policy.GetFileNameIfAllowedToOpen( |
69 requested_filename.c_str(), flags, &file_to_open, &unlink_after_open); | 69 requested_filename.c_str(), flags, &file_to_open, &unlink_after_open); |
70 | 70 |
71 if (safe_to_open_file) { | 71 if (safe_to_open_file) { |
72 CHECK(file_to_open); | 72 CHECK(file_to_open); |
(...skipping 11 matching lines...) Expand all Loading... |
84 } else { | 84 } else { |
85 write_pickle->WriteInt(-policy.denied_errno()); | 85 write_pickle->WriteInt(-policy.denied_errno()); |
86 } | 86 } |
87 } | 87 } |
88 | 88 |
89 // Perform access(2) on |requested_filename| with mode |mode| if allowed by our | 89 // Perform access(2) on |requested_filename| with mode |mode| if allowed by our |
90 // policy. Write the syscall return value (-errno) to |write_pickle|. | 90 // policy. Write the syscall return value (-errno) to |write_pickle|. |
91 void AccessFileForIPC(const BrokerPolicy& policy, | 91 void AccessFileForIPC(const BrokerPolicy& policy, |
92 const std::string& requested_filename, | 92 const std::string& requested_filename, |
93 int mode, | 93 int mode, |
94 Pickle* write_pickle) { | 94 base::Pickle* write_pickle) { |
95 DCHECK(write_pickle); | 95 DCHECK(write_pickle); |
96 const char* file_to_access = NULL; | 96 const char* file_to_access = NULL; |
97 const bool safe_to_access_file = policy.GetFileNameIfAllowedToAccess( | 97 const bool safe_to_access_file = policy.GetFileNameIfAllowedToAccess( |
98 requested_filename.c_str(), mode, &file_to_access); | 98 requested_filename.c_str(), mode, &file_to_access); |
99 | 99 |
100 if (safe_to_access_file) { | 100 if (safe_to_access_file) { |
101 CHECK(file_to_access); | 101 CHECK(file_to_access); |
102 int access_ret = access(file_to_access, mode); | 102 int access_ret = access(file_to_access, mode); |
103 int access_errno = errno; | 103 int access_errno = errno; |
104 if (!access_ret) | 104 if (!access_ret) |
105 write_pickle->WriteInt(0); | 105 write_pickle->WriteInt(0); |
106 else | 106 else |
107 write_pickle->WriteInt(-access_errno); | 107 write_pickle->WriteInt(-access_errno); |
108 } else { | 108 } else { |
109 write_pickle->WriteInt(-policy.denied_errno()); | 109 write_pickle->WriteInt(-policy.denied_errno()); |
110 } | 110 } |
111 } | 111 } |
112 | 112 |
113 // Handle a |command_type| request contained in |iter| and send the reply | 113 // Handle a |command_type| request contained in |iter| and send the reply |
114 // on |reply_ipc|. | 114 // on |reply_ipc|. |
115 // Currently COMMAND_OPEN and COMMAND_ACCESS are supported. | 115 // Currently COMMAND_OPEN and COMMAND_ACCESS are supported. |
116 bool HandleRemoteCommand(const BrokerPolicy& policy, | 116 bool HandleRemoteCommand(const BrokerPolicy& policy, |
117 IPCCommand command_type, | 117 IPCCommand command_type, |
118 int reply_ipc, | 118 int reply_ipc, |
119 PickleIterator iter) { | 119 base::PickleIterator iter) { |
120 // Currently all commands have two arguments: filename and flags. | 120 // Currently all commands have two arguments: filename and flags. |
121 std::string requested_filename; | 121 std::string requested_filename; |
122 int flags = 0; | 122 int flags = 0; |
123 if (!iter.ReadString(&requested_filename) || !iter.ReadInt(&flags)) | 123 if (!iter.ReadString(&requested_filename) || !iter.ReadInt(&flags)) |
124 return false; | 124 return false; |
125 | 125 |
126 Pickle write_pickle; | 126 base::Pickle write_pickle; |
127 std::vector<int> opened_files; | 127 std::vector<int> opened_files; |
128 | 128 |
129 switch (command_type) { | 129 switch (command_type) { |
130 case COMMAND_ACCESS: | 130 case COMMAND_ACCESS: |
131 AccessFileForIPC(policy, requested_filename, flags, &write_pickle); | 131 AccessFileForIPC(policy, requested_filename, flags, &write_pickle); |
132 break; | 132 break; |
133 case COMMAND_OPEN: | 133 case COMMAND_OPEN: |
134 OpenFileForIPC( | 134 OpenFileForIPC( |
135 policy, requested_filename, flags, &write_pickle, &opened_files); | 135 policy, requested_filename, flags, &write_pickle, &opened_files); |
136 break; | 136 break; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 // The client should send exactly one file descriptor, on which we | 187 // The client should send exactly one file descriptor, on which we |
188 // will write the reply. | 188 // will write the reply. |
189 // TODO(mdempsky): ScopedVector doesn't have 'at()', only 'operator[]'. | 189 // TODO(mdempsky): ScopedVector doesn't have 'at()', only 'operator[]'. |
190 if (msg_len < 0 || fds.size() != 1 || fds[0]->get() < 0) { | 190 if (msg_len < 0 || fds.size() != 1 || fds[0]->get() < 0) { |
191 PLOG(ERROR) << "Error reading message from the client"; | 191 PLOG(ERROR) << "Error reading message from the client"; |
192 return RequestStatus::FAILURE; | 192 return RequestStatus::FAILURE; |
193 } | 193 } |
194 | 194 |
195 base::ScopedFD temporary_ipc(fds[0]->Pass()); | 195 base::ScopedFD temporary_ipc(fds[0]->Pass()); |
196 | 196 |
197 Pickle pickle(buf, msg_len); | 197 base::Pickle pickle(buf, msg_len); |
198 PickleIterator iter(pickle); | 198 base::PickleIterator iter(pickle); |
199 int command_type; | 199 int command_type; |
200 if (iter.ReadInt(&command_type)) { | 200 if (iter.ReadInt(&command_type)) { |
201 bool command_handled = false; | 201 bool command_handled = false; |
202 // Go through all the possible IPC messages. | 202 // Go through all the possible IPC messages. |
203 switch (command_type) { | 203 switch (command_type) { |
204 case COMMAND_ACCESS: | 204 case COMMAND_ACCESS: |
205 case COMMAND_OPEN: | 205 case COMMAND_OPEN: |
206 // We reply on the file descriptor sent to us via the IPC channel. | 206 // We reply on the file descriptor sent to us via the IPC channel. |
207 command_handled = HandleRemoteCommand( | 207 command_handled = HandleRemoteCommand( |
208 broker_policy_, static_cast<IPCCommand>(command_type), | 208 broker_policy_, static_cast<IPCCommand>(command_type), |
(...skipping 13 matching lines...) Expand all Loading... |
222 NOTREACHED(); | 222 NOTREACHED(); |
223 } | 223 } |
224 | 224 |
225 LOG(ERROR) << "Error parsing IPC request"; | 225 LOG(ERROR) << "Error parsing IPC request"; |
226 return RequestStatus::FAILURE; | 226 return RequestStatus::FAILURE; |
227 } | 227 } |
228 | 228 |
229 } // namespace syscall_broker | 229 } // namespace syscall_broker |
230 | 230 |
231 } // namespace sandbox | 231 } // namespace sandbox |
OLD | NEW |